Co oznacza -fPIC podczas tworzenia biblioteki współdzielonej?

109

Wiem, że -fPICopcja „ ” ma coś wspólnego z rozwiązywaniem adresów i niezależnością między poszczególnymi modułami, ale nie jestem pewien, co to naprawdę oznacza. Możesz wytłumaczyć?

ks1322
źródło
1
Jeśli chcesz wiedzieć bardziej szczegółowo, jest tutaj świetny artykuł ( akkadia.org/drepper/dsohowto.pdf )
MJ

Odpowiedzi:

61

PIC to skrót od Position Independent Code

i cytując man gcc:

Jeśli jest obsługiwany przez maszynę docelową, emituje kod niezależny od pozycji, odpowiedni do dynamicznego łączenia i unikania ograniczeń rozmiaru globalnej tabeli offsetów. Ta opcja ma znaczenie w przypadku m68k, PowerPC i SPARC. Kod niezależny od pozycji wymaga specjalnego wsparcia i dlatego działa tylko na niektórych komputerach.

użyj tego podczas budowania obiektów współdzielonych (* .so) na wspomnianych architekturach.

Sean Riley
źródło
1
f nic nie znaczy, to tylko część nazwy opcji.
Zifre
17
Istnieje różnica między fpic i fPIC. Obaj robią to samo, ale fpic używa krótszego względnego przesunięcia, jeśli jest dostępny. Dlatego kompilacja z fpic może potencjalnie generować mniejsze pliki. Niestety nie zawsze działa zgodnie z oczekiwaniami, więc użyj fPIC. Należy również pamiętać, że nie wszystkie procesory obsługują krótsze przesunięcia, więc może to nie mieć znaczenia.
Martin York
2
`` F '' to kac po sposobie, w jaki gcc przenosił argumenty wiersza poleceń (było to kilka lat temu i zmienili tę część kodu, której ostatnio nie szukałem). Ale w tamtym czasie tylko niektóre litery lub kombinacje były dozwolone w różnych warunkach (był bardzo złożony język definiowania argumentów wiersza poleceń), w wyniku czego użyto „f”, aby ułatwić zdefiniowanie go jako argumentu wiersza poleceń.
Martin York
2
Co się stanie, jeśli zbuduje się * .so bez fPIC?
Isa A
2
@IsaA Kompilowałem dziś funkcję mysql c-api ze źródła i nie mogła się zbudować, /usr/bin/ld: /tmp/cc7hXILq.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPICwięc dodałem fPIC i zbudowałem.
chiliNUT
32

Jest fto przedrostek gcc dla opcji, które „kontrolują konwencje interfejsu używane podczas generowania kodu”

W PICoznacza „Position Kodeksu Independent”, jest to specjalizacja fpicdla m68k i SPARC.

Edycja: Po przeczytaniu strony 11 dokumentu, do którego odwołuje się 0x6adb015 i komentarzu coryana, dokonałem kilku zmian:

Ta opcja ma sens tylko w przypadku bibliotek współdzielonych i mówisz systemowi operacyjnemu, że używasz globalnej tabeli przesunięć, GOT. Oznacza to, że wszystkie odwołania do adresu odnoszą się do terminala GOT, a kod można udostępniać w wielu procesach.

W przeciwnym razie bez tej opcji program ładujący musiałby sam zmodyfikować wszystkie przesunięcia.

Nie trzeba dodawać, że prawie zawsze używamy -fpic / PIC.

Mark Beckwith
źródło
1
Myślałem, że system operacyjny może swobodnie ładować bibliotekę na dowolny adres wirtualny, ale bez pic / PIC program ładujący musi zmodyfikować kod i dostosować wszystkie bezwzględne skoki + pośrednie do rzeczywistych lokalizacji procedur / bibliotek. Dzięki pic / PIC kod nie jest modyfikowany, a zatem jest naprawdę współdzielony przez wiele procesów.
coryan
Wiele procesów jest w dużej mierze przypadkowych - ich kluczową kwestią jest to, że kod można załadować pod dowolnym adresem wirtualnym z absolutnym minimum poprawek adresu.
Jonathan Leffler
16

man gcc mówi:

-fpic
  Wygeneruj kod niezależny od pozycji (PIC) odpowiedni do użycia we współdzielonym pliku
  biblioteka, jeśli jest obsługiwana przez maszynę docelową. Taki kod ma dostęp do wszystkich
  stałe adresy poprzez globalną tablicę ofsetów (GOT). Dynamika
  loader rozwiązuje wpisy GOT podczas uruchamiania programu (plik dynamic
  loader nie jest częścią GCC; jest częścią systemu operacyjnego). Jeśli
  rozmiar GOT dla połączonego pliku wykonywalnego przekracza określony dla komputera
  maksymalny rozmiar, otrzymasz komunikat o błędzie od konsolidatora wskazujący
  że -fpic nie działa; w takim przypadku należy ponownie skompilować z -fPIC.
  (Te maksymalne wartości to 8k na SPARC i 32k na m68k i RS / 6000.
  386 nie ma takiego limitu).

  Kod niezależny od pozycji wymaga specjalnego wsparcia i dlatego
  działa tylko na niektórych komputerach. W przypadku 386 GCC obsługuje PIC dla
  System V, ale nie dla Sun 386i. Kod wygenerowany dla
  IBM RS / 6000 jest zawsze niezależny od pozycji.

-fPIC
  Jeśli jest obsługiwany dla maszyny docelowej, emituj kod niezależny od pozycji,
  nadaje się do dynamicznego łączenia i pozwala uniknąć ograniczeń rozmiaru
  globalna tabela offsetów. Ta opcja ma znaczenie w przypadku m68k
  i SPARC.

  Kod niezależny od pozycji wymaga specjalnego wsparcia i dlatego
  działa tylko na niektórych komputerach.
Nikolai Fetissov
źródło