2010-07-29 22 views
6

Tengo una biblioteca compartida de Linux, foo.so, que se carga desde un ejecutable usando dlopen("foo.so", RTLD_NOW | RTLD_LOCAL). Desde foo.so, me gustaría ampliar otra biblioteca, bar.so, que hace referencia a los símbolos definidos en foo.so, pero el vinculador no puede encontrarlos. No puedo cambiar RTLD_LOCAL a RTLD_GLOBAL, porque no tengo el origen del ejecutable que realiza la carga. Pensé que -Wl,--export-dynamic al vincular foo.so podría ayudar, pero no anula el indicador local para dlopen. La nueva característica de visibilidad de atributos de GCC tampoco parece ofrecer la respuesta.dlopen con dos bibliotecas compartidas, símbolos de exportación

¿Hay alguna manera en que pueda indicarle al enlazador que resuelva referencias a símbolos indefinidos en bar.so a esas definiciones en foo.so, sin vincular la barra con -lfoo o similaridad moviendo los símbolos a una tercera biblioteca y vinculando ambos foo y barra contra eso? Lo único que se me ocurre es abrir foo.so con RTLD_GLOBAL desde dentro de foo.so, luego dlopen bar.so, pero eso me parece un poco desordenado. Gracias.

Respuesta

4

Enlace foo.so contra bar.so.

Cuando se ejecute también el archivo ejecutable dlopen() s foo.so, bar.so.

Como alternativa, parche binario el ejecutable para agregar RTLD_GLOBAL a las banderas para la llamada dlopen(). El código será algo como

movl $2, 4(%esp)  # $2 == RTLD_NOW; RTLD_LOCAL is 0 
    movl $0xNNNNN, (%esp) # $0xNNNNN == &"foo.so" 
    call dlopen 

Patch a movl $0x102, 4(%esp) lugar (RTLD_GLOBAL == 0x100), y listo.

EDIT:
Si conoce el nombre de bar.so, entonces se puede vincular foo.so contra un "trozo" bar.so. No importa que no tenga "real" bar.so; todo lo que importa es que foo.so tiene una dependencia de él. En el tiempo de ejecución esa dependencia causará que bar.so se cargue siempre que se cargue foo.so.

+0

Gracias por la respuesta. No puedo vincular foo.so con bar.so porque bar.so será un plugin proporcionado por el usuario. Tampoco puedo parchar el ejecutable porque normalmente será propiedad de root en el sistema del cliente y no estoy seguro de que el parche sea demasiado bueno con ellos, complica bastante el proceso de instalación. También rompería otras bibliotecas que el ejecutivo está abriendo, algunas de ellas dependen de RTLD_LOCAL. Creo que tendré que irme con el dlopen foo.so de sí mismo, que parece funcionar. Aclamaciones –

Cuestiones relacionadas