¿Qué significa -fPIC al crear una biblioteca compartida?


109

Sé que la -fPICopción " " tiene algo que ver con la resolución de direcciones y la independencia entre módulos individuales, pero no estoy seguro de lo que realmente significa. ¿Puedes explicar?


1
También en caso de que quiera saber con más detalle, hay un gran artículo aquí ( akkadia.org/drepper/dsohowto.pdf )
MJ

Respuestas:


61

PIC significa Código Independiente de Posición

y citar man gcc:

Si es compatible con la máquina de destino, emita un código independiente de la posición, adecuado para la vinculación dinámica y evitando cualquier límite en el tamaño de la tabla de compensación global. Esta opción marca la diferencia en m68k, PowerPC y SPARC. El código independiente de la posición requiere un soporte especial y, por lo tanto, solo funciona en determinadas máquinas.

utilícelo cuando cree objetos compartidos (* .so) en las arquitecturas mencionadas.


1
f no significa nada, es solo parte del nombre de la opción.
Zifre

17
Existe una diferencia entre fpic y fPIC. Ambos hacen lo mismo, pero fpic usa un desplazamiento relativo más corto cuando está disponible. Por lo tanto, compilar con fpic puede producir archivos más pequeños. Desafortunadamente, no siempre funciona como se esperaba, así que use fPIC. Además, tenga en cuenta que no todos los procesadores admiten las compensaciones más cortas, por lo que es posible que no suponga una diferencia.
Martin York

2
La 'f' es una resaca de la forma en que gcc manejó los argumentos de la línea de comandos (esto fue hace un par de años y han cambiado esta parte del código que no he mirado recientemente). Pero en ese momento solo se permitían ciertas letras o combinaciones bajo diferentes condiciones (había un lenguaje muy complejo para definir argumentos de línea de comando) como resultado, la 'f' se usó para facilitar la definición como argumento de línea de comando.
Martin York

2
¿Qué pasará si uno construye un * .so sin fPIC?
Isa A

2
@IsaA Hoy estaba compilando una función c-api mysql desde la fuente y no se /usr/bin/ld: /tmp/cc7hXILq.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPICcompilaba, así que agregué fPIC y lo construí.
chiliNUT

32

El fes el prefijo gcc para las opciones de que "el control de las convenciones de interfaz utilizados en la generación de código"

Las PICgradas para "Código Independiente Posición", que es una especialización de la fpicde m68k y SPARC.

Editar: después de leer la página 11 del documento al que hace referencia 0x6adb015 , y el comentario de coryan, hice algunos cambios:

Esta opción solo tiene sentido para bibliotecas compartidas y le está diciendo al sistema operativo que está usando una Tabla de compensación global, GOT. Esto significa que todas las referencias de su dirección son relativas al GOT, y el código se puede compartir en múltiples procesos.

De lo contrario, sin esta opción, el cargador tendría que modificar todas las compensaciones por sí mismo.

No hace falta decir que casi siempre usamos -fpic / PIC.


1
Pensé que el sistema operativo era libre de cargar la biblioteca en cualquier dirección virtual, pero sin pic / PIC, el cargador tiene que modificar el código y ajustar todos los saltos absolutos + indirecciones a las ubicaciones reales de las rutinas / bibliotecas. Con pic / PIC, el código no se modifica y, por lo tanto, realmente se comparte entre múltiples procesos.
coryan

Múltiples procesos son en gran parte coincidentes: el punto clave es que el código se puede cargar en cualquier dirección virtual con un mínimo absoluto de correcciones de direcciones.
Jonathan Leffler

16

man gcc dice:

-fpic
  Genere un código independiente de la posición (PIC) adecuado para su uso en un
  biblioteca, si es compatible con la máquina de destino. Dicho código accede a todos
  direcciones constantes a través de una tabla de compensación global (GOT). La dinámica
  Loader resuelve las entradas GOT cuando se inicia el programa (la dinámica
  loader no es parte de GCC; es parte del sistema operativo). Si
  el tamaño GOT para el ejecutable vinculado excede un específico de la máquina
  tamaño máximo, recibe un mensaje de error del vinculador que indica
  que -fpic no funciona; en ese caso, vuelva a compilar con -fPIC en su lugar.
  (Estos máximos son 8k en SPARC y 32k en m68k y RS / 6000.
  El 386 no tiene tal límite).

  El código independiente de la posición requiere un soporte especial y, por lo tanto,
  funciona solo en ciertas máquinas. Para el 386, GCC admite PIC para
  System V pero no para el Sun 386i. Código generado para el
  IBM RS / 6000 siempre es independiente de la posición.

-fPIC
  Si es compatible con la máquina de destino, emita un código independiente de la posición,
  adecuado para enlaces dinámicos y evitar cualquier límite en el tamaño de
  la tabla de compensación global. Esta opción marca la diferencia en el m68k
  y el SPARC.

  El código independiente de la posición requiere un soporte especial y, por lo tanto,
  funciona solo en ciertas máquinas.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.