2012-04-03 10 views
6

Estoy desarrollando una plataforma integrada y me está resultando difícil encontrar la forma de vincular dinámicamente las bibliotecas compartidas. Estoy usando el formato de archivo bFLT y no tengo control sobre dónde se cargan las bibliotecas ejecutables y compartidas.Código de posición independiente, bibliotecas compartidas y carillas de código: hacer que funcionen juntas

Mi cargador carga correctamente la biblioteca compartida y el ejecutable en la memoria y modifica el GOT del ejecutable en tiempo de ejecución para vincularlo a la biblioteca compartida.

Puedo tomar con éxito la dirección de la función y sé que es correcta desde el desmontaje del código en esa ubicación. Sin embargo, si trato de llamar a la función, todo falla.

Resulta que GCC agrega un 'código de chapa' cuando llama a funciones de biblioteca compartida y toma un desvío cuando se llama a la función y no se bifurca a la dirección de la función. La dirección a la que se ramifica el código chapeado no se reubica correctamente porque no aparece en la lista de reubicaciones en el binario ejecutable.

El desmontaje de la chapa se ve así:

000008d0 <__library_call_veneer>: 
8d0: e51ff004 ldr pc, [pc, #-4] ; 8d4 <__library_call_veneer+0x4> 
8d4: 03000320 .word 0x03000320 ; This address isn't correctly relocated! 

Si tomo la dirección de la función y lo puse en un puntero de función (por lo tanto, sin pasar por el 'código de chapa') y lo llamo, el la biblioteca compartida funciona perfectamente.

Así, por ejemplo:

#define DIRECT_LIB_CALL(x, args...) do { \ 
     typeof(x) * volatile tmp = x; \ 
     tmp(#args); \ 
    } while (0) 

DIRECT_LIB_CALL(library_call); /* works */ 
library_call(); /* crashes */ 

¿Hay una manera de bien, diga GCC para no producir una chapa de código y rama directamente a la dirección ubicada en el GOT o de alguna manera hacer que la dirección que las ramas de código de chapa aparecer en la lista de reubicaciones para realizar?

+0

¿Está declarando los prototipos de la biblioteca utilizando C externo? –

+0

Estoy compilando en C, por lo que la "C" externa sería redundante, ¿no? – tangrs

+1

Las carillas son más o menos necesarias en los sistemas ARM, por lo que la chapa es lo correcto. Sin embargo, no actualizar la dirección no es ... Mirando su formato de archivo, http://docs.blackfin.uclinux.org/doku.php?id=toolchain:executable_file_formats y http://docs.blackfin.uclinux.org /doku.php?id=toolchain:creating_libraries aparece. Parece que puede tener una identificación de biblioteca compartida en conflicto, o puede querer modificar sus marcadores de enlace (como se explica allí). Lo siento no puedo ayudar mucho más –

Respuesta

2

Encontré una solución a este problema. No es el mejor método ni el más limpio, pero cumple su función en mi caso.

Aproveché la opción --wrap en mi enlazador que redirige los símbolos a __wrap_symbol. Con esto, configuré un script awk que genera automáticamente archivos ASM que cargan una dirección reubicada correctamente en la pc. Cualquier llamada a la biblioteca se redirigiría a este código. Básicamente lo que hice fue hacer mis propias carillas de código. Como la chapa del código generado no se estaba haciendo referencia, simplemente se optimizó.

Además, tuve que colocar mis chapas en la sección .data ya que nada en la sección .text no se reubicó correctamente. Dado que, la plataforma en la que estoy trabajando no diferencia mucho entre código y datos, esta solución hacky funciona.

Here's a link al proyecto en el que estoy trabajando, donde puede consultar los detalles.

+0

Buen trabajo. Presentaría una solicitud de función a los autores del SDK de homebrew para que agreguen el soporte de chapa adecuado ... es algo bastante básico para las plataformas ARM debido a las limitaciones de la bifurcación ... –

Cuestiones relacionadas