Unterschied im positionsunabhängigen Code: x86 vs. x86-64

Lesezeit: 2 Minuten

Benutzer-Avatar
Alex B

Ich habe kürzlich eine bestimmte gemeinsam genutzte Bibliothek (ELF) erstellt, die auf die x86-64-Architektur abzielt, wie folgt:

g++ -o binary.so -shared --no-undefined ... -lfoo -lbar

Dies schlug mit folgendem Fehler fehl:

Verschiebung R_X86_64_32 gegen `ein lokales Symbol’ kann nicht verwendet werden, wenn ein gemeinsames Objekt erstellt wird; mit -fPIC neu kompilieren

Das bedeutet natürlich, dass ich es als positionsunabhängigen Code neu erstellen muss, damit es für die Verknüpfung mit einer gemeinsam genutzten Bibliothek geeignet ist.

Aber das funktioniert perfekt auf x86 mit genau den gleichen Build-Argumenten. Die Frage ist also, wie sich die Verlagerung auf x86 von x86-64 unterscheidet und warum ich nicht mit kompilieren muss -fPIC auf ersterem?

  • Ich habe das nie verstanden. Wenn der Compiler Ihnen genau sagen kann, welche Option automatisch verwendet werden soll, warum müssen Sie dann Zauberworte sagen, damit er richtig funktioniert? Grrr..

    – Billy ONeal

    2. August 2010 um 3:25 Uhr

  • @Billy ONeal, jetzt glaube ich, dass dies der Fall einer undichten Abstraktion ist. Sie unterscheiden sich darin, wie sie globale Daten laden, was sich darauf auswirkt, ob PIC benötigt wird oder nicht.

    – Alex B

    2. August 2010 um 3:40 Uhr

  • Ich verstehe die Notwendigkeit des Unterschieds. Was ich nicht verstehe, ist, warum Sie dem Compiler einen Schalter geben müssen, damit er das tut.

    – Billy ONeal

    2. August 2010 um 12:12 Uhr

  • @Billy, der Fehler kommt vom Linker

    – Gearoid Murphy

    25. September 2012 um 15:19 Uhr

  • @GearoidMurphy: Okay, 6 davon, ein halbes Dutzend von anderen. Die Kompilierung wurde mit einem einzigen Aufruf von g++ aufgerufen (anstelle von Aufrufen des Compilers und Linkers separat), daher sollte g++ leicht erkennen können, ob eine Compiler-Option eine entsprechende Linker-Option erfordert.

    – Billy ONeal

    25. September 2012 um 16:32 Uhr

  • Das ist sinnvoll – die absolute 32-Bit-Adresse kann nicht in eine relative Verschiebung umgewandelt werden, da die Ladeadresse der Bibliothek > 2 GB sein könnte.

    – Café

    30. Juni 2010 um 7:13 Uhr

  • Ja, ich verstehe, dass positionsunabhängiger Code bei der Berechnung von Sprungoffsets anders sein muss, aber ich habe Mühe zu verstehen, warum das so ist tut Arbeite auf x86 ohne -fpic.

    – Alex B

    3. Juli 2010 um 14:54 Uhr

  • @Alex, der dynamische Lader kann einige, aber nicht alle Umzugsdatensätze verarbeiten, und der Grund, warum einige Umzugsdatensätze nicht verarbeitet werden, ist, dass sie eine Situation annehmen, die nicht wahr ist. Es gibt nur ein Nicht-PIC-32-Bit-Speichermodell, und dieses Modell verwendet nur behandelte Verschiebungsaufzeichnungen. Es gibt mehrere Nicht-PIC-64-Bit-Speichermodelle, von denen einige mit dynamischer Verschiebung kompatibel sind, andere nicht. Wenn Sie -mcmodel=large mit gcc 4.4 verwenden, brauchen Sie -fpic nicht.

    – Ein Programmierer

    16. Juli 2010 um 9:58 Uhr

  • Außer dass es nicht-PIC-Bibliotheken unterstützt. Einige Umzugsdatensätze werden nicht unterstützt, da .so normalerweise so geladen werden, dass die Annahmen dieser Umzugsdatensätze nicht gültig sind, aber wenn Sie sie nicht verwenden, gibt es kein Problem.

    – Ein Programmierer

    30. Juni 2010 um 7:15 Uhr

1363220cookie-checkUnterschied im positionsunabhängigen Code: x86 vs. x86-64

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy