Gentoo Logo

[ << ] [ < ] [ Home ] [ > ] [ >> ]


3. Guida per riparare gli errori relativi a -fPIC

Indice:

3.a. Il Problema

Capita a volte che GCC termini con un messaggio di errore simile al seguente:

Codice 1.1: Tipico messaggio di errore di GCC

.libs/assert.o: relocation R_X86_64_32 against `a local symbol' can not be used
when making a shared object; recompile with -fPIC .libs/assert.o: could not
read symbols: Bad value

Ci sono molte tipologie differenti di cause per un dato errore. Questo HOWTO le spiegherà tutte mostrando le possibili correzioni.

3.b. Cosa è PIC?

PIC è l'abbreviazione di Position-Independent Code (ndt Codice Indipendente dalla Posizione). Il seguente è un estratto dell' articolo su Wikipedia(tradotto) in merito al codice indipendente dalla posizione:

"In informatica, per codice indipendente dalla posizione (PIC, Position-Independent Code) o eseguibile indipendente dalla posizione (PIE, Position-Independent Executable) s'intende del codice oggetto che può essere eseguito in differenti locazioni in memoria. Il codice PIC è comunemente usato per librerie condivise, in modo da permettere che la stessa libreria possa essere mappata in una locazione di memoria unica per ogni applicazione (usando il sistema della memoria virtuale) dove non può sovrapporsi all'applicazione o ad altre librerie condivise. Il codice PIC è stato utilizzato anche su vecchi sistemi senza supporto MMU, in modo da permettere al sistema operativo di poter mantenere le applicazioni reciprocamente separate.

Il codice indipendente dalla posizione può essere copiato in ogni locazione di memoria senza modifiche ed esecuzioni, contrariamente dal codice rilocabile, che necessità di una analisi speciale da parte di un link editor oppure di un program loader per renderlo adatto all'esecuzione in una data locazione. Il codice deve essere generalmente scritto o compilato in un modo particolare per renderlo indipendente dalla posizione. Le istruzioni che riferiscono ad indirizzi di memoria specifici, come salti assoluti, devono essere sostituite con operazioni equivalenti ma relative al program-counter. L'indirezione aggiuntiva può causare al codice PIC di essere meno efficiente, anche se i moderni processori sono progettati per portare migliorie in tal senso."

—tratto da Wikipedia Encyclopaedia (traduzione dalla versione inglese)

Su alcune architetture (tra cui AMD64), le librerie condivise devono essere "PIC-abilitate" (ndt, "PIC-enabled").

3.c. Cosa sono le "riallocazioni"?

Ancora una volta, da Wikipedia:

"In informatica, la rilocazione si riferisce al processo di sostituzione dei riferimenti simbolici o nomi di librerie con gli attuali ed usabili indirizzi di memoria, prima dell'esecuzione del programma stesso. Questa attività è svolta tipicamente dal linker durante la compilazione, ma può essere svolta a tempo di esecuzione dal program loader. I compilatori e gli assemblatori tipicamente generano l'eseguibile con zero come indirizzo iniziale. Prima dell'esecuzione del codice oggetto, questi indirizzi devono essere modificati in modo che possano denotare indirizzi validi a tempo di esecuzione"

—tratto da Wikipedia Encyclopaedia (traduzione dalla versione inglese)

Con questi termini definiti, è possibile dare uno sguardo ai differenti scenari dove possono verificarsi dei problemi:

3.d. 1° Caso: Compilatore malfunzionante (broken)

Almeno GCC 3.4 è conosciuto per avere una implementazione errata dell'opzione -fvisibility-inlines-hidden. L'uso di questa opzione è comunque altamente scoraggiata ed i bug relativi riportati sono solitamente marcati come "RESOLVED INVALID". Vedere il bug 108872 per un esempio di un tipico errore causato da questa opzione.

3.e. 2° Caso: Controllo errato del supporto `-fPIC' nel "configure"

