Ausführbares und verknüpfbares Format - Executable and Linkable Format

ELF
Dateinamenerweiterung
none, .axf , .bin , .elf , .o , .prx , .puff , .ko , .mod und .so
magische Zahl 0x7F 'E' 'L' 'F'
Entwickelt von Unix-Systemlabore
Formattyp Binär , ausführbare Datei , Objekt , gemeinsam genutzte Bibliothek , Core-Dump
Behälter für Viele ausführbare Binärformate
Eine ELF-Datei hat zwei Ansichten: Der Programmkopf zeigt die zur Laufzeit verwendeten Segmente , während der Abschnittskopf die Menge der Abschnitte der Binärdatei auflistet .

In der Berechnung , das Executable and Linking Format ( ELF , früher unter dem Namen Extensible Linking Format ), ist ein gemeinsames Standard - Dateiformat für ausführbare Dateien, Objektcode , gemeinsam genutzte Bibliotheken und Core - Dumps . Zuerst in der Spezifikation für das Application Binary Interface (ABI) der Unix- Betriebssystemversion mit dem Namen System V Release 4 (SVR4) und später im Tool Interface Standard veröffentlicht, wurde es schnell von verschiedenen Anbietern von Unix- Systemen akzeptiert . 1999 wurde es vom 86open- Projekt als Standard-Binärdateiformat für Unix und Unix-ähnliche Systeme auf x86- Prozessoren ausgewählt .

Das ELF-Format ist vom Design her flexibel, erweiterbar und plattformübergreifend . Zum Beispiel unterstützt es verschiedene Endianness- und Adressgrößen, so dass es keine bestimmte Zentraleinheit (CPU) oder Befehlssatzarchitektur ausschließt . Dadurch konnte es von vielen verschiedenen Betriebssystemen auf vielen verschiedenen Hardwareplattformen übernommen werden .

Dateilayout

Jede ELF-Datei besteht aus einem ELF-Header, gefolgt von Dateidaten. Die Daten können umfassen:

  • Programmkopftabelle, die null oder mehr Speichersegmente beschreibt
  • Abschnittskopftabelle, die null oder mehr Abschnitte beschreibt
  • Daten, auf die durch Einträge in der Programmkopftabelle oder Abschnittskopftabelle verwiesen wird
Aufbau einer ELF-Datei mit hervorgehobenen Schlüsseleinträgen

Die Segmente enthalten Informationen, die für die Ausführung der Datei zur Laufzeit benötigt werden, während Abschnitte wichtige Daten zum Verknüpfen und Verschieben enthalten. Jedes Byte in der gesamten Datei kann höchstens einem Abschnitt gehören, und es können verwaiste Bytes vorkommen, die keinem Abschnitt gehören.

00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|

00000010 02 00 3e 00 01 00 00 00 c5 48 40 00 00 00 00 00 |..>......H@.....|

Beispiel-Hexdump des ELF-Dateiheaders

Dateikopf

Der ELF-Header definiert, ob 32- oder 64-Bit- Adressen verwendet werden. Die Kopfzeile enthält drei Felder, die von dieser Einstellung betroffen sind, und versetzt andere Felder, die ihnen folgen. Der ELF-Header ist 52 bzw. 64 Byte lang für 32-Bit- bzw. 64-Bit-Binärdateien.

