set_thread_area(2) System Calls Manual set_thread_area(2)

get_thread_area, set_thread_area - manipulează informațiile de stocare locală a firelor de execuție

Biblioteca C standard (libc, -lc)

#include <sys/syscall.h>     /* Definirea constantelor SYS_* */
#include <unistd.h>
#if defined __i386__ || defined __x86_64__
# include <asm/ldt.h>        /* Definirea structurii 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__ || defined __csky__
int syscall(SYS_set_thread_area, unsigned long addr);
#endif

Notă: Nu există nicio funcție învăluitoare (wrapper) glibc pentru aceste apeluri de sistem astfel că este necesară utilizarea a syscall(2).

Aceste apeluri oferă suport specific arhitecturii pentru o implementare a memoriei locale a firelor de execuție. În prezent, set_thread_area() este disponibil pe m68k, MIPS, C-SKY și x86 (ambele variante pe 32 și 64 de biți); get_thread_area() este disponibil pe m68k și x86.

Pe m68k, MIPS și C-SKY, set_thread_area() permite stocarea unui indicator arbitrar (furnizat în argumentul tp pe m68k și în argumentul addr pe MIPS și C-SKY) în structura de date a nucleului asociată cu firul de execuție apelant; acest indicator poate fi recuperat ulterior folosind get_thread_area() (a se vedea, de asemenea, secțiunea NOTE pentru informații privind obținerea indicatorului de fir de execuție pe MIPS).

Pe x86, Linux dedică trei intrări în GDT („Global Descriptor Table”, Tabelul de descriptori globali) pentru stocarea locală a firelor de execuție. Pentru mai multe informații despre GDT, consultați „Intel Software Developer's Manual” sau „AMD Architecture Programming Manual”.

Ambele apeluri de sistem primesc un argument care este un indicator la o structură de tipul următor:


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() citește intrarea GDT indicată de u_info->entry_number și completează restul câmpurilor din u_info.

set_thread_area() stabilește o intrare TLS în GDT.

Intrarea din matricea TLS definită de set_thread_area() corespunde valorii lui u_info->entry_number (u_info->numărul-intrării) transmisă de utilizator. În cazul în care această valoare este în limite, set_thread_area() scrie descriptorul TLS indicat de u_info în matricea TLS a firului.

Atunci când set_thread_area() primește un entry_number de -1, caută o intrare TLS liberă. În cazul în care set_thread_area() găsește o intrare TLS liberă, valoarea u_info->entry_number este definită la returnare pentru a arăta ce intrare a fost modificată.

Un user_desc este considerat „gol” dacă read_exec_only și seg_not_present sunt stabilite la 1 și toate celelalte câmpuri sunt 0. Dacă un descriptor „gol” este transmis la set_thread_area(), intrarea TLS corespunzătoare va fi ștearsă. A se vedea secțiunea ERORI pentru detalii suplimentare.

Începând cu Linux 3.19, set_thread_area() nu poate fi utilizat pentru a scrie segmente neprezente, segmente pe 16 biți sau segmente de cod, deși ștergerea unui segment este în continuare acceptată.

Pe x86, aceste apeluri de sistem returnează 0 în caz de succes și -1 în caz de eșec, cu errno configurată pentru a indica eroarea.

Pe C-SKY, MIPS și m68k, set_thread_area() returnează întotdeauna 0. Pe m68k, get_thread_area() returnează valoarea indicatorului de zonă a firului (stabilită anterior prin set_thread_area()).

ERORI-IEȘIRE

u_info este un indicator nevalid.
u_info->entry_number este în afara limitelor.
get_thread_area() sau set_thread_area() a fost invocat ca un apel de sistem pe 64 de biți.
(set_thread_area()) Nu a putut fi localizată o intrare TLS liberă.

Linux.

Linux 2.5.29.
Linux 2.5.32.

Aceste apeluri de sistem sunt, în general, destinate a fi utilizate numai de bibliotecile de fire de execuție „threading”.

arch_prctl(2) poate interfera cu set_thread_area() pe x86. Consultați arch_prctl(2) pentru mai multe detalii. În mod normal, acest lucru nu reprezintă o problemă, deoarece arch_prctl(2) este utilizat în mod normal numai de programele pe 64 de biți.

Pe MIPS, valoarea curentă a indicatorului zonei firului de execuție poate fi obținută cu ajutorul instrucțiunii:


rdhwr dest, $29

Această instrucțiune este capturează și este gestionată de către nucleu.

Pe nucleele pe 64 de biți înainte de Linux 3.19, unul dintre biții de umplutură din user_desc, dacă era definit, ar fi împiedicat ca descriptorul să fie considerat gol (a se vedea modify_ldt(2)). Ca urmare, singura modalitate fiabilă de a șterge o intrare TLS este de a utiliza memset(3) pentru a aduce la zero întreaga structură user_desc, inclusiv biții de umplutură, și apoi de a defini biții read_exec_only și seg_not_present. Pe Linux 3.19, un user_desc format în întregime din zerouri, cu excepția lui entry_number, va fi, de asemenea, interpretat ca o cerere de ștergere a unei intrări TLS, dar acest lucru s-a comportat diferit pe nucleele mai vechi.

Înainte de Linux 3.19, registrele segmentelor DS și ES nu trebuie să facă referire la intrările TLS.

arch_prctl(2), modify_ldt(2), ptrace(2) (PTRACE_GET_THREAD_AREA și PTRACE_SET_THREAD_AREA)

Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.

2 mai 2024 Pagini de manual de Linux 6.9.1