Les bibliothèques qui existent dans l'elfe d'un binaire DT_RUNPATH ne sont pas choisies?

2

J'ai construit sur mesure gcc-4.7.2dans mon environnement. Le système gcc est gcc-4.3.4.

J'ai corrigé le DT_RUNPATH pour tous les binaires et bibliothèques partagés de mon gcc personnalisé à l'aide depatchelf --set-rpath

Cependant, quand je tourne lddsur mon 4.7.2, cc1il récupère le système à la libstdc++place de celui indiqué par le DT_RUNPATH :

$ ldd /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/4.7.2/cc1
        libcloog-isl.so.1 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libcloog-isl.so.1 (0x00007f072dce8000)
        ...
        libc.so.6 => /lib64/libc.so.6 (0x00007f072bfe0000)
   -->  libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f072bcd5000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f072babe000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f072df0d000)

Comme on peut le voir, DT_RUNPATH spécifie les gcc-4.7.2emplacements des bibliothèques:

$ readelf -a /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/4.7.2/cc1 | grep PATH
 0x000000000000001d (RUNPATH)            Library runpath: \
    [/sdk/x86_64/2.11.1/gcc-4.7.2/lib64: \
     /sdk/x86_64/2.11.1/gcc-4.7.2/lib: \
     /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/lib64: \
     /sdk/x86_64/2.11.1/gcc-4.7.2/lib/gcc/x86_64-suse-linux/4.7.2]

Je sais que cela libstdc++.so.6existe dans la première entrée du DT_RUNPATH :

$ ls -l /sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so*
lrwxrwxrwx .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so -> libstdc++.so.6.0.17
lrwxrwxrwx .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so.6 -> libstdc++.so.6.0.17
-rwxr-x--- .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so.6.0.17
-rwxr-x--- .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so.6.0.17-gdb.py

Je n'ai pas de LD_LIBRARY_PATH défini dans mon environnement:

$ echo $LD_LIBRARY_PATH

$

Si je ne mets LD_LIBRARY_PATH alors il trouve la bibliothèque correcte:

export LD_LIBRARY_PATH=/sdk/x86_64/2.11.1/gcc-4.7.2/lib64: \
    /sdk/x86_64/2.11.1/gcc-4.7.2/lib: \
    /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/lib64: \
    /sdk/x86_64/2.11.1/gcc-4.7.2/lib/gcc/x86_64-suse-linux/4.7.2

$ ldd /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/4.7.2/cc1
        libcloog-isl.so.1 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libcloog-isl.so.1 (0x00007f072dce8000)
        ...
        libc.so.6 => /lib64/libc.so.6 (0x00007f072bfe0000)
   -->  libstdc++.so.6 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so.6 (0x00007fdf4e560000)
        libgcc_s.so.1 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libgcc_s.so.1 (0x00007fdf4e34b000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f072df0d000)
  • Comment se fait-il qu'il ne récupère pas la bibliothèque trouvée dans DT_RUNPATH ?
  • Comment puis-je le forcer à utiliser les gcc-4.7.2bibliothèques sans avoir à utiliser LD_LIBRARY_PATH ?
Steve Lorimer
la source

Réponses:

1

Le problème est que l'un des prérequis ( libppl.so) importe également libstdc++. Ce prérequis a été construit en utilisant le système gcc, et trouve donc/usr/lib64/libstdc++.so.6

$ ldd /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libppl.so
        linux-vdso.so.1 =>  (0x00007fffd10db000)
        libgmpxx.so.4 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmpxx.so.4 (0x00007f4716f92000)
        libgmp.so.10 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmp.so.10 (0x00007f4716d26000)
    --> libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f4716a25000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f47167a0000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f4716441000)
        libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007f471622c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f47174b4000)

Une fois qu'une bibliothèque a été localisée une fois par l'éditeur de liens dynamique, elle ne sera plus recherchée; cet emplacement sera utilisé pour toutes les exigences ultérieures.

J'ai résolu ce problème en reconstruisant les conditions préalables avec le nouveau gcc .

$ ldd /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libppl.so
        linux-vdso.so.1 =>  (0x00007fffd10db000)
        libgmpxx.so.4 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmpxx.so.4 (0x00007f4716f92000)
        libgmp.so.10 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmp.so.10 (0x00007f4716d26000)
    --> libstdc++.so.6 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/../lib64/libstdc++.so.6 (0x00007f4716a25000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f47167a0000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f4716441000)
        libgcc_s.so.1 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/../lib64/libgcc_s.so.1 (0x00007f471622c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f47174b4000)

Je pense que la dernière étape consiste à reconstruire maintenant gcc avec les nouvelles conditions requises pour la construction.

  • créer des conditions préalables avec le système gcc
  • construire un nouveau gcc
  • reconstruire les conditions préalables avec le nouveau gcc
  • reconstruire gcc avec des conditions préalables reconstruites

Si la dernière étape est nécessaire, je ne suis pas sûr.

Steve Lorimer
la source