ELF-Header
Versatz Größe (Byte) Gebiet Zweck
32-Bit 64-Bit 32-Bit 64-Bit
0x00 4 e_ident[EI_MAG0] bis e_ident[EI_MAG3] 0x7Fgefolgt von ELF( 45 4c 46) in ASCII ; diese vier Bytes bilden die magische Zahl .
0x04 1 e_ident[EI_CLASS] Dieses Byte wird entweder auf 1oder gesetzt 2, um das 32- bzw. 64-Bit-Format anzuzeigen.
0x05 1 e_ident[EI_DATA] Dieses Byte wird entweder auf 1oder gesetzt 2, um Little- bzw. Big- Endianness anzuzeigen . Dies beeinflusst die Interpretation von Multibyte-Feldern, die mit offset beginnen 0x10.
0x06 1 e_ident[EI_VERSION] Stellen Sie auf 1für die ursprüngliche und aktuelle Version von ELF ein.
0x07 1 e_ident[EI_OSABI] Identifiziert das Zielbetriebssystem ABI .
Wert ABI
0x00 System V
0x01 HP-UX
0x02 NetBSD
0x03 Linux
0x04 GNU Hurd
0x06 Solaris
0x07 AIX
0x08 IRIX
0x09 FreeBSD
0x0A Tru64
0x0B Novell Modesto
0x0C OpenBSD
0x0D OpenVMS
0x0E NonStop-Kernel
0x0F AROS
0x10 Fenix-Betriebssystem
0x11 CloudABI
0x12 Stratus Technologies OpenVOS

Es wird oft 0unabhängig von der Zielplattform auf gesetzt.

0x08 1 e_ident[EI_ABIVERSION] Spezifiziert weiter die ABI-Version. Seine Interpretation hängt vom Ziel-ABI ab. Der Linux-Kernel (nach mindestens 2.6) hat keine Definition davon, daher wird er für statisch gelinkte ausführbare Dateien ignoriert. In diesem Fall sind Offset und Größe von EI_PAD 8.

glibc 2.12+ falls e_ident[EI_OSABI] == 3 dieses Feld als ABI-Version des dynamischen Linkers behandelt : es definiert eine Liste der Funktionen des dynamischen Linkers, behandelt e_ident[EI_ABIVERSION] als eine vom gemeinsamen Objekt angeforderte Funktionsebene (ausführbar oder dynamisch .) Bibliothek) und verweigert das Laden, wenn ein unbekanntes Merkmal angefordert wird, dh e_ident[EI_ABIVERSION] ist größer als das größte bekannte Merkmal.

