Considérez les dépendances d'objets partagés de /bin/bash
, qui inclut /lib64/ld-linux-x86-64.so.2
(éditeur de liens/chargeur dynamique):
ldd /bin/bash
linux-vdso.so.1 (0x00007fffd0887000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f57a04e3000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f57a04de000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f57a031d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f57a0652000)
Inspection /lib64/ld-linux-x86-64.so.2
montre qu'il s'agit d'un lien symbolique vers /lib/x86_64-linux-gnu/ld-2.28.so
:
ls -la /lib64/ld-linux-x86-64.so.2
lrwxrwxrwx 1 root root 32 May 1 19:24 /lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.28.so
De plus, file
signale /lib/x86_64-linux-gnu/ld-2.28.so
à lui-même être lié dynamiquement:
file -L /lib64/ld-linux-x86-64.so.2
/lib64/ld-linux-x86-64.so.2: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped
J'aimerais savoir:
/lib64/ld-linux-x86-64.so.2
) lui-même lié dynamiquement? Se lie-t-il au moment de l'exécution?/lib/x86_64-linux-gnu/ld-2.28.so
est documenté pour gérer les binaires a.out (man ld.so
), mais /bin/bash
est un exécutable ELF?Le programme ld.so gère les binaires a.out, un format utilisé il y a longtemps; ld-linux.so * (/lib/ld-linux.so.1 pour libc5, /lib/ld-linux.so.2 pour glibc2) gère ELF, que tout le monde utilise depuis des années.
Oui, il se lie lorsqu'il s'initialise. Techniquement, l'éditeur de liens dynamique n'a pas besoin de résolution d'objet et de relocalisation pour lui-même, car il est entièrement résolu tel quel, mais il définit des symboles et il doit en prendre soin lors de la résolution du binaire qu'il est en train d'interpréter, et ces symboles sont mis à jour pour pointer vers leurs implémentations dans les bibliothèques chargées. En particulier, cela affecte malloc
- l'éditeur de liens a une version minimale intégrée, avec le symbole correspondant, mais qui est remplacée par la version de la bibliothèque C une fois qu'elle est chargée et déplacée (ou même par une version interposée s'il y a un), en veillant à ce que cela ne se produise pas à un point où il pourrait briser l'éditeur de liens.
Les détails sanglants sont dans rtld.c
, dans le dl_main
une fonction.
Notez cependant que ld.so
n'a pas de dépendances externes. Vous pouvez voir les symboles impliqués dans nm -D
; aucun d'eux n'est indéfini.
La page de manuel se réfère uniquement aux entrées directement sous /lib
, c'est-à-dire /lib/ld.so
(l'éditeur de liens dynamique libc 5, qui prend en charge a.out
) et /lib*/ld-linux*.so*
(l'éditeur de liens dynamique libc 6, qui prend en charge ELF). La page de manuel est très spécifique et ld.so
n'est pas ld-2.28.so
.
L'éditeur de liens dynamique que l'on trouve sur la grande majorité des systèmes actuels n'inclut pas a.out
soutien.
file
et ldd
rapportent des choses différentes pour l'éditeur de liens dynamiques car ils ont des définitions différentes de ce qui constitue un binaire lié statiquement. Pour ldd
, un binaire est lié statiquement s'il n'a pas de DT_NEEDED
symboles, c'est-à-dire pas de symboles non définis. Pour file
, un binaire ELF est lié statiquement s'il n'a pas de PT_DYNAMIC
section (cela changera dans la version de file
après 5.37; elle maintenant tilise la présence d'un PT_INTERP
section comme indicateur d'un binaire lié dynamiquement, qui correspond au commentaire dans le code).
L'éditeur de liens dynamique GNU C ne possède pas de DT_NEEDED
symboles, mais il a un PT_DYNAMIC
section (car il s'agit techniquement d'une bibliothèque partagée). Par conséquent, ldd
(qui est l'éditeur de liens dynamique) indique qu'il est lié statiquement, mais file
indique qu'il est lié dynamiquement. Il n'a pas de PT_INTERP
, donc la prochaine version de file
indiquera également qu'elle est liée statiquement.
$ ldd /lib64/ld-linux-x86-64.so.2
statically linked
$ file $(readlink /lib64/ld-linux-x86-64.so.2)
/lib/x86_64-linux-gnu/ld-2.28.so: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped
(avec file
5.35)
$ file $(readlink /lib64/ld-linux-x86-64.so.2)
/lib/x86_64-linux-gnu/ld-2.28.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped
(avec la version en cours de développement de file
).
Je soupçonne que le programme file
a tort que le lieur/chargeur dynamique soit lui-même lié dynamiquement. Le programme ldd
n'est pas d'accord. Du moins pas sur mon système (Debian Stretch):
ldd /lib/x86_64-linux-gnu/ld-2.24.so
statically linked
man ld.so
lit également: "ld-linux.so * gère ELF". Sur votre système (et le mien d'ailleurs), les deux sont des liens symboliques vers le même binaire que je déduis capable de gérer à la fois ELF et le (ancien obsolète) format a.out.