[ << ]
[ < ]
[ Inicio ]
[ > ]
[ >> ]
3. Cómo corregir los errores -fPIC
Contenido:
3.a. El problema
A veces gcc termina con un mensaje de error como el siguiente:
Listado de Código 1.1: Un típico mensaje de error de 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
|
Hay muchas causas para este tipo de error. Esta guía las explica todas
y muestra cómo solucionarlos.
3.b. ¿Qué es PIC?
PIC es la abreviación de Código Independiente de la
Posición. Lo siguiente es un extracto
del artículo
de la Wikipedia (en inglés) acerca del código independiente de
la posición:
"En informática, el código independiente de la posición (PIC) o
ejecutable independiente de la posición (PIE) es código objeto que se
puede ejecutar en diferentes localizaciones de la memoria. Las
librerías compartidas suelen usar PIC, así el código de la misma
librería puede ser mapeado a una localización diferente por cada
aplicación (usando el sistema de memoria virtual) donde no se solapará
con la aplicación o con otras librerías compartidas. También se usaba
PIC en viejos sistemas informáticos que carecían de MMU, así el
sistema operativo mantenía las aplicaciones separadas unas de
otras.
El código independiente de la posición puede ser
copiado a cualquier localización de memoria sin modificarlo y
ejecutarlo, a diferencia del código relocalizable, que necesita un
procesamiento especial por un editor de enlaces o un cargador de
programas para prepararlo para la ejecución en una localización
determinada. Generalmente, se debe escribir o compilar el código de
forma especial para que sea independiente de la
posición. Instrucciones que hacen referencia a direcciones de memoria
específicas, como por ejemplo ramas absolutas, se deben cambiar por
instrucciones equivalentes relativas. La redirección extra puede
causar que el código PIC sea menos eficiente aunque los procesadores
modernos están diseñados para aliviar esto."
—Enciclopedia Wikipedia
En ciertas arquitecturas (AMD64 entre ellas), las bibliotecas
compartidas
deben estar habilitadas para PIC.
3.c. ¿Qué son las "relocalizaciones"?
Otra vez, de la Wikipedia:
"En informática, el término relocalización hace referencia a
reemplazar referencias simbólicas o nombres de librerías por las
direcciones reales de memoria antes de ejecutar un
programa. Normalmente esta tarea la lleva a cabo el enlazador durante
la compilación aunque también la puede hacer un cargador durante la
ejecución. Los compiladores y ensambladores normalmente generan
ejecutables cuya dirección inicial (la más baja) es cero. Antes de la
ejecución del código objeto, se deben ajustar estas direcciones para
que apunten a la dirección correcta de ejecución."
—Enciclopedia Wikipedia
Ahora que hemos definido estos términos, podemos echar un vistazo a
los distintos escenarios donde se producen estos errores:
3.d. Caso 1: Compilador roto
Se sabe que GCC 3.4 tiene rota la implementación del indicador
-fvisibility-inlines-hidden. El uso de este indicador es por
tanto altamente desaconsejado, los errores reportados se marcan
normalmente como RESOLVED INVALID. En la página
error 108872 encontrará un
ejemplo de un mensaje de error típico causado por este indicador.
3.e. Caso 2: Soporte `-fPIC' roto en pruebas de configure
Muchas herramientas configure prueban si el compilador soporta
el indicador -fPIC o no. Para hacerlo, compilan un pequeño
programa con el indicador -fPIC y verifican
el stderr. Si el compilador muestra *cualquier* aviso, asume
que el indicador -fPIC no está soportado por el compilador y
aborta. Por desgracia, si el usuario especifica un indicador
inexistente (p.e. indicadores exclusivos de C++ en las CFLAGS o
indicadores introducidos en versiones recientes de GCC pero no en las
viejas), GCC también muestra un aviso resultando en un error.
Para evitar este tipo de errores, los perfiles AMD64 usan un bashrc
para filtrar los indicadores no validos en C[XX]FLAGS.
Consulte, por ejemplo,
el error 122208.
3.f. Caso 3: Ausencia de indicador `-fPIC' en el software a construir
Éste es el caso más común. Es un error en el sistema de construcción y
debe ser reparado en el ebuild, preferentemente con un parche enviado
a los desarrolladores. Asumiendo que el mensaje de error sea como
éste:
Listado de Código 6.1: Un mensaje de error de muestra |
.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
|
Esto significa que el archivo assert.o no fue compilado
con el indicador -fPIC como debería. Cuando solucione este tipo
de error, asegúrese de que sólo los objetos que vayan a ser usados en
librerías compartidas sean compilados con el indicador -fPIC.
En este caso, añadiendo -fPIC a las C[XX]FLAGS globales
se resuelve este problema, aunque no se aconseja esta práctica ya que
los ejecutables también terminan estando habilitados para PIC.
Nota:
Añadir el indicador -fPIC al enlazador o a las LDFLAGS
no sirve.
|
3.g. Caso 4: Enlazando dinámicamente contra archivos estáticos
A veces un paquete trata de construir librerías compartidas usando
archivos construidos estáticamente que no están habilitados para
PIC. Hay dos razones principales por lo que esto ocurre:
A menudo es el resultado de mezclar USE=static
y USE=-static. Si un paquete de librería puede ser construido
estáticamente mediante USE=static, normalmente no se crea un
archivo .so sino que sólo se crea un
archivo .a. Sin embargo, cuando se le pasa a GCC la
opción -l para enlazar una librería (estática o dinámica) si no
encuentra una librería compartida usa el archivo estático. En este
caso, la mejor solución es construir la librería estática usando
también el indicador
-fPIC.
Aviso:
Construya solamente archivos estáticos con -fPIC en AMD64. En
otras arquitecturas esto es innecesario y puede afectar al rendimiento
durante la ejecución.
|
Vea el error 88360 y
el error mysql
8796 como ejemplos de este error.
A veces también se da el caso de que una librería no está pensada para
ser una librería compartida, p.e. porque hace un uso intensivo de
variables globales. En este caso la solución es convertir la librería
compartida que se va a construir en estática.
Vea, por ejemplo, el error
131460.
Listado de Código 7.1: Un mensaje de error de muestra |
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
|
[ << ]
[ < ]
[ Inicio ]
[ > ]
[ >> ]
El contenido de este documento, a no ser que se especifique
expresamente, está registrado bajo los términos de la licencia
CC-BY-SA-2.5. Se aplican las
Pautas de
Utilización del logotipo y nombre de Gentoo.
|