0x09 7 e_ident[EI_PAD] derzeit ungenutzt, sollte mit Nullen aufgefüllt werden.
0x10 2 e-Typ Identifiziert den Objektdateityp.
Wert Typ
0x00 ET_NONE
0x01 ET_REL
0x02 ET_EXEC
0x03 ET_DYN
0x04 ET_CORE
0xFE00 ET_LOOS
0xFEFF ET_HIOS
0xFF00 ET_LOPROC
0xFFFF ET_HIPROC
0x12 2 e_maschine Gibt die Architektur des Zielbefehlssatzes an . Einige Beispiele sind:
Wert IST EIN
0x00 Kein spezifischer Befehlssatz
0x01 AT&T WE 32100
0x02 SPARC
0x03 x86
0x04 Motorola 68000 (M68k)
0x05 Motorola 88000 (M88k)
0x06 Intel-MCU
0x07 Intel 80860
0x08 MIPS
0x09 IBM-System/370
0x0A MIPS RS3000 Little-Endian
0x0B - 0x0D Reserviert für zukünftige Verwendung
0x0E Hewlett-Packard PA-RISC
0x0F Reserviert für zukünftige Verwendung
0x13 Intel 80960
0x14 PowerPC
0x15 PowerPC (64-Bit)
0x16 S390 , einschließlich S390x
0x17 IBM SPU/SPC
0x18 - 0x23 Reserviert für zukünftige Verwendung
0x24 NEC V800
0x25 Fujitsu FR20
0x26 TRW RH-32
0x27 Motorola RCE
0x28 ARM (bis ARMv7/Aarch32)
0x29 Digitale Alpha
0x2A SuperH
0x2B SPARC-Version 9
0x2C Siemens TriCore Embedded-Prozessor
0x2D Argonaut RISC-Kern
0x2E Hitachi H8/300
0x2F Hitachi H8/300H
0x30 Hitachi H8S
0x31 Hitachi H8/500
0x32 IA-64
0x33 Stanford MIPS-X
0x34 Motorola ColdFire
0x35 Motorola M68HC12
0x36 Fujitsu MMA Multimedia-Beschleuniger
0x37 Siemens PCP
0x38 Integrierter RISC-Prozessor mit nCPU von Sony
0x39 Denso NDR1 Mikroprozessor
0x3A Motorola Star*Core-Prozessor
0x3B Toyota ME16-Prozessor
0x3C STMicroelectronics ST100-Prozessor
0x3D Advanced Logic Corp. TinyJ Embedded-Prozessorfamilie
0x3E AMD x86-64
0x8C TMS320C6000-Familie
0xAF MCST Elbrus e2k
0xB7 ARM 64-Bit (ARMv8/Aarch64)
0xF3 RISC-V
0xF7 Berkeley Paketfilter
0x101 WDC 65C816
0x14 4 e_version Stellen Sie auf 1für die Originalversion von ELF ein.
0x18 4 8 e_entry Dies ist die Speicheradresse des Einstiegspunkts, von dem aus die Ausführung des Prozesses beginnt. Dieses Feld ist je nach dem zuvor definierten Format entweder 32 oder 64 Bit lang.
0x1C 0x20 4 8 e_phoff Zeigt auf den Anfang der Programmkopftabelle. Es folgt normalerweise unmittelbar auf den Dateiheader und macht den Offset 0x34bzw. 0x40für ausführbare 32- und 64-Bit-ELF-Dateien.
0x20 0x28 4 8 e_shoff Zeigt auf den Anfang der Abschnittsüberschriftentabelle.
0x24 0x30 4 e_flags Die Interpretation dieses Feldes hängt von der Zielarchitektur ab.
0x28 0x34 2 e_ehsize Enthält die Größe dieses Headers, normalerweise 64 Bytes für das 64-Bit- und 52 Bytes für das 32-Bit-Format.
0x2A 0x36 2 e_phentsize Enthält die Größe eines Programm-Header-Tabelleneintrags.
0x2C 0x38 2 e_phnum Enthält die Anzahl der Einträge in der Programmkopftabelle.
0x2E 0x3A 2 e_shentsize Enthält die Größe eines Abschnittskopftabelleneintrags.
0x30 0x3C 2 e_shnum Enthält die Anzahl der Einträge in der Abschnittskopftabelle.
0x32 0x3E 2 e_shstrndx Enthält den Index des Abschnittskopfzeilen-Tabelleneintrags, der die Abschnittsnamen enthält.
0x34 0x40 Ende des ELF-Headers (Größe)

Programmkopf

Die Programmkopftabelle teilt dem System mit, wie ein Prozessabbild erstellt wird. Es befindet sich am Datei-Offset e_phoff und besteht aus e_phnum- Einträgen, jeder mit der Größe e_phentsize . Das Layout unterscheidet sich bei 32-Bit- ELF und 64-Bit- ELF geringfügig , da sich die p_flags aus Ausrichtungsgründen an einer anderen Strukturposition befinden. Jeder Eintrag ist wie folgt aufgebaut:

