Pregunta

Al compilar bibliotecas compartidas en gcc, la opción -fPIC compila el código como independiente de la posición. ¿Hay alguna razón (rendimiento o de otro tipo) por la que no compilarías todas las posiciones de código independientemente?

¿Fue útil?

Solución

Agrega una indirección. Con el código de posición independiente, debe cargar la dirección de su función y luego saltar a ella. Normalmente, la dirección de la función ya está presente en la secuencia de instrucciones.

Otros consejos

Sí, hay razones de rendimiento. Algunos accesos están efectivamente bajo otra capa de indirección para obtener la posición absoluta en la memoria.

También existe la GOT (tabla de compensación global) que almacena las compensaciones de las variables globales. Para mí, esto se parece a una tabla de reparación de IAT, que está clasificada como dependiente de la posición por Wikipedia y algunas otras fuentes.

http://en.wikipedia.org/wiki/Position_independent_code

Este artículo explica cómo funciona PIC y lo compara con la alternativa - reubicación del tiempo de carga . Creo que es relevante para tu pregunta.

Además de la respuesta aceptada. Una cosa que perjudica mucho el rendimiento del código PIC es la falta de "direccionamiento relativo de IP". en x86. Con '' direccionamiento relativo de IP '' podría pedir datos que sean X bytes del puntero de instrucción actual. Esto haría que el código PIC sea mucho más simple.

Los saltos y las llamadas, por lo general son relativos a EIP, por lo que realmente no representan un problema. Sin embargo, acceder a los datos requerirá un pequeño truco adicional. A veces, un registro se reservará temporalmente como un "puntero base". a los datos que requiere el código. Por ejemplo, una técnica común es abusar de la forma en que funcionan las llamadas en x86:

call label_1
.dd 0xdeadbeef
.dd 0xfeedf00d
.dd 0x11223344
label_1:
pop ebp            ; now ebp holds the address of the first dataword
                   ; this works because the call pushes the **next**
                   ; instructions address
                   ; real code follows
mov eax, [ebp + 4] ; for example i'm accessing the '0xfeedf00d' in a PIC way

Esta y otras técnicas agregan una capa de indirección a los accesos de datos. Por ejemplo, la GOT (tabla de desplazamiento global) utilizada por los compiladores gcc.

x86-64 agregó un "RIP relativo" modo que simplifica mucho las cosas .

Debido a que la implementación de código completamente independiente de la posición agrega una restricción al generador de código que puede evitar el uso de operaciones más rápidas, o agrega pasos adicionales para preservar esa restricción.

Esto podría ser una compensación aceptable para obtener multiprocesamiento sin un sistema de memoria virtual, donde confía en los procesos para no invadir la memoria del otro y puede que necesite cargar una aplicación particular en cualquier dirección base.

En muchos sistemas modernos, las compensaciones de rendimiento son diferentes, y un cargador de reubicación suele ser menos costoso (cuesta cualquier tiempo que se cargue el código por primera vez) que lo mejor que puede hacer un optimizador si tiene un reinado libre. Además, la disponibilidad de espacios de direcciones virtuales oculta la mayor parte de la motivación para la independencia de posición en primer lugar.

Además, el hardware de memoria virtual en la mayoría de los procesadores modernos (utilizado por la mayoría de los sistemas operativos modernos) significa que un montón de código (todas las aplicaciones de espacio de usuario, salvo el uso peculiar de mmap o similar) no necesita ser independiente de la posición. Cada programa tiene su propio espacio de direcciones que cree que comienza en cero.

código independiente de la posición tiene una sobrecarga de rendimiento en la mayoría de la arquitectura, porque requiere un registro adicional.

Entonces, esto es para fines de rendimiento.

Hoy en día, el sistema operativo y el compilador por defecto hacen que todo el código sea independiente de la posición. Intente compilar sin el indicador -fPIC, el código se compilará bien pero solo recibirá una advertencia. Las ventanas de OS usan una técnica llamada mapeo de memoria para lograr esto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top