Portabil Executabil

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare

Formatul Portable Executable (PE) este un format de fișier pentru fișiere executabile , fișiere obiect , biblioteci partajate și drivere de dispozitiv , utilizat în versiunile pe 32 și 64 de biți ale sistemului de operare Microsoft Windows . Termenul „portabil” se referă la versatilitatea formatului pentru multe arhitecturi diferite. Formatul PE este practic o structură de date care încapsulează informațiile necesare încărcătorului Windows pentru a gestiona codul executabil.
Aceasta include rezolvarea dependențelor din bibliotecile partajate, tabelele de import și export API , datele de gestionare a resurselor și datele de stocare locală a firelor (TLS). Pe sistemele de operare ale familiei Windows NT , formatul PE este utilizat pentru EXE, DLL, OBJ, SYS ( drivere de dispozitiv), OCX (controale ActiveX ) și alte tipuri de fișiere. Specificația Extensible Firmware Interface ( EFI ) afirmă că formatul PE este formatul executabil standard în mediile EFI.

Formatul PE este o versiune modificată a formatului Unix COFF . De fapt, foarte des se mai numește și PE / COFF.

Pe sistemele de operare Windows NT, PE acceptă în prezent arhitectura IA-32 , IA-64 și x86-64 (AMD64 / Intel64). Înainte de Windows 2000 , Windows NT (și, prin urmare, PE) suporta arhitecturile MIPS , DEC Alpha și PowerPC . Datorită faptului că PE este utilizat și pe Windows CE , continuă să accepte numeroase variante ale arhitecturilor MIPS, ARM (inclusiv Thumb) și SuperH .

Istorie

Microsoft a trecut la formatul PE odată cu introducerea sistemului de operare Windows NT 3.1. Toate versiunile ulterioare ale Windows, inclusiv Windows 95, 98 și ME, acceptă PE. Pentru ca executabilele produse înainte de introducerea formatului PE să fie compatibile cu sistemele de operare produse ulterior, s-a decis plasarea antetului unui fișier PE alături de antetul unui fișier DOS. În acest fel, antetul dos este mai întâi citit și interpretat și apoi trecut la interpretarea antetului PE (dacă este prezent). Mai mult, majoritatea instrumentelor de compilare, la crearea unui fișier PE, vă permit să specificați un „stub DOS”, adică o porțiune de cod care se execută atunci când sistemul de operare pe care este executat fișierul nu este compatibil cu Standard PE. De obicei, codul DOS implicit tipărește un șir de avertizare precum „Acest program nu poate fi rulat în modul DOS” (deși se poate specifica un comportament diferit). PE, deocamdată, continuă să fie utilizat și cu modificările platformei Windows. Unele extensii ale formatului eșantion sunt formatul .NET PE pentru aplicațiile .NET, o versiune pe 64 de biți numită PE32 + (numită și PE +) și o versiune dezvoltată special pentru Windows CE.

Detalii tehnice

Aspect

Structura unui executabil portabil pe 32 de biți în SVG

Un fișier PE constă dintr-un număr de anteturi și secțiuni care îi spun linkerului dinamic cum să mapeze fișierul în memorie. O imagine executabilă este alcătuită din mai multe regiuni diferite, fiecare dintre ele necesită o protecție de memorie diferită. Prin urmare, începutul fiecărei secțiuni trebuie să fie aliniat cu dimensiunea unei pagini (4KB în IA-32). De exemplu, de obicei secțiunea .text (care conține codul mașinii care urmează să fie executat) este mapată în memorie ca doar în citire (deoarece codul nu poate fi modificat), secțiunea .data (care conține variabilele globale) este mapată în modul citit -scrie. Cu toate acestea, pentru a evita risipirea spațiului, secțiunile nici măcar nu sunt aliniate pe disc, ci doar virtual (adică numai în anteturi). O parte a sarcinii linkerului dinamic este să mapeze fiecare secțiune în spațiul său de memorie și să atribuie permisiunile corecte regiunilor rezultate, luând informațiile necesare din antetele fișierului. La fel funcționează formatul ELF Linux .

Importați tabelul

O secțiune importantă este tabelul de adrese de import (IAT), care este utilizat ca tabel de căutare atunci când aplicația încearcă să utilizeze o funcție de bibliotecă partajată externă. De fapt, un program compilat nu poate ști de unde vor fi încărcate în memorie bibliotecile de care depinde, deci este necesar un salt indirect ori de câte ori este efectuat un apel extern. Când linkerul dinamic încarcă modulele și le îmbină în același spațiu de adrese, scrie instrucțiuni de salt în spațiile din tabelul IAT, astfel încât acestea să indice locațiile de memorie ale funcțiilor de bibliotecă corespunzătoare. Deși acest lucru adaugă un salt suplimentar și la apelurile de biblioteci interne (de fapt, bibliotecile vor folosi și IAT și nu vor apela direct propriile funcții), decăderea performanței este foarte scăzută și flexibilitatea bibliotecilor partajate merită. În cazul în care compilatorul știe dinainte că un apel va fi intern la bibliotecă (cu atributul DllImport) se poate produce mai mult cod optimizat , care va avea ca rezultat , pur și simplu într - un apel indirect opcode .