Programmkopf
Versatz Größe (Byte) Gebiet Zweck
32-Bit 64-Bit 32-Bit 64-Bit
0x00 4 p_typ Gibt den Typ des Segments an.
Wert Name Bedeutung
0x00000000 PT_NULL Programmkopftabelleneintrag unbenutzt.
0x00000001 PT_LOAD Ladbares Segment.
0x0000002 PT_DYNAMIC Dynamische Verknüpfungsinformationen.
0x00000003 PT_INTERP Informationen zum Dolmetscher.
0x00000004 PT_NOTE Hilfsinformationen.
0x00000005 PT_SHLIB Reserviert.
0x00000006 PT_PHDR Segment, das die Programmkopftabelle selbst enthält.
0x00000007 PT_TLS Thread-lokale Speichervorlage.
0x60000000 PT_LOOS Reservierter Inklusivbereich. Betriebssystemspezifisch.
0x6FFFFFFF PT_HIOS
0x70000000 PT_LOPROC Reservierter Inklusivbereich. Prozessorspezifisch.
0x7FFFFFFFF PT_HIPROC
0x04 4 p_flags Segmentabhängige Flags (Position für 64-Bit-Struktur).
0x04 0x08 4 8 p_offset Offset des Segments im Dateibild.
0x08 0x10 4 8 p_vaddr Virtuelle Adresse des Segments im Speicher.
0x0C 0x18 4 8 p_paddr Auf Systemen, bei denen die physikalische Adresse relevant ist, reserviert für die physikalische Adresse des Segments.
0x10 0x20 4 8 p_filesz Größe in Byte des Segments im Dateibild. Kann 0 sein.
0x14 0x28 4 8 p_memsz Größe in Byte des Segments im Speicher. Kann 0 sein.
0x18 4 p_flags Segmentabhängige Flags (Position für 32-Bit-Struktur).
0x1C 0x30 4 8 p_align 0und 1geben Sie keine Ausrichtung an. Andernfalls sollte eine positive ganzzahlige Potenz von 2 sein, wobei p_vaddr p_offset modulus p_align gleichsetzt .
0x20 0x38 Ende des Programmkopfes (Größe).

Abschnittsüberschrift

Versatz Größe (Byte) Gebiet Zweck
32-Bit 64-Bit 32-Bit 64-Bit
0x00 4 sh_name Ein Offset zu einer Zeichenfolge im Abschnitt .shstrtab , der den Namen dieses Abschnitts darstellt.
0x04 4 sh_typ Gibt den Typ dieses Headers an.
Wert Name Bedeutung
0x0 SHT_NULL Tabelleneintrag Abschnittsüberschrift unbenutzt
0x1 SHT_PROGBITS Programmdaten
0x2 SHT_SYMTAB Symboltabelle
0x3 SHT_STRTAB String-Tabelle
0x4 SHT_RELA Umzugseinträge mit Nachträgen
0x5 SHT_HASH Symbol-Hash-Tabelle
0x6 SHT_DYNAMIC Dynamische Verknüpfungsinformationen
0x7 SHT_NOTE Anmerkungen
0x8 SHT_NOBITS Programmplatz ohne Daten (bss)
0x9 SHT_REL Umzugseinträge, keine Nachträge
0x0A SHT_SHLIB Reserviert
0x0B SHT_DYNSYM Dynamische Linker-Symboltabelle
0x0E SHT_INIT_ARRAY Reihe von Konstruktoren
0x0F SHT_FINI_ARRAY Array von Destruktoren
0x10 SHT_PREINIT_ARRAY Reihe von Vorkonstruktoren
0x11 SHT_GROUP Abschnittsgruppe
0x12 SHT_SYMTAB_SHNDX Erweiterte Abschnittsindizes
0x13 SHT_NUM Anzahl der definierten Typen.
0x60000000 SHT_LOOS Starten Sie betriebssystemspezifisch.
... ... ...
0x08 4 8 sh_flags Identifiziert die Attribute des Abschnitts.
Wert Name Bedeutung
0x1 SHF_WRITE Schreibbar
0x2 SHF_ALLOC Belegt Speicher während der Ausführung
0x4 SHF_EXECINSTR Ausführbar
0x10 SHF_MERGE Könnte zusammengeführt werden
0x20 SHF_STRINGS Enthält nullterminierte Strings
0x40 SHF_INFO_LINK 'sh_info' enthält den SHT-Index
0x80 SHF_LINK_ORDER Bestellung nach dem Kombinieren beibehalten
0x100 SHF_OS_NONCONFORMING Nicht standardmäßige betriebssystemspezifische Handhabung erforderlich
0x200 SHF_GROUP Abschnitt ist Mitglied einer Gruppe
0x400 SHF_TLS Abschnitt hält Thread-lokale Daten
0x0ff00000 SHF_MASKOS Betriebssystemspezifisch
0xf0000000 SHF_MASKPROC Prozessorspezifisch
0x4000000 SHF_ORDERED Besondere Bestellanforderung (Solaris)
0x8000000 SHF_EXCLUDE Abschnitt ist ausgeschlossen, es sei denn, er wird referenziert oder zugewiesen (Solaris)
0x0C 0x10 4 8 sh_addr Virtuelle Adresse des Abschnitts im Speicher für geladene Abschnitte.
0x10 0x18 4 8 sh_offset Offset des Abschnitts im Dateibild.
0x14 0x20 4 8 sh_size Größe in Byte des Abschnitts im Dateibild. Kann 0 sein.
0x18 0x28 4 sh_link Enthält den Abschnittsindex eines zugehörigen Abschnitts. Dieses Feld wird je nach Abschnittstyp für verschiedene Zwecke verwendet.
0x1C 0x2C 4 sh_info Enthält zusätzliche Informationen zum Abschnitt. Dieses Feld wird je nach Abschnittstyp für verschiedene Zwecke verwendet.
0x20 0x30 4 8 sh_addralign Enthält die erforderliche Ausrichtung des Abschnitts. Dieses Feld muss eine Zweierpotenz sein.
0x24 0x38 4 8 sh_entsize Enthält die Größe jedes Eintrags in Byte für Abschnitte, die Einträge mit fester Größe enthalten. Andernfalls enthält dieses Feld Null.
0x28 0x40 Ende der Abschnittsüberschrift (Größe)

