2016-05-12 4 views
4

Wenn ein triviales Programm mit dem folgenden Befehl kompiliert wird:Warum wird ein mit "-fpic" und "-pie" zusammengestelltes Programm eine Relocation-Tabelle erstellt?

arm-none-eabi-gcc -shared -fpic -pie --specs=nosys.specs simple.c -o simple.exe 

und die Verlagerung Einträge werden mit dem Befehl gedruckt:

arm-none-eabi-readelf simple.exe -r 

ein Bündel Verlagerung es Einträge Abschnitt (siehe unten).

Da die Flags -fpic/-pie bewirken, dass der Compiler eine positionsunabhängige ausführbare Datei generiert, ist meine naive (und eindeutig falsche) Annahme, dass keine Umlagerungstabelle benötigt wird, da der Loader das ausführbare Bild überall ohne Problem platzieren kann . Warum gibt es überhaupt eine Verschiebungstabelle, und zeigt dies an, dass der Code nicht wirklich positionsunabhängig ist?

Relocation section '.rel.dyn' at offset 0x82d4 contains 37 entries: 
Offset  Info Type   Sym.Value Sym. Name 
000084a8 00000017 R_ARM_RELATIVE 
000084d0 00000017 R_ARM_RELATIVE 
00008508 00000017 R_ARM_RELATIVE 
00008510 00000017 R_ARM_RELATIVE 
0000855c 00000017 R_ARM_RELATIVE 
00008560 00000017 R_ARM_RELATIVE 
00008564 00000017 R_ARM_RELATIVE 
00008678 00000017 R_ARM_RELATIVE 
0000867c 00000017 R_ARM_RELATIVE 
0000870c 00000017 R_ARM_RELATIVE 
00008710 00000017 R_ARM_RELATIVE 
00008714 00000017 R_ARM_RELATIVE 
00008718 00000017 R_ARM_RELATIVE 
00008978 00000017 R_ARM_RELATIVE 
000089dc 00000017 R_ARM_RELATIVE 
000089e0 00000017 R_ARM_RELATIVE 
00008abc 00000017 R_ARM_RELATIVE 
00008ae4 00000017 R_ARM_RELATIVE 
00018af4 00000017 R_ARM_RELATIVE 
00018af8 00000017 R_ARM_RELATIVE 
00018afc 00000017 R_ARM_RELATIVE 
00018c04 00000017 R_ARM_RELATIVE 
00018c08 00000017 R_ARM_RELATIVE 
00018c0c 00000017 R_ARM_RELATIVE 
00018c34 00000017 R_ARM_RELATIVE 
00019028 00000017 R_ARM_RELATIVE 
000084cc 00000c02 R_ARM_ABS32  00000000 __libc_fini 
0000850c 00000602 R_ARM_ABS32  00000000 __deregister_frame_inf 
00008558 00001302 R_ARM_ABS32  00000000 __register_frame_info 
00008568 00001202 R_ARM_ABS32  00000000 _Jv_RegisterClasses 
00008664 00000d02 R_ARM_ABS32  00000000 __stack 
00008668 00000a02 R_ARM_ABS32  00000000 hardware_init_hook 
0000866c 00000802 R_ARM_ABS32  00000000 software_init_hook 
00008670 00000502 R_ARM_ABS32  0001902c __bss_start__ 
00008674 00000702 R_ARM_ABS32  00019048 __bss_end__ 
0000897c 00001402 R_ARM_ABS32  00000000 free 
00008ac0 00000402 R_ARM_ABS32  00000000 malloc 

Relocation section '.rel.plt' at offset 0x83fc contains 4 entries: 
Offset  Info Type   Sym.Value Sym. Name 
00018be8 00000416 R_ARM_JUMP_SLOT 00000000 malloc 
00018bec 00000616 R_ARM_JUMP_SLOT 00000000 __deregister_frame_inf 
00018bf0 00001316 R_ARM_JUMP_SLOT 00000000 __register_frame_info 
00018bf4 00001416 R_ARM_JUMP_SLOT 00000000 free 
+0

http://stackoverflow.com/questions/3544035/what-is-the-difference-between-fpic-and-fpic-gcc-parameters/3544211 – user3159253

+0

Relocatable bedeutet, dass die Symbole eine indirekte Ebene benötigen, da die Der Speicherort kann sich für eine ausführbare Datei von einer anderen unterscheiden. Statisch verknüpfte Bibliotheken haben ihre Positionen zum Zeitpunkt der statischen Verknüpfung festgelegt. – jxh

Antwort

0

Eine ausführbare besteht aus mehreren Abschnitten .

  1. Read-Only ausführbaren Code, der auch als "Text"
  2. Read-Only Constant Daten (globale Konstanten)
  3. (bekannt: Während die tatsächliche Implementierung Details unterscheiden, können diese grob in vier Gruppen eingeteilt werden Read-Write initialisierte) Daten (globale Variablen mit initializers)
  4. Uninitialized Read-Write Data (andere globale Variablen initialisiert 0)

Nichtpositionsunabhängigen Code co Es gibt viele Referenzen auf die Adressen von Funktionen, globalen Variablen und globalen Konflikten.

Read-Only Daten und Initialized Read-Write Data manchmal Verweise auf die Adressen von Funktionen enthalten, globale Variablen und globale constsants:

int x; 
int *y = &x; // y needs a relocation. 

Der Lader kann Code relocate basierend auf Verlagerungen gibt sind nur zwei Probleme:

  1. Relocations Zeit beim Programmstart/Bibliothek Laden nehmen
  2. Wenn wir umziehen, haben wir jetzt eine In-RAM-modifizierte Kopie des Textsegments, die für jeden Prozess unterschiedlich ist, der unsere Bibliothek lädt, also verschwenden wir RAM.

Jetzt für die richtige Antwort: PIC war beabsichtigt, die obigen Probleme zu lösen, indem Verlagerungen Text loszuwerden, nicht von allen Verlagerungen loszuwerden.

Es gibt vergleichsweise wenige Umlagerungen in schreibgeschützten Daten und initialisierten Daten, sodass weder (1.) noch (2.) normalerweise ein Problem darstellen. Wir kümmern uns nicht einmal um (2.) für Lese-Schreib-Daten, da wir für jeden Prozess separate Kopien davon benötigen. Und in der Tat gibt es keine Möglichkeit für den Compiler, Daten positionsunabhängig zu machen, denn wenn Sie nach einem globalen gefragt haben, dann hat der Compiler keine andere Wahl, als den Zeiger dorthin zu setzen.

Nun, wie wird Code positionsunabhängig gemacht? Das hängt von der Plattform ab, aber es beinhaltet oft einige relativ ineffiziente Operationen, oder der Prozessor legt willkürliche Grenzen für die maximalen Offsets fest, die in den effizienteren Anweisungen zum ortsunabhängigen Zugriff auf Datencode verwendet werden. Außerdem bedeutet dynamische Verknüpfung, dass die Adresse einiger Funktionen nicht einmal als relativer Offset bekannt ist. So neigen Compiler dazu, Tabellen zu verwenden, die die tatsächlichen Adressen enthalten, und der Code wird die tatsächlichen Adressen aus der Tabelle nachschlagen. Die Tabellen, die als GOT, TOC, PLT und wahrscheinlich einige andere Namen auf verschiedenen Plattformen bekannt sind, werden wahrscheinlich Constant Data mit vielen Umzügen sein.

Wenn Umsiedlungen nicht vermieden werden können, besteht die Idee darin, sie alle an einem Ort zu platzieren, um Probleme zu minimieren (1.) und (2.).

Verwandte Themen