format de fișier Elf

În descrierea formatului de tipuri de date care urmează să fie utilizate [u] intN_t. unde u este semnul unsigned și N determină mărimea tipului, de exemplu, uint16_t. Aceste tipuri sunt definite în standardul stdint.h fișier antet.

Toate tipurile de date și constante sunt descrise în fișierul antet elf.h.

fișier antet

La începutul fișierului (la offset 0 din start) este fișierul ELF-antet descrisă de următoarea structură:

câmp e_ident conține informații de identificare despre fișierul. Câmpul este o matrice de octet pentru a avea aceeași performanță pe diferite arhitecturi și diferite dimensiuni cuvânt octet ordine în cuvântul. Elementele de matrice au următoarele funcții:

În viitor, va furniza valorile pentru constantele de Linux pe arhitectura i386. Pentru valori constante pentru alte sisteme de operare și arhitecturi, consultați documentația.

câmp e_type identifică tipul de fișier: 0 (necunoscut), 1 (fișier obiect), 2 (fișier executabil), 3 (o bibliotecă partajată), 4 (core-file).

câmp e_machine identifică tipul procesorului 0 (necunoscut), 3 (Intel 80386 și compatibles).

câmp e_version identifică versiunea fișierului: 0 (versiune nevalidă), 1 (versiunea curentă).

câmp e_phoff specifică abaterea de la începutul fișierului înainte de tabel antet de program (tabelul antet de program). Informații despre tabelul de antet program este prezentată mai jos.

câmp e_shoff specifică abaterea de la începutul fișierului la începutul antetul secțiunii tabel (tabelul secțiunii de program). Informații privind titlurile secțiunilor de masă vor fi prezentate mai jos.

câmp e_flags specifică steagurile suplimentare procesoare specifice. În prezent, valoarea acestui câmp trebuie să fie întotdeauna 0.

E_ehsize magazine câmp de antet dimensiunea pentru ELF-fișiere. Valoarea sa trebuie să fie egală cu 52 (sizeof (Elf32_Ehdr)).

E_phentsize câmp stochează dimensiunea o înregistrare în tabelul de antete de program. Valoarea sa ar trebui să fie 32 (sizeof (Elf32_Phdr)), sau 0 în cazul în care masa antet program este gol.

câmp E_phnum deține numărul de intrări în tabelul din antetul programului.

E_shentsize câmp stochează dimensiunea o intrare în secțiunea de tabel antet. Valoarea sa trebuie să fie egală cu 40 (sizeof (Elf32_Shdr)), sau 0 în cazul în tabelul de antet secțiune este goală.

magazine de câmp E_shnum numărul de intrări în tabelul de secțiunea antet.

sectiunea e_shstrndx magazine de câmp antet un index care stochează numele tuturor secțiunilor (cm. mai jos).

antet secțiune Tabel

Informațiile stocate în fișiere pentru ELF-, organizate în secțiuni. Fiecare secțiune are propriul nume unic. Unele secțiuni sunt stocate informații de serviciu pentru ELF fișiere (de exemplu, rândurile din tabel), alte secțiuni stochează informații de depanare, a treia secțiune a datelor cod de magazin sau de program.

tabel secțiune antet este o serie de structuri Elf32_Shdr. Numărul de elemente de matrice este determinată de fișierul ELF-antet câmp e_shnum. Array la offset stocate în e_shoff domeniu. Element Array 0 este rezervat și nu sunt utilizate pentru a descrie secțiuni. Astfel, descrieri ale secțiunilor sunt elementele unui tablou cu indici între 1 și e_shnum - 1.

Structura Elf32_Shdr este definită după cum urmează:

câmp sh_name stochează indexul numele secțiunii. indice de nume - offset în secțiunea de date al cărui indice este specificat în e_shstrndx antet pentru ELF-files. La acest decalaj este plasat un șir terminat cu un octet nul, care este numele secțiunii.

Astfel, pentru a obține numele secțiunii din următoarele etape:

  • Descărcați antetul secțiunii, indicele este stocat în e_shstrndx antet pentru ELF-files.
  • Încărcați secțiunea corespunzătoare a corpului.
  • Prin deplasarea în zona de memorie predeterminată început sh_name relativă, care este încărcată secțiune este cerută de șirul numele secțiunii.

Sh_type câmp stochează secțiunea de tip. Valorile posibile ale câmpului sunt enumerate mai jos.

Secțiunea cuprinde instrucțiuni procesor.

Steaguri pot fi combinate cu sau nivel de bit.

câmp sh_offset reținerile abaterea de la începutul fișierului, în conformitate cu care este stocată secțiunea de date.

