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?





  • 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?
    lg

    Was 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)


Log in to reply