Cosa significa -fPIC quando si crea una libreria condivisa?


109

So che l' -fPICopzione " " ha qualcosa a che fare con la risoluzione degli indirizzi e l'indipendenza tra i singoli moduli, ma non sono sicuro di cosa significhi veramente. Puoi spiegare?


1
Inoltre, nel caso volessi sapere più in dettaglio, c'è un ottimo articolo qui ( akkadia.org/drepper/dsohowto.pdf )
MJ

Risposte:


61

PIC sta per Position Independent Code

e per citare man gcc:

Se supportato per la macchina di destinazione, emette codice indipendente dalla posizione, adatto per il collegamento dinamico ed evitando qualsiasi limite alla dimensione della tabella offset globale. Questa opzione fa la differenza su m68k, PowerPC e SPARC. Il codice indipendente dalla posizione richiede un supporto speciale e quindi funziona solo su determinate macchine.

usalo quando costruisci oggetti condivisi (* .so) su quelle architetture menzionate.


1
f non significa niente, è solo una parte del nome dell'opzione.
Zifre

17
C'è una differenza tra fpic e fPIC. Entrambi fanno la stessa cosa, ma fpic utilizza un offset relativo più breve ove disponibile. Pertanto la compilazione con fpic può potenzialmente produrre file più piccoli. Purtroppo non sempre funziona come previsto, quindi usa fPIC. Notare inoltre che non tutti i processori supportano gli offset più brevi, quindi potrebbe non fare la differenza.
Martin York,

2
La 'f' è una sbornia dal modo in cui gcc gestisce gli argomenti della riga di comando (questo è stato un paio di anni fa e hanno cambiato questa parte del codice che non ho guardato di recente). Ma all'epoca solo alcune lettere o combinazioni erano consentite in condizioni diverse (c'era un linguaggio molto complesso per definire gli argomenti della riga di comando), di conseguenza la "f" è stata utilizzata per renderlo facile da definire come argomento della riga di comando.
Martin York,

2
Cosa succederà se si crea un * .so senza fPIC?
Isa A

2
@IsaA Oggi stavo compilando una funzione mysql c-api dal sorgente e non si sarebbe compilata, /usr/bin/ld: /tmp/cc7hXILq.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPICquindi ho aggiunto fPIC e l'ho compilata.
chiliNUT

32

Il fè il prefisso gcc per le opzioni che "controllano le convenzioni dell'interfaccia utilizzate nella generazione di codice"

L' PICacronimo di "Position Independent Code", è una specializzazione di fpicm68K e SPARC.

Modifica: dopo aver letto la pagina 11 del documento a cui fa riferimento 0x6adb015 e il commento di coryan, ho apportato alcune modifiche:

Questa opzione ha senso solo per le librerie condivise e stai dicendo al sistema operativo che stai utilizzando una tabella offset globale, GOT. Ciò significa che tutti i riferimenti agli indirizzi sono relativi al GOT e il codice può essere condiviso tra più processi.

Altrimenti, senza questa opzione, il caricatore dovrebbe modificare da solo tutti gli offset.

Inutile dire che usiamo quasi sempre -fpic / PIC.


1
Pensavo che il sistema operativo fosse libero di caricare la libreria in qualsiasi indirizzo virtuale, ma senza pic / PIC il caricatore deve modificare il codice e regolare tutti i salti assoluti + le indicazioni indirette alle posizioni effettive delle routine / librerie. Con pic / PIC il codice non viene modificato e quindi è realmente condiviso tra più processi.
coryan

Più processi sono in gran parte casuali: il punto chiave è che il codice può essere caricato in qualsiasi indirizzo virtuale con un minimo assoluto di correzioni degli indirizzi.
Jonathan Leffler,

16

man gcc dice:

-fPIC
  Genera codice indipendente dalla posizione (PIC) adatto per l'uso in un file condiviso
  libreria, se supportata per la macchina di destinazione. Tale codice accede a tutti
  indirizzi costanti tramite una tabella di offset globale (GOT). La dinamica
  loader risolve le voci GOT all'avvio del programma (il file dynamic
  loader non fa parte di GCC; fa parte del sistema operativo). Se
  la dimensione GOT per l'eseguibile collegato supera una specifica della macchina
  dimensione massima, viene visualizzato un messaggio di errore dal linker che indica
  che -fpic non funziona; in tal caso, ricompilare con -fPIC invece.
  (Questi massimi sono 8k su SPARC e 32k su m68k e RS / 6000.
  Il 386 non ha tale limite.)

  Il codice indipendente dalla posizione richiede un supporto speciale e quindi
  funziona solo su alcune macchine. Per il 386, GCC supporta PIC per
  System V ma non per Sun 386i. Codice generato per
  IBM RS / 6000 è sempre indipendente dalla posizione.

-fPIC
  Se supportato per la macchina di destinazione, emette codice indipendente dalla posizione,
  adatto per il collegamento dinamico ed evitando qualsiasi limite alla dimensione di
  la tabella offset globale. Questa opzione fa la differenza sull'm68k
  e lo SPARC.

  Il codice indipendente dalla posizione richiede un supporto speciale e quindi
  funziona solo su alcune macchine.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.