Werkzeuge

  • readelfist ein binäres Unix-Dienstprogramm, das Informationen über eine oder mehrere ELF-Dateien anzeigt. Eine freie Softwareimplementierung wird von GNU Binutils bereitgestellt .
  • elfutilsbietet alternative Tools zu GNU Binutils ausschließlich für Linux.
  • elfdumpist ein Befehl zum Anzeigen von ELF-Informationen in einer ELF-Datei, verfügbar unter Solaris und FreeBSD .
  • objdumpbietet eine breite Palette von Informationen über ELF-Dateien und andere Objektformate. objdumpverwendet die Binary File Descriptor-Bibliothek als Back-End, um die ELF-Daten zu strukturieren.
  • Das Unix- fileDienstprogramm kann einige Informationen über ELF-Dateien anzeigen, einschließlich der Befehlssatzarchitektur, für die der Code in einer verschiebbaren, ausführbaren oder gemeinsam genutzten Objektdatei vorgesehen ist oder auf der ein ELF- Core-Dump erstellt wurde.

Anwendungen

Unix-ähnliche Systeme

Das ELF-Format hat ältere ausführbare Formate in verschiedenen Umgebungen ersetzt. Es hat die Formate a.out und COFF in Unix-ähnlichen Betriebssystemen ersetzt:

Nicht-Unix-Einführung

ELF hat auch eine gewisse Akzeptanz in Nicht-Unix-Betriebssystemen erfahren, wie zum Beispiel:

Spielekonsole

Einige Spielkonsolen verwenden auch ELF:

PowerPC

Andere (Betriebssysteme) auf PowerPC laufen , die ELF verwenden:

Mobiltelefone

Einige Betriebssysteme für Mobiltelefone und mobile Geräte verwenden ELF:

Einige Telefone können laufen ELF - Dateien durch die Verwendung eines Patches , der hinzufügt Assembler - Code zu der Haupt Firmware , die eine Funktion als bekannt ist ELFPack in der U - Bahn modding Kultur. Das ELF-Dateiformat wird auch mit Atmel AVR (8-Bit), AVR32 und mit Texas Instruments MSP430 Mikrocontroller-Architekturen verwendet. Einige Implementierungen von Open Firmware können auch ELF-Dateien laden, insbesondere die Apple -Implementierung, die in fast allen PowerPC- Maschinen des Unternehmens verwendet wird.

