gcc shared-libraries 32bit-64bit dynamic-linking fpic

gcc - ¿Por qué es absolutamente necesario fPIC en 64 y no en plataformas de 32 bits?



shared-libraries 32bit-64bit (3)

Pero no encuentro esto bastante adecuado. Si las reubicaciones estropean el concepto de bibliotecas compartidas, ¿por qué se puede hacer en plataformas de 32 bits?

Se puede hacer, simplemente no es particularmente eficiente ... calcular las reubicaciones tiene costos de tiempo de ejecución, los ejecutables reubicados requieren memoria adicional y el mecanismo introduce mucha complejidad en el cargador ejecutable. Además, las distribuciones de Linux realmente quieren animar a que se compile todo el código con -fPIC porque cambiar la dirección base de un ejecutable es una estrategia de mitigación que dificulta la redacción de exploits para vulnerabilidades de seguridad.

También vale la pena mencionar que -fPIC no es generalmente un costo de rendimiento significativo, especialmente si usa -fvisibility = hidden o equivalente.

¿Por qué no todos los campos aumentaron de tamaño para adaptarse?

El "campo" en cuestión es el campo inmediato de los modos de direccionamiento x86-64, que no está bajo el control de los desarrolladores de ELF.

Hace poco recibí un

... la reubicación R_X86_64_32 contra `un símbolo local ''no se puede usar al crear un objeto compartido; recompilar con -fPIC

error al intentar compilar un programa como una biblioteca compartida.

Ahora, la solución a esto no es demasiado difícil (recompile todas las dependencias con -fPIC), pero después de algunas investigaciones, resulta que este problema solo está presente en las plataformas x86-64. En 32 bits, cualquier código dependiente de la posición aún puede ser reubicado por el cargador dinámico.

La mejor answer que pude encontrar es:

x86 admite las reubicaciones de .text (que es lo que sucede cuando tienes un código dependiente de la posición). Este soporte tiene un costo, es decir, que cada página que contiene tal reubicación se vuelve básicamente no compartida, incluso si se encuentra en una biblioteca compartida, lo que arruina el concepto mismo de las bibliotecas compartidas. Por lo tanto, decidimos rechazar esto en amd64 (además, crea problemas si el valor necesita más de 32 bits, porque todos los relocs .text solo tienen el tamaño ''word32'')

Pero no encuentro esto bastante adecuado. Si las reubicaciones estropean el concepto de bibliotecas compartidas, ¿por qué se puede hacer en plataformas de 32 bits? Además, si hubo cambios que debían realizarse en el formato ELF para admitir 64 bits, ¿por qué no se aumentó el tamaño de todos los campos para adaptarse?

Este puede ser un punto menor, pero está motivado por el hecho de que a) el código en cuestión es un código científico y sería bueno no tener que tener un impacto en el rendimiento yb) esta información no fue imposible de encontrar en el sitio. ¡primer lugar!

[Editar: ''La respuesta''

La answer @awoodlands es probablemente la mejor ''respuesta literal'', @servn added buena información.

En una búsqueda para encontrar más información sobre los diferentes tipos de reubicaciones, encontré this y, en última instancia, una referencia ABI x86_64 (consulte la página 68)]



Según tengo entendido, el problema es que x86-64 parece introducir una forma nueva y más rápida de referenciar los datos en relación con el puntero de instrucción, que no existía para x86-32.

Este artículo tiene un buen análisis en profundidad de él, y ofrece el siguiente resumen ejecutivo:

La capacidad de x86-64 para usar la compensación relativa del puntero de instrucción para las direcciones de datos es una buena optimización, pero en una situación de biblioteca compartida las suposiciones sobre la ubicación relativa de los datos no son válidas y no se pueden usar. En este caso, el acceso a los datos globales (es decir, cualquier cosa que pueda modificarse) debe pasar por una capa de abstracción, es decir, la tabla de compensación global.

Es decir, el direccionamiento -fPIC agrega una capa adicional de abstracción al direccionamiento, para hacer que lo que antes era posible (y una característica deseable) en el estilo de direccionamiento habitual aún funcione con la arquitectura más nueva.