GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Grundlagen des Linux-ELF-Objektdateiformats (und der ELF-Header-Struktur).

ELF steht für ausführbares und verlinkbares Dateiformat.

ELF wird als Standarddateiformat für Objektdateien unter Linux verwendet. Davor wurde das a.out-Dateiformat als Standard verwendet, aber in letzter Zeit hat ELF die Ladung als Standard übernommen.

ELF unterstützt :

  • Unterschiedliche Prozessoren
  • Unterschiedliche Datencodierung
  • Verschiedene Maschinenklassen

Dieser Artikel erklärt die verschiedenen Arten von ELF-Objektdateien und ELF-Header.

ELF-Objektdateien

Eine Datei, die kompilierten Code enthält, wird als Objektdatei bezeichnet. Eine Objektdatei kann einer der folgenden Typen sein:

1. Verschiebbare Datei

Diese Art von Objektdatei enthält Daten und Code, die mit anderen verschiebbaren Dateien verknüpft werden können, um eine ausführbare Binärdatei oder eine gemeinsam genutzte Objektdatei zu erzeugen. Laienhaft ausgedrückt ist eine verschiebbare Datei dieselbe wie die .o-Datei, die erzeugt wird, wenn wir einen Code auf folgende Weise kompilieren:

 gcc -Wall -c test.c -o test.o

Die nach obiger Operation erzeugte test.o wäre also eine verschiebbare Datei.

2. Shared-Object-Datei

Diese Art von Objektdatei wird vom dynamischen Linker verwendet, um sie mit der ausführbaren Datei und/oder anderen gemeinsam genutzten Objektdateien zu kombinieren, um ein vollständiges Prozessabbild zu erstellen. Laienhaft ausgedrückt ist eine Shared-Object-Datei dieselbe wie die .so-Datei, die erzeugt wird, wenn der Code mit dem Flag -fPIC auf folgende Weise kompiliert wird:

gcc -c -Wall -Werror -fPIC shared.c
gcc -shared -o libshared.so shared.o

Nachdem die beiden obigen Befehle ausgeführt wurden, wird eine gemeinsam genutzte Objektdatei libshared.o als Ausgabe erzeugt.

HINWEIS:Weitere Informationen zu gemeinsam genutzten Linux-Bibliotheken finden Sie in unserem Artikel gemeinsam genutzte Linux-Bibliotheken

3. Ausführbare Datei

Diese Art von Objektdatei ist eine Datei, die ein Programm ausführen kann, wenn es ausgeführt wird. Laienhaft ausgedrückt handelt es sich um die Ausgabe von Befehlen wie diesem:

 gcc -Wall test.c -o test

Die Ausgabe „test“ wäre also eine ausführbare Datei, die bei der Ausführung die in der Datei „test.c“ geschriebene Logik ausführt.

Wie aus den obigen Arten von Objektdateien geschlossen werden kann, ist eine Objektdatei von der Programmerstellung bis zu ihrer Ausführung beteiligt, oder wir können sagen, von der Verknüpfung bis zur Ausführungsphase (um mehr über Linux/GCC-Kompilierungsphasen zu erfahren, lesen Sie unseren Artikel Journey of ein C-Programm).

ELF-Header

Alle oben beschriebenen Objektdateien sind unter Linux vom ELF-Typ.

Dies kann leicht nachgewiesen werden, indem man sich jede dieser Dateien ansieht. Zum Beispiel habe ich mir jede der drei Dateien in meinem System angesehen :

Verschiebbare Datei:

 $ vim func.o

^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^A^@>^@^A^@^@^@^@^@^@^@^@^@^@^@
^@UHå¿^@^@^@^@è^@^@^@^@¸^@^@^@^@è^@^@^@^@ÉÃ^@^@
 Inside func()^@^@GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3^@^T^@^@^@^@
^@^@^@^AzR^@^Ax^P^A^[^L^G^H^A^@^@^\^@^.symtab^@.strtab^@.shstrtab^
@.rela.text^@.data^@.bss^@.rodata^@.comment^@.note.GNU-stack^@.rela.eh_frame
^@^@^@^@^@^@^@^@^@^@^@^@^@

Gemeinsame Objektdatei:

$ vim libshared.so

^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^C^@>^@^A^@^@^@ ^@^@^@^@^@^A^@^@^@^F^@^
^@^@^@^@^@è^A^@^@^@^@^@^@è^A^@^@^@^@^@^@^A^@^@^@^@^@^@^@^D^@^@^@^T^@^@^
@^C^@^@^@GNU^@·YG®z^L^ZÊ7uÈí,?^N^@^@^@^@^C^@^@^@^L^@^@^@

Ausführbare Datei:

$ vim test

^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^B^@>^@^A^@^@^@P@^@^@^@^@^@@^@^@^@^@^@<
^@^@^@D^@^@^^B^@^@^@^@^@^@^A^@^@^@^@^@^@^@/lib64/ld-linux-x86-64.so.2^@^D^
@^@^@^D^@^@^@^T^@^@^@^C^@^@^@GNU^@òÁ}CKbE;ära`6"^O^N\^C^@^@^@

Wir sehen also, dass, da es sich um Binärdateien handelt, nicht viel verständlich ist, außer der ELF-Zeichenfolge am Anfang jeder Datei. Dies zeigt, dass diese Dateien nur im ELF-Format vorliegen.

Jede Datei beginnt mit einem ELF-Header, der ziemlich genau die vollständige Organisation der Datei angibt. Beispielsweise enthalten verschiebbare und gemeinsam genutzte Objektdateien Abschnitte, aber am anderen Ende besteht die ausführbare Datei aus Segmenten. Abhängig vom Typ der Objektdatei gibt der ELF-Header also detaillierte Informationen über die Datei.

Meistens bei ausführbaren Dateien folgt auf einen ELF-Header eine Programm-Header-Tabelle. Eine Programmkopftabelle hilft bei der Erstellung des Prozessabbilds. Da es beim Erstellen eines Prozessabbilds hilft (das nach dem Ausführen der ausführbaren Datei erstellt wird), wird die Programm-Header-Tabelle für ausführbare Dateien obligatorisch, ist jedoch für verschiebbare und gemeinsam genutzte Objektdateien optional.

Das Folgende ist die Organisation des ELF-Headers:

#define EI_NIDENT 16
typedef struct {
e_ident[EI_NIDENT];
unsigned char e_type;
Elf32_Half e_machine;
Elf32_Half e_version;
Elf32_Word e_entry;
Elf32_Addr e_phoff;
Elf32_Off e_shoff;
Elf32_Off e_flags;
Elf32_Word e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;

Wir sehen also, dass die oben gezeigte Organisation die Form einer Struktur hat. Jedes Mitglied hier im Detail zu erklären würde die Dinge komplex machen, also lassen Sie uns die grundlegende Bedeutung und die Informationen durchgehen, die jedes Mitglied dieser Struktur besitzt, um eine Vorstellung von diesem speziellen Feld zu bekommen.

1. e_ident

Wie wir bereits wissen, unterstützt das ELF-Format verschiedene Klassen von Maschinen, Prozessoren usw. Um all dies zu unterstützen, enthalten die anfänglichen Informationen in der ELF-Datei Informationen darüber, wie die Datei unabhängig von dem Prozessor interpretiert wird, auf dem die ausführbare Datei ausgeführt wird. Das Array ‚e_ident‘ liefert genau die gleichen Informationen :

Name     Value      Purpose
EI_MAG     0          File identification
EI_MAG1    1          File identification
EI_MAG2    2          File identification
EI_MAG3    3          File identification
EI_CLASS   4          File class
EI_DATA    5          Data encoding
EI_VERSION 6          File version
EI_PAD     7          Start of padding bytes
EI_NIDENT  16         Size of e_ident[]
  • EI_MAG Die ersten vier Bytes darüber enthalten die magische Zahl „0x7fELF“.
  • EI_CLASS Ein ELF kann zwei Klassen haben, 32 Bit oder 64 Bit. Dadurch wird das Dateiformat portabel.
  • EI_DATA Dieses Mitglied gibt die Information über die Datenkodierung. Einfach ausgedrückt sagen diese Informationen, ob die Daten im Big-Endian- oder Little-Endian-Format vorliegen.
  • EI_VERSION Dieses Mitglied liefert Informationen über die Version der Objektdatei.
  • EI_PAD Dieses Mitglied markiert den Beginn der ungenutzten Bytes im e_indent-Datenfeld.
  • EI_NIDENT Dieses Mitglied liefert die Größe des Arrays e_indent. Dies hilft beim Parsen der ELF-Datei.

2. e_type

Dieses Mitglied identifiziert den Typ der Objektdatei. Beispielsweise kann eine Objektdatei folgenden Typs sein:

Name    Value    Meaning
ET_NONE  0       No file type
ET_REL   1       Relocatable file
ET_EXEC  2       Executable file
ET_DYN   3       Shared object file
ET_CORE  4       Core file

HINWEIS:Die obige Liste ist nicht vollständig, gibt aber dennoch Informationen zu den wichtigsten Objektdateitypen, auf die ELF verweisen kann.

3. e_machine

Dieses Mitglied gibt Informationen zur Architektur, die eine ELF-Datei benötigt.

Name            Value      Meaning
ET_NONE           0          No machine
EM_M32            1          AT&T WE 32100
EM_SPARC          2          SPARC
EM_386            3          Intel Architecture
EM_68K            4          Motorola 68000
EM_88K            5          Motorola 88000
EM_860            7          Intel 80860
EM_MIPS           8          MIPS RS3000 Big-Endian
EM_MIPS_RS4_BE   10          MIPS RS4000 Big-Endian
RESERVED       11-16         Reserved for future use

4. Zusätzliche Mitglieder

Abgesehen von den oben genannten drei Mitgliedern hat es auch die folgenden Mitglieder:

  • e_version:Dieses Mitglied stellt die Versionsinformationen der ELF-Objektdatei bereit.
  • e_entry:Dieses Mitglied liefert die virtuellen Adressinformationen des Einstiegspunkts, an den das System die Kontrolle übergeben muss, damit der Prozess initiiert werden kann.
  • e_phoff:Dieses Mitglied enthält den Offset zur Programmkopftabelle. Diese Informationen werden in Bytes gespeichert. In Ermangelung einer Programmkopftabelle ist die in diesem Mitglied enthaltene Information Null.
  • e_shoff:Dieses Mitglied enthält den Offset zur Abschnittskopftabelle. Wie bei e_phoff werden auch diese Informationen in Form von Bytes gespeichert und in Ermangelung einer Abschnittskopftabelle ist die in diesem Feld enthaltene Information Null.
  • e_flags:Dieses Mitglied enthält Informationen zu prozessspezifischen Flags.
  • e_ehsize:Dieses Mitglied enthält Informationen zur Größe des ELF-Headers in Byes.
  • e_phentsize:Dieses Element enthält Informationen zur Größe eines Eintrags in der Programmkopftabelle der Objektdatei. Beachten Sie, dass alle Einträge die gleiche Größe haben.
  • e_phnum:Dieses Element enthält die Informationen bezüglich der Anzahl der Einträge in der Programmkopftabelle.
  • e_shentsize:Dieses Element enthält die Informationen bezüglich der Größe eines Eintrags in der Abschnittskopftabelle. Die Größe wird in Form einer Anzahl von Bytes dargestellt.
  • e_shnum:Dieses Mitglied liefert die Informationen bezüglich der Anzahl der Einträge in der Abschnittskopftabelle.

Beachten Sie, dass das Produkt von ephnum und ephentsize die Gesamtgröße der Programm-Header-Tabelle in Bytes ergibt und ebenso das Produkt von eshnum und eshentsize die Gesamtgröße der Abschnitts-Header-Tabelle in Bytes ergibt.


Linux
  1. Grundlagen der Linux-Dateiberechtigungen

  2. So leiten Sie die Ausgabe in eine Datei und Stdout in Linux um

  3. a.out durch ELF-Dateiformat ersetzt?

  4. glibc:Elf-Datei OS ABI ungültig

  5. Was ist der Unterschied zwischen Abschnitt und Segment im ELF-Dateiformat

So mounten und unmounten Sie Dateisysteme in Linux

Ls-Befehl in Linux (Dateien und Verzeichnisse auflisten)

Linux-Grundlagen:So verstecken, sperren, verschlüsseln und sichern Sie Ihre Dateien unter Linux

Linux-Hostdatei:Wie wird sie bearbeitet und verwendet?

Eine Einführung in Hashing und Prüfsummen in Linux

Grundlagen des Ethernet-Bonding unter Linux