Spezifikationen

Die Linux Standard Base (LSB) ergänzt einige der obigen Spezifikationen für Architekturen, in denen sie spezifiziert ist. Dies ist beispielsweise bei der System V ABI, AMD64 Supplement, der Fall.

86open

86open war ein Projekt zur Konsensbildung über ein gemeinsames Binärdateiformat für Unix und Unix-ähnliche Betriebssysteme auf der gemeinsamen PC-kompatiblen x86- Architektur, um Softwareentwickler zu ermutigen, auf die Architektur zu portieren. Die ursprüngliche Idee bestand darin, eine kleine Teilmenge von Spec 1170, einem Vorgänger der Single UNIX Specification , und der GNU C Library (glibc) zu standardisieren , um die Ausführung unveränderter Binärdateien auf den x86-Unix-ähnlichen Betriebssystemen zu ermöglichen. Das Projekt wurde ursprünglich als "Spec 150" bezeichnet.

Als Format wurde schließlich ELF gewählt, insbesondere die Linux-Implementierung von ELF, nachdem es sich als De-facto- Standard herausgestellt hatte, der von allen beteiligten Herstellern und Betriebssystemen unterstützt wird.

Die Gruppe begann 1997 mit E-Mail-Diskussionen und traf sich zum ersten Mal am 22. August 1997 in den Büros der Santa Cruz Operation .

Der Lenkungsausschuss war Marc Ewing , Dion Johnson, Evan Leibovitch, Bruce Perens , Andrew Roach, Bryan Wayne Sparks und Linus Torvalds . Weitere Projektbeteiligte waren Keith Bostic , Chuck Cranor, Michael Davidson, Chris G. Demetriou, Ulrich Drepper, Don Dugger, Steve Ginzburg, Jon "maddog" Hall , Ron Holt, Jordan Hubbard , Dave Jensen, Kean Johnston, Andrew Josey, Robert Lipe, Bela Lubkin, Tim Marsland, Greg Page, Ronald Joe Record, Tim Ruckle, Joel Silverstein, Chia-pi Tien und Erik Troan. Vertretene Betriebssysteme und Firmen waren BeOS , BSDI , FreeBSD , Intel , Linux , NetBSD , SCO und SunSoft .

Das Projekt schritt voran und Mitte 1998 begann SCO mit der Entwicklung von lxrun , einer Open-Source- Kompatibilitätsschicht , die Linux-Binärdateien auf OpenServer , UnixWare und Solaris ausführen kann . SCO kündigte offizielle Unterstützung von lxrun bei Linuxworld im März 1999 Sun Microsystems begann Anfang 1999 lxrun für Solaris offiziell unterstützt und später auf die integrierte Unterstützung des Linux - Binär - Format über verschoben Solaris Container für Linux - Anwendungen .

Da die BSDs seit langem Linux-Binärdateien (durch eine Kompatibilitätsschicht ) unterstützten und die wichtigsten x86-Unix-Anbieter das Format unterstützten, entschied das Projekt, dass Linux ELF das von der Industrie gewählte Format sei und "erkläre[d] sich selbst aufgelöst" auf 25. Juli 1999.

FatELF: universelle Binärdateien für Linux

FatELF ist eine Erweiterung im ELF-Binärformat, die Fat-Binärfunktionen hinzufügt . Es richtet sich an Linux und andere Unix-ähnliche Betriebssysteme. Zusätzlich zur Abstraktion der CPU-Architektur ( Bytereihenfolge , Wortgröße , CPU- Befehlssatz usw.) gibt es den potentiellen Vorteil der Software-Plattform-Abstraktion, zB Binärdateien, die mehrere Kernel- ABI- Versionen unterstützen. Ab dem 2. März 2021 ist FatELF nicht mehr in den Mainline-Linux-Kernel integriert.

Siehe auch

Verweise

Weiterlesen

Externe Links