Was bedeutet -fPIC beim Erstellen einer gemeinsam genutzten Bibliothek?


109

Ich weiß, dass -fPICdie Option ' ' etwas mit dem Auflösen von Adressen und der Unabhängigkeit zwischen einzelnen Modulen zu tun hat, bin mir aber nicht sicher, was dies wirklich bedeutet. Können Sie erklären?


1
Auch für den Fall, dass Sie mehr wissen möchten, gibt es hier einen großartigen Artikel ( akkadia.org/drepper/dsohowto.pdf )
MJ

Antworten:


61

PIC steht für Position Independent Code

und um zu zitieren man gcc:

Wenn dies für den Zielcomputer unterstützt wird, geben Sie positionsunabhängigen Code aus, der für die dynamische Verknüpfung geeignet ist und eine Begrenzung der Größe der globalen Versatztabelle vermeidet. Diese Option macht einen Unterschied bei m68k, PowerPC und SPARC. Positionsunabhängiger Code erfordert spezielle Unterstützung und funktioniert daher nur auf bestimmten Computern.

Verwenden Sie diese Option, wenn Sie gemeinsam genutzte Objekte (* .so) auf den genannten Architekturen erstellen.


1
f bedeutet nichts, es ist nur ein Teil des Optionsnamens.
Zifre

17
Es gibt einen Unterschied zwischen fpic und fPIC. Beide machen dasselbe, aber fpic verwendet einen kürzeren relativen Versatz, sofern verfügbar. Das Kompilieren mit fpic kann daher möglicherweise kleinere Dateien erzeugen. Leider funktioniert es nicht immer wie erwartet, verwenden Sie also fPIC. Beachten Sie auch, dass nicht alle Prozessoren die kürzeren Offsets unterstützen, sodass dies möglicherweise keinen Unterschied macht.
Martin York

2
Das 'f' ist ein Kater von der Art und Weise, wie gcc Befehlszeilenargumente handhabte (dies war vor ein paar Jahren und sie haben diesen Teil des Codes geändert, den ich in letzter Zeit nicht gesehen habe). Zu dieser Zeit waren jedoch nur bestimmte Buchstaben oder Kombinationen unter verschiedenen Bedingungen zulässig (es gab eine sehr komplexe Sprache zum Definieren von Befehlszeilenargumenten). Daher wurde das 'f' verwendet, um die Definition als Befehlszeilenargument zu vereinfachen.
Martin York

2
Was passiert, wenn man ein * .so ohne fPIC baut?
Isa A

2
@IsaA Ich habe heute eine C-API-MySQL-Funktion aus dem Quellcode kompiliert und sie wurde nicht erstellt. Ich habe /usr/bin/ld: /tmp/cc7hXILq.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPICalso fPIC hinzugefügt und sie erstellt.
ChiliNUT

31

Das fist der gcc Präfix für Optionen , die „die Schnittstellenkonventionen in der Codegenerierung verwendet Control“

Das PICsteht für "Position Independent Code", es ist eine Spezialisierung des fpicfür m68K und SPARC.

Bearbeiten: Nachdem ich Seite 11 des Dokuments gelesen hatte , auf das 0x6adb015 verweist , und den Kommentar von Coryan, nahm ich einige Änderungen vor:

Diese Option ist nur für gemeinsam genutzte Bibliotheken sinnvoll und Sie teilen dem Betriebssystem mit, dass Sie eine globale Offset-Tabelle (GOT) verwenden. Dies bedeutet, dass alle Ihre Adressreferenzen relativ zum GOT sind und der Code für mehrere Prozesse freigegeben werden kann.

Andernfalls müsste der Loader ohne diese Option alle Offsets selbst ändern.

Natürlich verwenden wir fast immer -fpic / PIC.


1
Ich dachte, das Betriebssystem könnte die Bibliothek in eine beliebige virtuelle Adresse laden, aber ohne pic / PIC muss der Loader den Code ändern und alle absoluten Sprünge + Indirektionen an die tatsächlichen Positionen der Routinen / Bibliotheken anpassen. Mit pic / PIC wird der Code nicht geändert und somit wirklich von mehreren Prozessen gemeinsam genutzt.
Coryan

Mehrere Prozesse sind weitgehend zufällig - der entscheidende Punkt ist, dass der Code an jeder virtuellen Adresse mit einem absoluten Minimum an Adresskorrekturen geladen werden kann.
Jonathan Leffler

16

man gcc sagt:

-fpic
  Generieren Sie einen positionsunabhängigen Code (PIC), der für die Verwendung in einem gemeinsam genutzten Code geeignet ist
  Bibliothek, falls für den Zielcomputer unterstützt. Ein solcher Code greift auf alle zu
  konstante Adressen über eine globale Offset-Tabelle (GOT). Die Dynamik
  Der Loader löst die GOT-Einträge beim Start des Programms auf (die Dynamik
  Der Lader ist nicht Teil von GCC. es ist Teil des Betriebssystems). Wenn
  Die GOT-Größe für die verknüpfte ausführbare Datei überschreitet eine maschinenspezifische
  Bei maximaler Größe erhalten Sie vom Linker eine Fehlermeldung
  das -fpic funktioniert nicht; In diesem Fall kompilieren Sie stattdessen mit -fPIC neu.
  (Diese Höchstwerte betragen 8k beim SPARC und 32k beim m68k und RS / 6000.
  Der 386 hat keine solche Grenze.)

  Positionsunabhängiger Code erfordert daher besondere Unterstützung
  funktioniert nur auf bestimmten Maschinen. Für den 386 unterstützt GCC PIC für
  System V, aber nicht für die Sun 386i. Code generiert für die
  IBM RS / 6000 ist immer positionsunabhängig.

-fPIC
  Wenn dies für den Zielcomputer unterstützt wird, geben Sie positionsunabhängigen Code aus.
  Geeignet für die dynamische Verknüpfung und zur Vermeidung von Größenbeschränkungen von
  die globale Offset-Tabelle. Diese Option macht beim m68k einen Unterschied
  und der SPARC.

  Positionsunabhängiger Code erfordert daher besondere Unterstützung
  funktioniert nur auf bestimmten Maschinen.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.