Molti strumenti configure verificano l'eventuale supporto per l'opzione -fPIC da parte del compilatore. La verifica è eseguita compilando un programma minimale con l'opzione -fPIC e verificando lo stderr. Se il compilatore visualizza un qualsiasi messaggio di avvertimento (warning), è assunto che l'opzione -fPIC non sia supportata ed è quindi abbandonata. Sfortunatamente, se l'utente specifica una opzione inesistente (per esempio, delle opzioni C++ in CFLAGS oppure opzioni introdotte dalle nuove versioni di GCC ma non supportate dalle versioni precedenti), GCC visualizza in ogni caso un messaggio di avviso ("warning"), ottenendo un malfunzionamento della procedura di verifica.

Per evitare questo tipo di problema, i profili definiti per AMD64 usano un bashrc che filtra le opzioni definite in C[XX]FLAGS non valide.

Vedere il bug 122208 per un esempio.

3.f. 3° Caso: Assenza del supporto a `-fPIC' nel software da compilare

Questo è il caso più comune. È un vero bug del sistema di compilazione e dovrebbe essere corretto nell'ebuild, preferibilmente attraverso una patch da sottoporre agli sviluppatori originali del software. Assumendo che l'errore sia simile a questo:

Codice 6.1: Un esempio di messaggio di errore

.libs/assert.o: relocation R_X86_64_32 against `a local symbol' can not be used
when making a shared object; recompile with -fPIC .libs/assert.o: could not
read symbols: Bad value

Questo significa che il file assert.o non è stato compilato con l'opzione -fPIC, contrariamente a come dovrebbe essere. Per la correzione di questo tipo di errore, bisogna assicurarsi che solo gli oggetti usati nelle librerie siano compilati con -fPIC.

In questo caso, aggiungendo globalmente -fPIC in C[XX]FLAGS si risolverebbe il problema, ma questa pratica è scoraggiata perché anche gli eseguibili finirebbero per essere abilitati per essere PIC.

Nota: L'aggiunta dell'opzione -fPIC al comando di linking o in LDFLAGS non aiuta.

3.g. 4° Caso: Collegare dinamicamente rispetto archivi statici

Capita qualche volta che un pacchetto possa creare delle librerie condivise usando archivi compilati staticamente e non abilitati come PIC. Ci sono due ragioni principali perché questo possa accadere:

Spesso è il risultato di un mix di USE=static e USE=-static. Se un pacchetto di libreria può essere compilato staticamente impostando USE=static, solitamente non crea un file .so ma solo un archivio .a. Comunque, quando a GCC viene passata l'opzione -l per collegare detta (dinamica o statica) libreria, esso ripiega sull'archivio statico quando non può individuare la relativa libreria condivisa. In questo caso, la soluzione preferita è la compilazione statica della libreria usando anche l'opzione -fPIC.

Avvertenza: Compilare gli archivi statici con l'opzione -fPIC abilitata solo su AMD64. Su altre architetture questo non è necessario ed avrà un impatto a tempo di esecuzione.

Vedere i bug 88360 e mysql 8796 per un esempio.

Qualche volta può essere il caso che una libreria non sia predisposta ad essere una libreria condivisa, per esempio perché fa un intenso uso di variabili globali. In questo caso la soluzione è cambiare la libreria condivisa in una libreria statica.

Vedere il bug 131460 per un esempio

Codice 7.1: Esempio di messaggio di errore

gcc   -fPIC -DSHARED_OBJECT -c lex.yy.c
gcc  -shared -o html2txt.so lex.yy.o -lfl
usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/../../../../x86_64-pc-linux-gnu/bin/ld:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/../../../../lib64/libfl.a(libyywrap.o):
relocation R_X86_64_32 against `a local symbol' can not be used when making a
shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/../../../../lib64/libfl.a: could not
read symbols: Bad value

[ << ] [ < ] [ Home ] [ > ] [ >> ]


Stampa

Visualizza tutto

Aggiornato il 23 luglio 2006

Oggetto: Questa guida è per gli sviluppatori e utenti interessati e fa vedere come riparare errori relativi a -fPIC

Tom Martin
Manutentore

Simon Stelling
Manutentore

Team Italiano
Traduttore

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.