Mutări

Fișierele PE nu conțin cod independent de poziție . În schimb, acestea sunt compilate la o bază preferată de adresă ( adresa de bază) și toate adresele create de compilator / linker sunt setate în avans. Dacă un fișier PE nu poate fi încărcat pe adresa de bază preferată (pentru că poate există altceva pe adresa respectivă), sistemul de operare va schimba baza pentru acesta. Aceasta implică recalcularea tuturor adreselor absolute și modificarea tuturor codurilor pentru a utiliza noile valori. Încărcătorul face acest lucru comparând adresa preferată și adresa reală de încărcare și calculând diferența. Aceasta este apoi adăugată la adresa preferată pentru a obține noua adresă a locației de memorie. Mutările adresei de bază sunt salvate într-o listă și adăugate, atunci când este necesar, la o locație de memorie existentă. Codul rezultat este privat de proces și nu mai poate fi partajat, astfel încât multe dintre beneficiile DLL-urilor de reducere a memoriei se pierd în acest scenariu. Relocarea bazei încetinește, de asemenea, încărcarea modulului cu mult. Din acest motiv, trebuie utilizat numai atunci când este strict necesar și, din nou din acest motiv, DLL-urile Microsoft au adresele de bază calculate în mod intenționat pentru a nu se suprapune. În cazul în care nu există relocări, formatul PE are în continuare avantajul unui cod cu adevărat eficient, dar în prezența acestora, utilizarea memoriei devine considerabil mai mare. Formatul ELF , pe de altă parte, acceptă codul PIC (Position-Independent Code) folosind un GOT (Global Offset Table) și un PLT (Procedure Linkage Table), care scade ușor timpii de execuție (o diferență foarte minimă), dar elimină complet problemele relocării, permițând astfel să nu risipească memoria.

.NET, metadate și formatul PE

Microsoft .NET Framework a extins formatul PE cu caracteristici care acceptă timpul de execuție al limbajului comun (CLR, o implementare a mașinii virtuale .NET). Printre adăugiri se numără un antet CLR și o secțiune Data CLR. În timpul încărcării unui fișier executabil, încărcătorul sistemului de operare trece executarea către CLR datorită unei referințe din tabelul IMPORT PE / COFF. Apoi CLR VM (Mașina virtuală a CLR) încarcă secțiunea CLR Header și Data CLR.

Secțiunea Data CLR conține două segmente importante: metadate și cod de limbă intermediară (IL):

  • Metadatele conțin informații relevante despre asamblare, inclusiv manifestul asamblării. Un manifest descrie ansamblul în detaliu, inclusiv identificarea unică (cu un hash, numărul versiunii etc.), informații despre componentele exportate, informații despre tipuri (acceptate de sistemul de tip comun (CTS)), referințe externe și o listă a fișierelor prezente în asamblare. Mediul CLR utilizează pe larg metadatele.
  • Codul Intermediate Language (IL) este un cod abstract, independent de limbă, care îndeplinește cerințele Common Intermediate Language (CIL) ale .NET CLR. Termenul „intermediar” se referă la natura codului IL, care este independent de limbă și platformă. Acest „limbaj intermediar”, similar cu codul de byt din Java , permite tuturor platformelor și limbajelor să accepte .NET CLR. IL acceptă programarea orientată pe obiecte ( polimorfism , tipuri abstracte etc.), excepții, evenimente și diverse structuri de date. Codul IL este asamblat într-un fișier PE .NET pentru a fi executat de CLR.

Utilizare pe alte sisteme de operare

Formatul PE este, de asemenea, utilizat de ReactOS , deoarece ReactOS este creat pentru a fi binar compatibil cu Windows. A fost folosit și de alte sisteme de operare, precum SkyOS și BeOS R3. Cu toate acestea, ambele două sisteme de operare au trecut la utilizarea formatului ELF. Formatul PE este, de asemenea, utilizat de Möbius .

Deoarece platforma de dezvoltare MONO intenționează să fie compatibilă binar cu Microsoft .NET , utilizează același format PE ca implementarea Microsoft.

Pe arhitectura x86 care utilizează sisteme de operare asemănătoare Unix , binarele Windows (în format PE) pot fi rulate cu Wine . Chiar și sistemul HX DOS Extender folosește formatul PE pentru binarele native DOS pe 32 de biți, mai mult, în unele cazuri poate rula și binarele Windows în DOS, funcționând ca un fel de Wine, dar pentru DOS.

Mac OS X Leopard poate încărca și analiza fișiere PE, dar nu este compatibil ABI cu Windows.

Elemente conexe

Alte proiecte

linkuri externe

Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT