modify_ldt(2)

NUME
modify_ldt - obține sau stabilește o intrare LDT pentru fiecare proces în parte

BIBLIOTECA
Biblioteca C standard (libc, -lc)

SINOPSIS
#include <asm/ldt.h>         /* Definiția lui struct user_desc */
#include <sys/syscall.h>     /* Definiția constantelor SYS_* */
#include <unistd.h>

int syscall(unsigned long bytecount;
            SYS_modify_ldt, int func, void ptr[bytecount],
            unsigned long bytecount);

Notă: glibc nu oferă o funcție de învăluire pentru modify_ldt(), fiind necesară utilizarea syscall(2).

DESCRIERE
modify_ldt() citește sau scrie tabelul descriptorilor locali (LDT) pentru un proces. LDT este o matrice de descriptori de segmente la care poate face referire codul utilizatorului. Linux permite proceselor să configureze un LDT pentru fiecare proces în parte (de fapt, pentru fiecare mm). Pentru mai multe informații despre LDT, consultați Intel Software Developer's Manual sau AMD Architecture Programming Manual.

Când func este 0, modify_ldt() citește LDT în memoria indicată de ptr. Numărul de octeți citiți este cel mai mic dintre bytecount și dimensiunea reală a LDT, deși nucleul poate acționa ca și cum LDT ar fi umplut cu octeți de zero la sfârșit. În caz de succes, modify_ldt() va returna numărul de octeți citiți.

Când func este 1 sau 0x11, modify_ldt() modifică intrarea LDT indicată de ptr->entry_number. ptr indică o structură user_desc, iar bytecount trebuie să fie egală cu dimensiunea acestei structuri.

Structura user_desc este definită în <asm/ldt.h> ca:

    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;
    };

În Linux 2.4 și versiunile anterioare, această structură se numea modify_ldt_ldt_s.

Câmpul contents este tipul de segment (date, date expandate, cod neconform sau cod conform). Celelalte câmpuri corespund descrierilor lor din manualul CPU, deși modify_ldt() nu poate activa bitul „accessed” definit de hardware și descris în manualul CPU.

Un user_desc este considerat „gol” dacă read_exec_only și seg_not_present sunt stabilite la 1, iar toate celelalte câmpuri sunt 0. O intrare LDT poate fi eliminată prin stabilirea unui user_desc „gol” sau, dacă func este 1, prin stabilirea atât a base, cât și a limit la 0.

Un segment de cod conform (adică unul cu conținut==3) va fi respins dacă func este 1 sau dacă seg_not_present este 0.

Când func este 2, modify_ldt() va citi zerouri. Aceasta pare a fi o reminiscență din Linux 2.4.

VALOAREA RETURNATĂ
În caz de succes, modify_ldt() returnează fie numărul real de octeți citiți (pentru citire), fie 0 (pentru scriere). În caz de eșec, modify_ldt() returnează -1 și configurează errno pentru a indica eroarea.

ERORI-IEȘIRE

EFAULT
    ptr indică în afara spațiului de adrese.

EINVAL
    ptr este 0, sau func este 1 și bytecount nu este egal cu dimensiunea structurii user_desc, sau func este 1 sau 0x11 și noua intrare LDT are valori nevalide.

ENOSYS
    func nu este nici 0, 1, 2, nici 0x11.

STANDARDE
Linux.

NOTE
modify_ldt() nu ar trebui să fie utilizat pentru stocarea locală a firelor, deoarece încetinește comutarea contextelor și nu acceptă decât un număr limitat de fire. Bibliotecile de creare de fire de execuție (threading) ar trebui să utilizeze în schimb set_thread_area(2) sau arch_prctl(2), cu excepția nucleelor extrem de vechi care nu acceptă aceste apeluri de sistem.

În mod normal, modify_ldt() este utilizat pentru a rula cod vechi pe 16 biți sau cod segmentat pe 32 de biți. Cu toate acestea, nu toate nucleele permit instalarea segmentelor pe 16 biți.

Chiar și în cazul nucleelor pe 64 de biți, modify_ldt() nu poate fi utilizat pentru a crea un segment de cod în modul lung (adică pe 64 de biți). Câmpul nedocumentat „lm” din user_desc nu este util și, în ciuda numelui său, nu are ca rezultat un segment în modul lung.

ERORI
În nucleele pe 64 de biți înainte de Linux 3.19, activarea bitului „lm” în user_desc împiedică ca descriptorul să fie considerat gol. Rețineți că bitul „lm” nu există în antetele pe 32 de biți, dar aceste nuclee cu erori vor observa totuși bitul chiar și atunci când este activat într-un proces pe 32 de biți.

CONSULTAȚI ȘI
arch_prctl(2), set_thread_area(2), vm86(2)

TRADUCERE
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 (https://www.gnu.org/licenses/gpl-3.0.html) 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.