Câmpul sh_size stochează dimensiunea secțiunii în octeți.

magazine de câmp se poate reprezenta un indice de alte secțiuni (în unele cazuri speciale).

Câmp sh_info stochează secțiunea cu informații suplimentare.

magazine de câmp Sh_entsize dimensiunea de o înregistrare, în cazul în care secțiunea stochează un tabel de intrări de dimensiuni fixe.

titlurile programelor Tabel

Capetele de tabel ale programului conține informațiile necesare pentru încărcarea programului pentru execuție.

Program Table anteturi este o serie de structuri Elf32_Phdr. Matricea este plasat la offset de la începutul fișierului, care este stocat în câmpul antet e_phoff ELF-file, iar numărul de elemente de matrice stocate într-un câmp de antet e_phnum ELF-file.

Structura Elf32_Phdr este definită după cum urmează.

câmp P_type stochează antet tip. Unele posibile tipuri de valori antet sunt prezentate în tabelul de mai jos.

câmp p_offset reținerile abaterea de la începutul fișierului, care este situat pe acest segment.

Valoarea câmpului P_paddr ar trebui să fie egal cu 0.

câmp P_filesz stochează o dimensiune segment al unui fișier (poate fi 0).

magazine p_memsz Câmp în mărime segment de memorie (poate fi 0).

P_flags magazine de câmp steaguri accesul la segmentul de memorie (poate fi combinată cu ajutorul unui bitwise „sau“).

segment poate fi citit

segment PT_NOTE

În segmentul de ELF-fișiere cu tipul de magazin PT_NOTE informații suplimentare cu privire la stadiul punerii în aplicare a programului. Segmentul în sine conține orice număr de înregistrări de dimensiuni arbitrare. Segment are întotdeauna o dimensiune care este un multiplu de 4 octeți (pentru Elf32) și fiecare intrare în segmentul începe la multiplu de offset de 4 octeți. La începutul fiecărei înregistrări este un antet de înregistrare, reprezentată prin următoarea structură:

n_namesz cuprinde o lungime de câmp nume de înregistrare. Numele ar trebui să fie un șir de caractere care se încheie octet non-gol 0. Șirul de nume foarte începe să înregistreze imediat după structura Elf32_Nhdr.

câmp n_descsz conține informații referitoare la lungimea de înregistrare. Lungimea trebuie să fie un multiplu de 4 octeți. Porțiunea de date a înregistrării începe imediat după numele înregistrării bazate pe aliniere este de 4 octeți.

câmp n_type conține tipul de înregistrare. Tipuri de intrare posibile depind de tipul de fișier (obiect, de bază) și sunt discutate în următoarele secțiuni.

Mai jos este un exemplu PT_NOTE segment.

înjunghie format depanare

Când compilați un fișier executabil poate fi adăugat la informațiile de depanare debugger utilizează pentru a afișa executarea programului progresului în ceea ce privește limbaj de nivel înalt. Există mai multe formate de informații de depanare (injunghie, DWARF), aici descris ca fiind cel mai simplu format înjunghie.

Pentru a compila un program cu adăugarea de depanare informații în formatul opțiunii înjunghie gcc -gstabs utilizat. de exemplu

În înjunghie informația despre formatul de depanare sunt stocate în secțiunile .stab și .stabstr ELF-fișier.

sectiunea .stab conține o serie de structuri:

sectiunea .stabstr stochează șirurile de caractere care se termină octet 0 sunt utilizate în înregistrările din secțiunea .stab.

Câmpul n_type stochează tipul de înregistrare. Posibile tipuri de înregistrări pot fi găsite în stab.h. ne interesează doar câteva dintre ele.

Numele fișierului este setat folosind directivele #line sau nume de fișier care urmează să fie incluse utilizând #include
n_strx - secțiunea Index .stabstr șir de nume de fișier
Presupunem că acțiunea numele fișierului care urmează să fie instalat în înregistrarea N_SOL începe cu următoarea înregistrare.

Numărul de linii de cod executabil
n_value - deplasarea primei linii de instrucțiuni cu privire la funcția
n_desc - numărul liniei în codul sursă

N_SLINE este organizat în ture în funcție.

Prima intrare în tabel este de performanță .stab și are tipul N_UNDF. Indicele de înregistrare se presupune a fi 0.

nume de fișier, care este o funcție, aceasta poate fi în înregistrarea N_SOL după înregistrarea funcției N_FUN în sine, ci la prima înregistrare N_SLINE. Trebuie să se presupune că numele fișierului în care funcția este definit la fel ca și numele fișierului, înființat primul N_SLINE record în această funcție.

Exemplu: fișier file1.h: I