2013-12-17 16 views
8

Auf gcc Zielmaschinen, wenn man eine gemeinsam genutzte Bibliothek kompilieren wollte, müsste man -fpic oder -fPIC angeben, damit die Dinge korrekt funktionieren. Dies liegt daran, dass standardmäßig eine 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.Muss man -fPIC beim Kompilieren mit GCC noch verwenden?

Moderne Kernel implementieren jetzt Adressraum-Randomisierung und viele moderne Architekturen unterstützen PC-relative Adressierung. 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, die mich dazu bringt, dass es nicht mehr notwendig ist.

Ist also -fpic jetzt redundant oder muss man separate .o-Dateien erzeugen, eine für die statische Bibliothek und eine für die gemeinsame Benutzung der Bibliothek?

Antwort

0

Sie mussten nie separate .o Dateien generieren. 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, dass -fPIC diesen Modus verwendet, anstatt ein zusätzliches Register zu reservieren.

+0

PIC-Code ist in den meisten Fällen langsamer, da der zusätzliche Sprung durch den PLT bei vielen Funktionsaufrufen eine zusätzliche Indirektion erfordert. Es ist eine gute Idee, statische Bibliotheken ohne PIC zu erstellen. – Art

+0

@Art: Es kann langsamer sein, aber nicht viel. Und ich stimme nicht zu, dass es nützlich ist, statische Bibliotheken ohne zu erstellen. Statische Bibliotheken werden nicht nur in ausführbare Dateien, sondern auch in gemeinsam genutzte Bibliotheken eingebunden. Und, wie die Frage erwähnt, müssen ausführbare ASLR-Dateien auch positionsunabhängig sein. Am sichersten ist es also, '-fPIC' anzugeben. –

+0

@Art Das Problem auf einem Intel ist nicht die Funktion Anrufe oder Sprünge (die alle PC relativ sind), aber den Zugriff auf globale Daten. (Bei anderen Prozessoren sind die Probleme anders.) –

1

Ich stimme Ihnen zu: in vielen Fällen die -fpic/-fPIC Optionen sind fast überflüssig, ich aber sie verwenden, um sicherzustellen:

  • Portabilität (nie sicher, was insbesondere OS/kernel verfügbar sein wird)
  • Rückwärtskompatibilität: mit diesen Optionen es das Verhalten, das Sie auf älteren Kerneln wollen gewährleistet
  • Gewohnheit - Hard Dinge zu brechen :)
  • Übereinstimmung mit älterem Codebases, dass es möglicherweise
0 erfordern
5

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 anderen Regeln und insbesondere bei Adressraum-Randomisierung kann sie während der Verbindungszeit nicht aufgelöst werden.

Und clang hat das Flag -fPIC wie gcc.

$ cat > foo.c 
void foo(void); 
void bar(void) { foo(); } 
$ gcc -S foo.c && grep call.*foo foo.s 
    call foo 
$ gcc -fPIC -S foo.c && grep call.*foo foo.s 
    call [email protected] 
$ clang -S foo.c && grep call.*foo foo.s 
    callq foo 
$ clang -fPIC -S foo.c && grep call.*foo foo.s 
    callq [email protected] 
$ 
+1

Well-fPIC ist es nicht in der Anleitung – doron

+0

@doron Ich denke, es ist (aber vielleicht war nicht im Jahr 2013): https://clang.llvm.org/docs/ClangCommandLineReference.html#target-unabhängige- Compilation- Optionen –

0

gcc Ziele viele Plattformen und Architekturen, und nicht alle von ihnen unterstützt nativ PIC wie die x86-Architektur der Fall ist. In einigen Fällen bedeutet das Erstellen von PIC zusätzlichen Overhead, der unerwünscht sein kann und unabhängig davon, ob Sie dies wünschen oder benötigen. Dies hängt von Ihrem Projekt und der Plattform ab, auf die Sie abzielen.

0

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 Abbilddatei deaktiviert (nicht jedoch für gemeinsam genutzte Bibliotheken).