Was ist __i686.get_pc_thunk.bx? Warum brauchen wir diesen Aufruf?

Lesezeit: 3 Minuten

Benutzeravatar von Thangaraj
Thangaraj

Als ich meine kleine Funktion zerlegte, sah ich zufällig diesen Aufruf

call   0xf60d2f47 <__i686.get_pc_thunk.bx>.

Ich habe keine Ahnung, warum ich diesen Aufruf in meinem Programm brauche. Jede Erklärung wäre hilfreich.

Benutzeravatar von caf
Café

Dieser Aufruf wird in positionsunabhängigem Code auf x86 verwendet. Es lädt die Position des Codes in die %ebx Register, wodurch auf globale Objekte (die einen festen Offset vom Code haben) als Offset von diesem Register zugegriffen werden kann.

Positionsunabhängiger Code ist Code, der unverändert an verschiedenen Adressen geladen und ausgeführt werden kann. Dies ist wichtig für Code, der in Shared Libraries gelinkt wird, da diese in unterschiedlichen Prozessen auf eine andere Adresse gemappt werden können.

Beachten Sie, dass ein äquivalenter Aufruf ist nicht auf x86-64 erforderlich, da diese Architektur über IP-relative Adressierungsmodi verfügt (d. h. sie kann Speicherorte direkt adressieren als Offset vom Ort der aktuellen Anweisung).

  • Ich stimme zu, gibt es einen guten Link, um weitere Informationen darüber zu erhalten?

    – Thangaraj

    14. Juli 2011 um 10:01 Uhr

  • @caf, warum hat x32 keinen IP-relativen Adressierungsmodus? Wenn ich mache lea symbol(%rip), %rsi es übersetzt zu lea symbol-.-7(%rip)also versetzt die CPU die Übersetzung trotzdem (die erste Verwendung dient der Bequemlichkeit. Also noch einmal – warum tut es das? nicht haben Sie einen IP-relativen x32-Adressierungsmodus?

    – autistisch456

    12. Juni 2020 um 18:48 Uhr

  • @autistic456: Das ist 64-Bit-Code. Die RIP-relative Adressierung war neu in x86-64 (wie diese Antwort sagt) und ist im 32-Bit-Code nicht verfügbar. (Ansehen gcc -m32 Ausgabe, wenn Sie sehen möchten, wie unpraktisch 32-Bit-PIE / PIC-Code ist.) Warum nicht, nur aus historischen Gründen. 8086 hatte es nicht, und die Änderungen von 386 an den Adressierungsmodus-Codierungen (für den 32-Bit-Modus) führten zu dieser Zeit keine EIP-relative Adressierung ein. Positionsunabhängigkeit war damals (als 386 entworfen wurde) nicht so wertvoll wie später.

    – Peter Cordes

    12. Juni 2020 um 19:20 Uhr


  • @PeterCordes warum war nicht Betrachten Sie PIE zum Zeitpunkt des Entwerfens von x386 als ausführbar? Bedeutet das, dass zu dieser Zeit alle Programme auf eine absolute Adresse festgelegt waren, sodass bei vollem Speicher kein Platz mehr für neue Prozesse übrig war? Und wenn mehr Prozesse auf denselben Adresseintrag zugegriffen haben, gab es dann einen Konflikt? Soweit ich weiß, ist der PIC mit all diesen Tabellen (GOF-Tabelle, PLT-Tabelle und andere) verbunden, die direkt im ELF-Format eingebettet sind. Was bedeutet, dass es zum Zeitpunkt von 386 keine ausführbare PIC-Datei und somit kein ELF-Format gab? Oder war es anders?

    – autistisch456

    12. Juni 2020 um 21:14 Uhr

  • @autistic456: Wie von PeterCordes erwähnt, wurde die Laufzeitverlagerung auf 8086 durch die Verwendung von segmentbezogener Adressierung erreicht. Das 80286-Design sah vor, diesen Stil fortzusetzen, indem die Segmentierungsfähigkeiten des Prozessors erweitert wurden, um eine beliebige 24-Bit-Basis und -Grenze für jedes Segment zu ermöglichen, und das 80386 erweiterte dieses Design noch weiter. Später stellte sich heraus, dass ein flaches Speichermodell bevorzugt wurde, und dies prägte das spätere x86-64-Design.

    – Café

    13. Juni 2020 um 2:06 Uhr

Weitere Informationen anhand eines Beispiels hinzufügen:

Angenommen, nachdem Sie gdb innerhalb des Funktionsstarts disassiert haben, werden Sie so etwas finden:

0x012c17a3  <startup+7>:     call   0x12b2ce7 <__i686.get_pc_thunk.bx>
0x012c17a8 <startup+12>:     add    $0x10d6518,%ebx

Nachdem Sie dann __i686.get_pc_thunk.bx aufgerufen haben, wird das Register ebx mit Wert gefüllt 0x012c17a8die die Adresse der nächsten Anweisung ist.

Sie können die Funktion als get_pc(Programmzähler) lesen.

Zum besseren Verständnis fand ich diesen Artikel sehr schön:

https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html

1409970cookie-checkWas ist __i686.get_pc_thunk.bx? Warum brauchen wir diesen Aufruf?

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

Privacy policy