Gentoo Logo

[ << ] [ < ] [ 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 ] [ > ] [ >> ]


Imprimir

Ver completo

Página actualizada 23 de julio, 2006

Sumario: Esta guía esta dirigida a los desarrolladores y usuarios interesados en solucionar los errores -fPIC.

Tom Martin
Responsable de mantenimiento

Simon Stelling
Responsable de mantenimiento

Jaime Gascón Romero
Traductor

Donate to support our development efforts.

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