Auf gcc-Zielmaschinen müsste man, wenn man eine gemeinsam genutzte Bibliothek kompilieren möchte, -fpic oder -fPIC angeben, damit die Dinge korrekt funktionieren. Dies liegt daran, dass standardmäßig absolute Adressierung verwendet wurde, die für ausführbare Dateien geeignet ist, die die volle Kontrolle über ihren eigenen Adressraum haben, aber keine gemeinsam genutzten Bibliotheken, die irgendwo in den Adressraum einer ausführbaren Datei geladen werden können.
Moderne Kernel implementieren jedoch Adressraum-Randomisierung und viele moderne Architekturen unterstützen die relative Adressierung von PCs. Dies alles scheint die absolute Adressierung entweder unbrauchbar zu machen (Adressraum-Randomisierung) oder unnötig (relative PC-Adressierung).
Ich habe auch bemerkt, dass clang keine -fPIC-Option hat, was mich dazu bringt, dass es nicht länger notwendig ist.
Ist also -fpic jetzt redundant oder muss man separate .o-Dateien erzeugen, eine für die Benutzung der statischen Bibliothek und eine für die Benutzung der gemeinsamen Bibliothek?
Sie müssen noch mit -fPIC kompilieren. Das Problem ist mit pc-relativer Adressierung nicht lösbar. Das Problem ist, wie Sie externe Symbole auflösen. In einem dynamisch verknüpften Programm folgt die Auflösung verschiedenen Regeln und insbesondere bei Adressraum-Randomisierung kann sie während der Verbindungszeit nicht aufgelöst werden.
Und clang hat das Flag -fPIC genau wie gcc.
%Vor%Ich stimme Ihnen zu: In vielen Fällen sind die Optionen -fpic / -fPIC fast überflüssig, aber ich verwende sie, um Folgendes sicherzustellen:
Sie mussten nie separate .o
-Dateien erzeugen. Geben Sie immer die Compileroptionen an, um portablen Code zu generieren (normalerweise -fPIC
).
Auf einigen Systemen ist der Compiler möglicherweise so konfiguriert, dass er diese Option erzwingt oder standardmäßig aktiviert. Aber es tut nicht weh, es trotzdem zu spezifizieren.
Hinweis: Man hofft, dass dort, wo PC-relative Adressierung unterstützt wird und gut funktioniert , -fPIC
diesen Modus verwendet, anstatt ein zusätzliches Register zu reservieren.
gcc
richtet sich an viele Plattformen und Architekturen, und nicht alle unterstützen native PICs wie die x86-Architektur. In einigen Fällen bedeutet die Erstellung von PIC zusätzlichen Overhead, der unerwünscht sein kann und unabhängig davon, ob dies von Ihrem Projekt und der Plattform, auf die Sie abzielen, abhängt.
Es hängt vom Ziel ab. Einige Ziele (wie x86_64) sind standardmäßig positionsunabhängig, sp -fpic
ist ein Noop und hat keine Auswirkungen auf den generierten Code. In diesen Fällen können Sie es weglassen und nichts ändert sich. Andere Ziele (wie x86 32-Bit) sind standardmäßig nicht positionsunabhängig. Wenn Sie auf diesen Rechnern -fpic
für die ausführbare Datei weglassen, wird ASLR für diese Bilddatei deaktiviert (nicht jedoch für gemeinsam genutzte Bibliotheken).