SET_THREAD_AREA(2)

NOM
get_thread_area, set_thread_area - Manipuler les informations de la zone de stockage locale du thread

SYNOPSIS
#include <sys/syscall.h>   /* Définition des constantes SYS_* */
#include <unistd.h>

#if defined __i386__ || defined __x86_64__
# include <asm/ldt.h>      /* Définition de struct user_desc */

int syscall(SYS_get_thread_area, struct user_desc *u_info);
int syscall(SYS_set_thread_area, struct user_desc *u_info);

#elif defined __m68k__

int syscall(SYS_get_thread_area);
int syscall(SYS_set_thread_area, unsigned long tp);

#elif defined __mips__

int syscall(SYS_set_thread_area, unsigned long addr);

#endif

Note : La glibc ne fournit pas de fonction autour de ces appels système ; appelez-les avec syscall(2).

DESCRIPTION
Ces appels fournissent la prise en charge spécifique à l'architecture de l'implémentation d'un stockage local du thread. Pour le moment, set_thread_area() est disponible sur m68k, MIPS et x86 (variantes 32 et 64 bits) ; get_thread_area() est disponible sur m68k et x86.

Sur m68k et MIPS, set_thread_area() permet de stocker un pointeur arbitraire (fourni dans les paramètres tp sur m68k et addr sur MIPS) dans la structure de données du noyau associée au thread appelant ; ce pointeur peut être récupéré ensuite en utilisant get_thread_area() (voir aussi les NOTES pour des informations sur l'obtention du pointeur du thread sur MIPS).

Sur x86, Linux consacre trois entrées de la GDT (Table globale de descripteurs) au stockage local du thread. Pour plus d'informations sur la GDT, voir le manuel du développeur logiciel d'Intel ou le manuel de programmation de l'architecture AMD.

Les deux appels système prennent un argument qui est un pointeur vers une structure du type suivant :

    struct user_desc {
        unsigned int  entry_number;
        unsigned int  base_addr;
        unsigned int  limit;
        unsigned int  seg_32bit:1;
        unsigned int  contents:2;
        unsigned int  read_exec_only:1;
        unsigned int  limit_in_pages:1;
        unsigned int  seg_not_present:1;
        unsigned int  useable:1;
    #ifdef __x86_64__
        unsigned int  lm:1;
    #endif
    };

get_thread_area() lit l'entrée de la GDT indiquée par u_info->entry_number et remplit le reste des champs dans u_info.

set_thread_area() définit une entrée TLS (Mémoire locale de thread) dans la GDT.

L'entrée de la table de stockage local du thread (TLS) définie par set_thread_area() correspond à la valeur u_info->entry_number fournie par l'utilisateur. Si la valeur est dans les limites, set_thread_area() copie le descripteur TLS pointé par u_info dans la table TLS du thread.

Quand set_thread_area() reçoit un nombre entry_number valant -1, il cherche une entrée libre dans la table TLS. Si set_thread_area() trouve une entrée TLS libre, la valeur de u_info->entry_number est remplie au retour pour montrer quelle entrée a été modifiée.

Un user_desc est considéré comme « vide » si read_exec_only et seg_not_present sont positionnés sur 1 et tous les autres champs valent 0. Si un descripteur « vide » est passé à set_thread_area(), l'entrée TLS correspondante sera effacée. Voir BOGUES pour des détails complémentaires.

Depuis Linux 3.19, set_thread_area() ne peut pas être utilisé pour écrire des segments non présents, segments 16 bits ou de code, bien que le vidage d'un segment soit toujours acceptable.

VALEUR RENVOYÉE
Sur x86, ces appels système renvoient 0 s'ils réussissent et -1 s'ils échouent en positionnant errno pour indiquer l'erreur.

Sur MIPS et m68k, set_thread_area() renvoie toujours 0. Sur m68k, get_thread_area() renvoie la valeur du pointeur de la zone de thread (précédemment définie à l'aide de set_thread_area()).

ERREURS

EFAULT
    u_info est un pointeur non valable.

EINVAL
    u_info->entry_number est en dehors des limites.

ENOSYS
    get_thread_area() ou set_thread_area() a été appelé en tant qu'appel système 64 bits.

ESRCH
    (set_thread_area()) Impossible de trouver une entrée TLS libre.

VERSIONS
set_thread_area() est apparue pour la première fois dans Linux 2.5.29. get_thread_area() est apparu dans Linux 2.5.32.

CONFORMITÉ
set_thread_area() et get_thread_area() sont spécifiques à Linux et ne devraient pas être employés dans des programmes conçus pour être portables.

NOTES
Ces appels système ne sont généralement conçus que pour une utilisation dans des bibliothèques de segmentation de processus.

arch_prctl(2) peut interférer avec set_thread_area() sur x86. Voir arch_prctl(2) pour plus de détails. Il ne s'agit pas d'un problème en général, car arch_prctl(2) n'est en principe utilisé que par des programmes 64 bits.

Sur MIPS, la valeur actuelle du pointeur de la zone de thread peut être récupérée en utilisant l'instruction :

    rdhwr dest, $29

Cette instruction intercepte et est prise en charge par le noyau.

BOGUES
Sur des noyaux 64 bits avant Linux 3.19, un des bits de remplissage de user_desc, s'il est positionné, empêcherait le descripteur d'être considéré comme vide (voir modify_ldt(2)). Il s'en suit que la seule manière fiable d'effacer une entrée TLS est d'utiliser memset(3) pour mettre à zéro toute la structure user_desc, y compris les bits de remplissage, puis de positionner les bits read_exec_only et seg_not_present. Sur Linux 3.19, un user_desc consistant entièrement en zéros sauf entry_number sera aussi interprété comme une requête pour effacer une entrée TLS, mais le comportement était différent sur les anciens noyaux.

Avant Linux 3.19, les registres de segment DS et ES ne doivent pas se référer aux entrées TLS.

VOIR AUSSI
arch_prctl(2), modify_ldt(2), ptrace(2) (PTRACE_GET_THREAD_AREA et PTRACE_SET_THREAD_AREA)

COLOPHON
Cette page fait partie de la publication 5.13 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Philippe MENGUAL <jpmengual@debian.org> Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 (https://www.gnu.org/licenses/gpl-3.0.html) concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE. Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.