2010-11-19 14 views
11

Tengo un sistema "fsimage.so" que requiere mkdirp, que simplemente vive en libgen.so. Pero fsimage.so no sabe esto. Por ejemplo:¿Puedo agregar una referencia de biblioteca al objeto compartido existente?

# ldd /usr/lib/python2.4/vendor-packages/fsimage.so 
    libfsimage.so.1.0 =>  /usr/lib/libfsimage.so.1.0 
    libxml2.so.2 => /lib/libxml2.so.2 
    libgcc_s.so.1 =>   /usr/sfw/lib/libgcc_s.so.1 
    libpthread.so.1 =>  /lib/libpthread.so.1 
    libz.so.1 =>  /lib/libz.so.1 
    libm.so.2 =>  /lib/libm.so.2 
    libsocket.so.1 =>  /lib/libsocket.so.1 
    libnsl.so.1 => /lib/libnsl.so.1 
    libc.so.1 =>  /lib/libc.so.1 
    libmp.so.2 => /lib/libmp.so.2 
    libmd.so.1 => /lib/libmd.so.1 

# ./test 
Traceback (most recent call last): 
    File "./test", line 26, in ? 
    import fsimage 
ImportError: ld.so.1: isapython2.4: fatal: relocation error: file /usr/lib/python2.4/vendor-packages/fsimage.so: symbol mkdirp: referenced symbol not found 

# LD_PRELOAD=/usr/lib/libgen.so ./test 
Usage: ./test 

Naturalmente, si tuviera las fuentes, etc, podría simplemente enlazar de nuevo, y añadir "-lgen", y agregará libgen.so como dependencia.

Pero como un ejercicio de hackeo, digamos que no tengo ninguna fuente, y simplemente quería agregar que fsimage.so también necesita cargar libgen.so. Usando elfedit/objcopy, etc., ¿no es esto posible? Supongo que no puedo usar "ld" para usar .so como entrada, y escribir un .so nuevo con una biblioteca adicional.

# elfdump /usr/lib/python2.4/vendor-packages/fsimage.so|grep NEEDED 
    [0] NEEDED   0x5187    libfsimage.so.1.0 
    [1] NEEDED   0x5152    libxml2.so.2 
    [2] NEEDED   0x5171    libgcc_s.so.1 

Primer intento de stackoverflow, ir fácil en mí :)

Respuesta

10

Gracias "Ruso empleado", me diste la información necesaria para buscar más profundamente. Solaris ya se envía con "elfedit", por lo que si otras personas quieren saber, estas son las instrucciones

# elfedit libfsimage.so.1.0.0 libfsimage.so.1.0.0-new 
> dyn:value DT_NEEDED 
index tag    value 
    [0] NEEDED   0x4f81    libpthread.so.1 
    [1] NEEDED   0x4fac    libxml2.so.2 
    [2] NEEDED   0x4fc2    libgcc_s.so.1 
> dyn:value -add -s DT_NEEDED libscf.so 
index tag    value 
    [35] NEEDED   0x500d    libscf.so 
> dyn:value DT_NEEDED 
index tag    value 
    [0] NEEDED   0x4f81    libpthread.so.1 
    [1] NEEDED   0x4fac    libxml2.so.2 
    [2] NEEDED   0x4fc2    libgcc_s.so.1 
    [35] NEEDED   0x500d    libscf.so 
> :write 
> :quit 

# ldd libfsimage.so.1.0.0-new 
    libpthread.so.1 =>  /lib/libpthread.so.1 
    libxml2.so.2 => /lib/libxml2.so.2 
    libgcc_s.so.1 =>   /usr/sfw/lib/libgcc_s.so.1 
    libscf.so =>  /lib/libscf.so 
    libz.so.1 =>  /lib/libz.so.1 
    libm.so.2 =>  /lib/libm.so.2 
    libsocket.so.1 =>  /lib/libsocket.so.1 
    libnsl.so.1 => /lib/libnsl.so.1 
    libc.so.1 =>  /lib/libc.so.1 
    libuutil.so.1 =>   /lib/libuutil.so.1 
    libgen.so.1 => /lib/libgen.so.1 
    libnvpair.so.1 =>  /lib/libnvpair.so.1 
    libsmbios.so.1 =>  /usr/lib/libsmbios.so.1 
    libmp.so.2 => /lib/libmp.so.2 
    libmd.so.1 => /lib/libmd.so.1 
+0

Ejecuto elfedit con el, por lo que quiero editar como primer arg y un nuevo nombre para el segundo y no pasa nada. La ayuda se muestra. Estoy en Linux sin embargo. – kaneda

7
No

fácilmente.

mayoría UNIX sistemas (AIX es una excepción notable) consideran *.so un producto "final" enlace, y no es adecuada como una entrada para cualquier enlace adicional.

Para agregar una nueva etiqueta DT_NEEDED a la sección dinámica de fsimage.so, deberá volver a escribir su sección .dynamic. Eliminar una entrada de .dynamic es relativamente fácil: puede simplemente "deslizar" las otras entradas y reemplazar la última entrada con DT_NULL.

Por otro lado, la adición de una nueva entrada que requiere anexar toda una sección nueva .dynamic al archivo, y luego actualizar todos los punteros (offsets) dentro fsimage.so para que apunte a la nueva sección. Esto requiere una comprensión "profunda" del formato ELF.

Existen herramientas existentes para hacer esto, p. rpath pero he tenido un éxito desigual con él.

+0

sospeché como tal. Sé que Solaris dejará 512 bytes de espacio en ELF, por lo que puede agregar fácilmente nuevas secciones, como texto, etc. Pero no (directa/fácilmente) la expansión de secciones de DT_NEEDED. Aún aprendizaje interesante. Por ahora, podría recompilar mi python y agregar las bibliotecas que quería, pero ingresé en un lío separado de 32 bits frente a 64 bits. Suspiro :) – lundman

1

Puede utilizar PatchELF. Lanzamiento 0.9 es a cabo desde el 29 de Feb de 2016 y le permite:

  • Cambiar el cargador dinámico ("intérprete ELF") de ejecutables
  • Cambiar el rPath de ejecutables y bibliotecas
  • Reduce la rPath de ejecutables y bibliotecas
  • Retire declarada dependencias de las bibliotecas dinámicas (DT_NEEDED entradas)
  • Añadir una dependencia declarada en una librería dinámica (DT_NEEDED)
  • Reemplazar una dependencia declarada en una librería dinámica con otro (DT_NEEDED)
  • Cambio SONAME de una biblioteca dinámica

En su caso:

$ patchelf --add-needed /usr/lib/libgen.so /usr/lib/python2.4/vendor-packages/fsimage.so 
+1

La versión estable más reciente [v0.8] [1] solo tiene '--recuperar-necesita BIBLIOTECA' y no agrega, probablemente por la razón indicada por lundman en la versión aceptada. Sin embargo, la [versión de desarrollo en github] [2] también tiene la opción --add-library, así que este podría ser el camino a seguir [1]: https: //github.com/NixOS/patchelf/blob/0.8 /src/patchelf.cc [2]: https: //github.com/NixOS/patchelf/blob/master/src/patchelf.cc – Davide

Cuestiones relacionadas