Comment ldd
sait que cela dépend de libc.so.6
, pas libc.so.5
ou libc.so.7
?Comprendre la sortie ldd
libc.so.6 => /lib64/libc.so.6 (0x00000034f4000000)
/lib64/ld-linux-x86-64.so.2 (0x00000034f3c00000)
Comment ldd
sait que cela dépend de libc.so.6
, pas libc.so.5
ou libc.so.7
?Comprendre la sortie ldd
libc.so.6 => /lib64/libc.so.6 (0x00000034f4000000)
/lib64/ld-linux-x86-64.so.2 (0x00000034f3c00000)
Il est enregistré à l'intérieur binaire d'application lui-même (spécifiée au moment de la compilation, plus exactement à l'étape de liaison, fait avec ld
):
$ readelf -d /bin/echo
Dynamic section at offset 0x5f1c contains 21 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
...
(il y a des colonnes supplémentaires pour la façon dont Elf fait stocker des informations . dans la section dynamique, mais vous pouvez voir que libc.so.6 est codé en dur avec .6
suffixe en raison de SONAME)
ou même sans aucune connaissance du format de fichier ELF:
$ strings /bin/echo |grep libc.so
libc.so.6
Pour trouver, comment linker trouve une bibliothèque (elle est faite à l'étape finale de la compilation), utilisez gcc
l'option -Wl,--verbose
(cette demande gcc passer l'option --verbose
-ld
):
$ gcc a.c -Wl,--verbose
...
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.so failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.a failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.so failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.a failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so succeeded
opened script file /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so
opened script file /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so
attempt to open /lib/libc.so.6 succeeded
/lib/libc.so.6
Linker ne sait rien sur le suffixe .digit
, il suffit de parcourir tous les répertoires de recherche de bibliothèque en essayant d'ouvrir libLIBNAME.so
et , où LIBNAME est une chaîne après l'option -l
. (L'option -lc
est ajoutée par défaut).
Premier succès est /usr/lib/libc.so
qui lui-même n'est pas une bibliothèque, mais un script de liaison (fichier texte). Voici le contenu du scénario typique libc.so
:
$ cat /usr/lib/libc.so
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
GROUP (/lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED (/lib/ld-linux.so.2))
Ainsi, le script /usr/lib/libc.so
se trouve plus tôt que la bibliothèque réelle, et ce script dit, ce fichier sera lié, libc.so.6
dans ce cas.
En cas le plus fréquent, lib___.so
symlink à une version comme lib___.so.3.4.5
et il y a champ SONAME rempli lib___.so.3.4.5
qui dit ld
lien pas lib___.so
mais lib___.so.3.4
qui est un autre lien symbolique vers lib___.so.3.4.5
. Le nom .3.4
sera enregistré dans le champ Binaire NÉCESSAIRE.
http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#dynamic_section
a la signification de chaque balises dynamiques. Le 1 indique qu'il est un sens de l'étiquette DT_NEEDED dans ce cas, le
typedef struct {
Elf32_Sword d_tag;
union {
Elf32_Word d_val;
Elf32_Addr d_ptr;
} d_un;
} Elf32_Dyn;
la structure
a union d_val valide et rechercher à un décalage spécifié par thi membre du syndicat dans le tableau DT_STRTAB pour trouver le nom de la bibliothèque que ce binaire/SO dépend de.
Que signifie «0x00000001 (NEEDED)»? –
Est-il vrai que 'ldconfig' liera' libc.so.6' à la dernière version de 'libc.so.6.x', et lierait' lib.so' à la dernière version de 'libc.so.x '? Et supposons que 'lib.so' soit lié à' lib.so.7', alors le binaire généré par 'gcc -l lib.so ...' dépendra de 'lib.so.7', n'est-ce pas? –
+1 pour modifier votre réponse afin de contenir autant d'informations utiles. Ceci est un post SO classique. Merci. –