Aus dem Wiki Ausführbares und verlinkbares Format :
Die Segmente enthalten Informationen, die für die Laufzeitausführung der Datei erforderlich sind, 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 kann verwaiste Bytes geben, die keinem Abschnitt gehören.
Aber was ist der Unterschied zwischen Abschnitt und Segment? Enthält ein Segment in einer ausführbaren ELF-Datei einen oder mehrere Abschnitte?
Antworten:
Genau das, was Sie zitiert haben: Die Segmente enthalten Informationen, die zur Laufzeit benötigt werden, während die Abschnitte Informationen enthalten, die während der Verknüpfung benötigt werden.
Ein Segment kann 0 oder mehr Abschnitte enthalten. Beispiel:
Hier
PHDR
enthält das Segment 0 Abschnitte, dasINTERP
Segment enthält.interp
Abschnitte und das ersteLOAD
Segment enthält eine ganze Reihe von Abschnitten.Weiterführende Literatur mit einer schönen Illustration .
quelle
"segments contain information needed at runtime"
und"sections contain information needed during linking"
scheint ein strittiger Punkt zu sein, wenn man bedenkt, dass Abschnitte mit Segmenten enthalten sind. Es ist sinnvoll, sie wie beschrieben zu betrachten, wenn man bedenkt, dass die Art der Informationen nicht eng miteinander verbunden ist. Wenn man jedoch die Tatsache berücksichtigt, dass eine die andere enthält, wird dies etwas verwirrender.loadable
etwas sinnvoller. Betrachten Sie diese großartige Darstellung von Abschnitten / Segmenten. Danke für deinen Beitrag!Der Abschnitt enthält statische Daten für den Linker und segmentiert dynamische Daten für das Betriebssystem
Das Zitat ist korrekt, aber um den Unterschied tatsächlich zu verstehen, sollten Sie versuchen, die Felder der Einträge für Abschnittsüberschriften und Programmüberschriften (Segmente) und deren Verwendung durch den Linker (Abschnitte) und das Betriebssystem (Segment) zu verstehen. .
Besonders wichtige Informationen sind (neben den Längen):
Abschnitt: Teilen Sie dem Linker mit, ob ein Abschnitt einer der folgenden ist:
.data
,.text
usw..symtab
,.srttab
,.rela.text
Segment: teilt dem Betriebssystem mit:
Ich habe ein Tutorial geschrieben, das dies ausführlicher behandelt: http://www.cirosantilli.com/elf-hello-world/
Enthält ein Segment einen oder mehrere Abschnitte?
Ja, und es ist der Linker, der Abschnitte in Segmente unterteilt.
In Binutils wird die Art und Weise, wie Abschnitte in Segmente eingefügt werden,
ld
durch eine Textdatei bestimmt, die als Linkerskript bezeichnet wird . Dokumente: https://sourceware.org/binutils/docs/ld/Scripts.htmlSie können die Standardeinstellung mit abrufen
ld --verbose
und eine benutzerdefinierte mit festlegen-T
.Zum Beispiel enthält mein Standard-Ubuntu 17.04-Linker-Skript:
was sagt den Linker an Put Abschnitte genannt
.text.unlikely
,.text.*_unlikely
,.text.exit
etc. im.text
Segment.Die Betriebssystementwicklung ist ein Fall, in dem benutzerdefinierte Skripte nützlich sind, minimales Beispiel: https://github.com/cirosantilli/x86-bare-metal-examples/blob/d217b180be4220a0b4a453f31275d38e697a99e0/linker.ld
Sobald die ausführbare Datei verknüpft ist, kann nur festgestellt werden, welcher Abschnitt zu welchem Segment gegangen ist, wenn der Linker den optionalen Abschnittsheader in der ausführbaren Datei speichert: Wo ist die Zuordnung von Abschnitt zu Segment in ELF-Dateien gespeichert?
quelle
readelf
zeigen sie ohne Namen. Ich denke,ld
diese Namen werden als Platzhalter / Variablen im Skript verwendet, oder?ld
weiß, dass.text
Execute-Berechtigung hat, aber nicht Write.Bitte korrigieren Sie mich, wenn ich falsch liege, da ich mich nicht als Experte für dieses Thema betrachten würde, aber nach meinen Recherchen scheinen einige Aussagen in den Antworten / Kommentaren nicht ganz korrekt zu sein. Um dies zu erläutern, zitiere ich Sätze und kommentiere sie:
Gemäß diesem LWN-Artikel verwendet der Kernel nur den Segmentheader vom Typ PT_INTERP, PT_LOAD und PT_GNU_STACK, um ausführbare Dateien in den Speicher zu laden. Es gibt jedoch auch andere Segmenttypen wie PHDR, DYNAMIC, NOTE, GNU_EH_FRAME, GNU_PROPERTY, GNU_RELRO, die ignoriert werden.
Afaiu, das GNU_RELRO-Segment ist wie ein Dummy-Segment; Wenn es vorhanden ist, verwendet der Loader dies als Flag, um die Umzugsdaten schreibgeschützt zu machen. Aber der Loader ist nicht Teil des Betriebssystems, zumindest für Linux.
Bei den anderen Segmenttypen habe ich nicht herausgefunden, wofür sie tatsächlich verwendet werden. Sie erscheinen mir überflüssig, da es entsprechende Abschnitte gibt, die im Grunde die gleichen oder mehr Informationen enthalten.
Nach meinem Verständnis ist diese Antwort daher nur eine vereinfachte Annäherung an eine chaotischere Wahrheit.
Sie können ausführbare ELF-Dateien ohne Abschnittskopf haben, und verschiebbare (* .o) Dateien haben normalerweise keinen Segmentkopf. Darüber hinaus kann man in der Readelf-Ausgabe in der akzeptierten Antwort den Abschnitt .interp in mehreren Segmenten sehen. Ich sehe keine Eindämmungsbeschränkung.
Auch dies scheint eine Vereinfachung zu sein. Der Runtime Loader (oder "Interpreter") benötigt auch die Abschnitte zum Laden gemeinsam genutzter Bibliotheken, zum Auflösen von Symbolen, zum Verschieben usw.
Zusammenfassend lässt sich sagen, dass die gegebenen Antworten wahrscheinlich vernünftige allgemeine Annäherungen sind, es jedoch anscheinend komplizierter wird, wenn man sich die Details ansieht.
quelle