2016-04-06 15 views
3

Ich füge eine Thread-lokale Variable zu einigen Objektdateien hinzu, die immer direkt mit ausführbaren Dateien verknüpft sind. Diese Objekte werden niemals in einer gemeinsam genutzten Bibliothek enthalten sein (und es ist sicher anzunehmen, dass dies für die absehbare Zukunft gelten wird). Das bedeutet, dass das Flag -fPIC für diese Objekte nicht benötigt wird, richtig?Ist es möglich, Nicht-PIC-Objekte in eine ausführbare Datei mit PIC-Objekten zu verknüpfen?

Unsere Codebasis hat standardmäßig das Flag -fPIC für alle Objekte. Viele davon sind in Shared Libraries enthalten, daher ist die Verwendung von -fPIC sinnvoll. Dieses Flag weist jedoch auf ein Problem beim Debuggen der neuen lokalen Thread-Variable wegen GDB crashes while stepping over thread local variable with -fPIC hin. Wenn ich -fPIC aus diesen wenigen Objektdateien mit der neuen lokalen Threadvariablen entferne, kann ich richtig debuggen.

Ich kann keine verbindlichen Aussagen finden, dass das Mischen von Nicht-PIC-Objekten mit PIC-Objekten in einer ausführbaren Datei in Ordnung ist. Meine bisherigen Tests zeigen, dass es in Ordnung ist, aber es fühlt sich nicht koscher an, und die Online-Diskussion ist im Allgemeinen "nicht PIC und nicht PIC" aufgrund der gemeinsamen Bibliothek Fall.

Ist es in diesem Fall sicher, Nicht-PIC-Objekte in eine mit PIC-Objekten und Bibliotheken erstellte ausführbare Datei zu verknüpfen? Vielleicht gibt es eine verbindliche Aussage von GCC-Dokumenten zu diesem Thema, aber ich kann es nicht finden.

EDIT: Binär Patching gcc, um diesen Fehler zu vermeiden, ist keine kurzfristige Lösung. Das Umschalten des Compilers unter Linux ist keine mögliche Lösung.

+0

Ich denke, das sollte in Ordnung sein. Das Mischen von '-fPIC'-Code mit Nicht-PIC-Code in einer ausführbaren Datei hat die Schattenseiten von PIC (zusätzliche Indirektion für Globals/Funktionen), aber die ausführbare Datei ist nicht PIC.Sie erhalten also eine effizientere ausführbare Datei, indem Sie PIC-Objekte für Ihre gemeinsam genutzten Bibliotheken erstellen und dann die gleiche Quelle ohne PIC für die Version neu kompilieren, die in einer Nicht-PIC-Binärdatei enthalten ist. Beachten Sie, dass positionsunabhängige ausführbare Dateien eine Sache sind, und OS X erfordert sie für x86-64, aber Linux/Windows nicht. Es würde eine Adressraum-Layout-Randomisierung sogar für ausführbare Dateien und nicht nur für Bibliotheken ermöglichen. –

+0

Nicht als Antwort, weil es nicht etwas ist, das ich ausprobiert habe. Ich verstehe, wie PIC in Bezug auf die Asm-Ausgabe arbeitet, aber ich kann etwas übersehen. –

Antwort

1

Außer Bugs wie oben, sollte es in Ordnung sein. Ich kann Ihnen keine Referenzen zu definitiven Dokumenten liefern, die dies beschreiben, sondern nur aus Erfahrung sprechen. GCC (oder der Assembler) wird anderen Code erzeugen, wenn Sie -fPIC angeben, aber der resultierende Code verwendet weiterhin standardisierte Verschiebungssymbole. Für die Verknüpfung von Stücken ist dies zunächst egal, ein Linker wird nur stur alles zusammen und weiß nicht, ob der Code PIC auf Nicht-PIC-Code bezeichnet. Ich weiß das, weil ich mit Systemen arbeite, die keine gemeinsamen Bibliotheken unterstützen, und ich musste meine eigenen Loader einpacken.

Der letzte Punkt schwierig ist, dass Sie den Linker sagen können, ob das resultierende Objekt eine gemeinsame Bibliothek sein soll oder nicht. Nur dann erzeugt der Linker einige (OS-spezifische) Strukturen und Symbole, um Im-/Exporte zu bezeichnen. Andernfalls wird der Linker gerade seine Arbeit beenden, der Hauptunterschied besteht darin, dass fehlende Symbole zu einem Fehler führen.

Die saubere Trennung zwischen Compiler + Linker sollte garantieren, dass die Flags keine Rolle spielen sollten (außerhalb der Leistungsunterschiede). Ich wäre vorsichtig mit LTO hart, das hatte in der Vergangenheit mehrere Probleme mit verschiedenen Compilereinstellungen.

Wie gesagt, habe ich einige Zeit damit verbracht, dies zu untersuchen und habe mehrere Dokumente über ELF und dynamische Lader geleert. Sie werden eine explizite Erwähnung der Verknüpfung von PIC/non-PIC nirgendwo finden, aber der Linking-Prozess kümmert sich wirklich nicht um die Compiler-Einstellungen für die Eingaben, gültiger Code wird gültiger Code bleiben.

Wenn Sie Nicht-PIC-Code mit einer gemeinsam genutzten Bibliothek (PIC) verknüpfen möchten, wird der Linker beendet, wenn absolute Relocation auftritt (was sehr wahrscheinlich ist). Wenn Sie beliebigen Code mit einem Programm verknüpfen möchten, sind Sie nur beschränkt auf, was das endgültige Programm behandeln kann. Auf einem Betriebssystem, das PIC unterstützt, können Sie alles verwenden, da sich der Linker sonst über fehlende Symbole oder nicht unterstützte Bereiche/Relocation-Typen beschweren könnte.