Frage zu ELF-sections
-
hallo,
ich habe ein paar fragen zu den sections in elf-dateien:
1. was genau wird im ".shstrtab" gespeichert? laut spezifikation werden darin "section-names" gespeichert. was genau bedeutet das jetzt?
2. Was genau ist ein(e) "Symbol table"? In der ".symtab" section wird nämlich ein solcher gespeichert. leider habe ich noch nirgends eine genaue erklärung gefunden. außerdem nimmt diese section einen großteil der elf ein (mindestens ca. 2/3), aber es scheint, dass dieser symbol-table nicht so wichtig ist, denn man kann ihn ja entfernen.
3. Wie genau ist eigentlich das ELF-format lizensiert? auch dazu hab ich nichts gefunden.
und noch eine kleine assemblerfrage:
wie kann ich mit der intel-syntax unter linux einen stack erstellen?
hier http://de.wikibooks.org/wiki/Assembler-Programmierung_f%C3%BCr_x86-Prozessoren/_Unterprogramme_und_Interrupts ist das mit dem stack erklärt, es gibt auch ein kleines beispiel, leider nur für windows.
anscheinend ist das unter windows so:segment stack stack resb 64h
aber wie ist das unter linux? und was ist eigentlich der unterschied zwischen section und segment? ich mein, natürlich werden unter linux sections und unter windows segments benutzt, aber gibts sonst noch einen unterschied?
lg
-
hat denn keiner eine idee?
-
Genaueres findest du hier: http://www.skyfree.org/linux/references/ELF_Format.pdf
-
dot schrieb:
Genaueres findest du hier: http://www.skyfree.org/linux/references/ELF_Format.pdf
eben nicht. das ist nämlich die spezifikation.
-
aber das mit dem stack könntet ihr mir doch bitte sagen?
-
...... schrieb:
hallo,
ich habe ein paar fragen zu den sections in elf-dateien:
1. was genau wird im ".shstrtab" gespeichert? laut spezifikation werden darin "section-names" gespeichert. was genau bedeutet das jetzt?
Wie du vielleicht schon festgestellt hast hat jede ELF section einen Namen, z.B. mit .rodata wird die section für globale Variablen bezeichnet, welche readonly sind, also auf welche nur lesend zugegriffen werden kann. Alle diese section-Namen werden im ELF abgespeichert, nämlich in der ELF section .shstrtab. Damit ist es Programm wie objdump möglich die Namen jeder section auszugeben, z.B.
$ objdump -h /bin/sh /bin/sh: file format elf64-x86-64 Sections: Idx Name Size VMA LMA File off Algn 0 .interp 0000001c 0000000000400238 0000000000400238 00000238 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .note.ABI-tag 00000020 0000000000400254 0000000000400254 00000254 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .note.gnu.build-id 00000024 0000000000400274 0000000000400274 00000274 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .gnu.hash 0000006c 0000000000400298 0000000000400298 00000298 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .dynsym 00000960 0000000000400308 0000000000400308 00000308 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .dynstr 00000382 0000000000400c68 0000000000400c68 00000c68 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .gnu.version 000000c8 0000000000400fea 0000000000400fea 00000fea 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .gnu.version_r 00000070 00000000004010b8 00000000004010b8 000010b8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 8 .rela.dyn 00000030 0000000000401128 0000000000401128 00001128 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 9 .rela.plt 000008e8 0000000000401158 0000000000401158 00001158 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 10 .init 00000018 0000000000401a40 0000000000401a40 00001a40 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 11 .plt 00000600 0000000000401a60 0000000000401a60 00001a60 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 12 .text 00010708 0000000000402060 0000000000402060 00002060 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 13 .fini 0000000e 0000000000412768 0000000000412768 00012768 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 14 .rodata 00003522 0000000000412780 0000000000412780 00012780 2**5 CONTENTS, ALLOC, LOAD, READONLY, DATA 15 .eh_frame_hdr 000007f4 0000000000415ca4 0000000000415ca4 00015ca4 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 16 .eh_frame 00002cb4 0000000000416498 0000000000416498 00016498 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 17 .ctors 00000010 0000000000619e28 0000000000619e28 00019e28 2**3 CONTENTS, ALLOC, LOAD, DATA 18 .dtors 00000010 0000000000619e38 0000000000619e38 00019e38 2**3 CONTENTS, ALLOC, LOAD, DATA 19 .jcr 00000008 0000000000619e48 0000000000619e48 00019e48 2**3 CONTENTS, ALLOC, LOAD, DATA 20 .dynamic 00000190 0000000000619e50 0000000000619e50 00019e50 2**3 CONTENTS, ALLOC, LOAD, DATA 21 .got 00000008 0000000000619fe0 0000000000619fe0 00019fe0 2**3 CONTENTS, ALLOC, LOAD, DATA 22 .got.plt 00000310 0000000000619fe8 0000000000619fe8 00019fe8 2**3 CONTENTS, ALLOC, LOAD, DATA 23 .data 00000220 000000000061a300 000000000061a300 0001a300 2**5 CONTENTS, ALLOC, LOAD, DATA 24 .bss 00002c08 000000000061a520 000000000061a520 0001a520 2**5 ALLOC
Ohne der section .shstrtab würde man nicht sehen, dass section 24 das BSS Segment ist. (Bei diesen neumodischen ELFs heißt die .dynstr)
2. Was genau ist ein(e) "Symbol table"? In der ".symtab" section wird nämlich ein solcher gespeichert. leider habe ich noch nirgends eine genaue erklärung gefunden. außerdem nimmt diese section einen großteil der elf ein (mindestens ca. 2/3), aber es scheint, dass dieser symbol-table nicht so wichtig ist, denn man kann ihn ja entfernen.
Auch hier gilt wieder: irgendwoher muss nm ja die ganzen Funktionsnamen haben bzw. der Debugger. Solche Informationen werden auch in ELF sections abgelegt. Ein typsicher Fall wo die Symbol Table benötigt wird: wie du vielleicht weißt sind die .o Dateien die der Compiler aus den .c Dateien erzeugt auch ELF Dateien. Wenn der Linker also mehrere .o Dateien zu einem ausführbaren ELF zusammensetzt, dann kann er die symbolischen Bezeichner über die symbol tabel der einzelnen .o Dateien auflösen.
Und du hast recht beide sections werden in einem ausführbaren ELF nicht benötigt und können mit strip entfernt werden. In der Tat ist das /bin/sh auf meinem System "stripped" und daher schlägt ein nm /bin/sh fehl:
$ nm /bin/sh nm: /bin/sh: no symbols
Obwohl das ELF eine .dynsym enthält (entspricht der .symtab), denn standardmäßig sucht es nach einer .symtab, aber mit der Option -D siehst du zumindest einige Symbole, also einfach mal nm -D /bin/sh|less ausführen (die Ausgabe ist recht lang)
3. Wie genau ist eigentlich das ELF-format lizensiert? auch dazu hab ich nichts gefunden.
Da bin ich überfragt.
und noch eine kleine assemblerfrage:
wie kann ich mit der intel-syntax unter linux einen stack erstellen?
hier http://de.wikibooks.org/wiki/Assembler-Programmierung_f%C3%BCr_x86-Prozessoren/_Unterprogramme_und_Interrupts ist das mit dem stack erklärt, es gibt auch ein kleines beispiel, leider nur für windows.
anscheinend ist das unter windows so:segment stack stack resb 64h
aber wie ist das unter linux? und was ist eigentlich der unterschied zwischen section und segment? ich mein, natürlich werden unter linux sections und unter windows segments benutzt, aber gibts sonst noch einen unterschied?
lgWas hier in den Beispielen segment heißt, heißt unter Linux section. Das Segment stack ist ein spezielles Segment das den Stack enthält und wenn du den Text darunter liest, dann steht dort, dass der Assembler (oder Linker) in den EXE Header rein schreibt wie groß der Stack sein soll und wo er liegt. Windows übernimmt beim Starten deines Programmes dann die Initialisierung des Stacks (so wie in der EXE angegeben).
Wie das unter Linux aussieht kann ich dir nicht genau sagen. Vermutlich alloziiert der Kernel ein Stück dynamisches Speicher und teilt dem Prozess beim Start über ein Register die Adresse mit. Den Rest übernimmt dann die Laufzeitumgebung, welche Initialisierungen vor Start der main-Funktion durchführt. In C++ werden z.B. die Konstruktoren von globalen Objekten aufgerufen. (Diese stehen übrigens in der section .ctors)