2010-11-19 35 views
11

J'ai un système "fsimage.so" qui nécessite mkdirp, qui réside justement dans libgen.so. Mais fsimage.so ne le sait pas. Par exemple:Puis-je ajouter une référence de bibliothèque à un objet partagé existant?

# 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 

Naturellement, si j'avais les sources etc, je pourrais simplement lier à nouveau, et ajouter « -lgen », et il va ajouter libgen.so comme une dépendance.

Mais comme un exercice de hackery, disons que je n'ai aucune source, et je voulais simplement ajouter que fsimage.so doit également charger libgen.so. En utilisant elfedit/objcopy etc, n'est-ce pas possible? Je ne suppose pas que je peux utiliser "ld" pour utiliser .so comme entrée, et écrire un nouveau .so avec une bibliothèque supplémentaire?

# 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 

Première tentative de stackoverflow, allez-y doucement sur moi :)

Répondre

10

Merci "Employé russe", vous m'a donné l'information nécessaire pour chercher plus profondément. Solaris déjà livré avec « elfedit », donc si d'autres veut savoir, ce sont les instructions

# 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

Je cours elfedit avec le donc je veux éditer en tant que premier argument et un nouveau nom pour le second et rien ne se passe. L'aide est montrée. Je suis sur Linux cependant. – kaneda

7

pas facilement.

La plupart des systèmes (AIX est une exception notable) considèrent *.so un produit de liaison «final» et ne convient pas comme entrée pour toute autre liaison. Pour ajouter une nouvelle étiquette DT_NEEDED à la section dynamique de fsimage.so, vous devez réécrire sa section .dynamic. Suppression d'une entrée de .dynamic est relativement facile - vous pouvez simplement "glisser" les autres entrées vers le haut, et remplacer la dernière entrée par DT_NULL. D'autre part, pour ajouter une nouvelle entrée, vous devez ajouter une nouvelle section .dynamic au fichier, puis mettre à jour tous les pointeurs (offsets) au sein de fsimage.so pour pointer vers la nouvelle section. Cela nécessite une compréhension «profonde» du format ELF.

Il existe des outils existants pour ce faire, par ex. rpath mais j'ai eu un succès mitigé.

+0

Je me doutais bien en tant que tel. Je sais que Solaris va laisser 512 octets d'espace dans ELF, de sorte que vous pouvez facilement ajouter de nouvelles sections, comme du texte, etc. Mais pas (directement/facilement) l'expansion des sections DT_NEEDED. Encore un apprentissage intéressant. Pour l'instant, je pourrais recompiler mon python et ajouter les bibliothèques que je voulais, mais entré dans un désordre séparé de 32 bits contre 64 bits. Soupir :) – lundman

1

Vous pouvez utiliser PatchELF. Version 09 est sorti depuis le 29 février 2016 et vous permet de:

  • Changer le chargeur dynamique ("interpréteur ELF") de executables
  • Modifier la RPATH executables et bibliothèques
  • Réduire la RPATH executables et les bibliothèques
  • Supprimer les dépendances déclarées sur les bibliothèques dynamiques (DT_NEEDED entrées)
  • Ajouter une dépendance déclarée sur une bibliothèque dynamique (DT_NEEDED)
  • Remplacer une dépendance déclarée sur une bibliothèque dynamique avec un autre (DT_NEEDED)
  • Changement SONAME d'une bibliothèque dynamique

Dans votre cas:

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

La version stable la plus récente [v0.8] [1] a seulement LIBRARY '--remove-needed 'et ne pas ajouter, probablement pour la raison indiquée par lundman dans la version acceptée. Cependant, la [version de développement dans github] [2] a aussi l'option --add-library, donc cela pourrait être le chemin à parcourir [1]: https: //github.com/NixOS/patchelf/blob/0.8 /src/patchelf.cc [2]: https: //github.com/NixOS/patchelf/blob/master/src/patchelf.cc – Davide