Ce paragraphe est en fait un peu court : il sera étendu dans une version ultérieure dès que j'aurai récupéré le HowTo ELF
Linux possède des bibliothèques dynamiques, comme on vous le répète depuis le début de ce document ! Or, il existe un système pour reporter le travail d'association des noms des symboles et de leur adresse dans la bibliothèque, qui est normalement effectué lors de l'édition de liens en l'effectuant lors du chargement du programme.
Envoyez moi vos erreurs ! Je n'en fait pas grand chose sauf les insérer dans ce paragraphe...
can't load library: /lib/libxxx.so, Incompatible version
(seulement a.out) Cela signifie que vous n'avez pas la version correcte de la bibliothèque (numéro dit majeur). Non, il n'est pas possible d'effectuer un lien symbolique sur la bibliothèque que vous possédez : si vous avez de la chance, vous obtiendrez un segmentation fault. Récupérez la nouvelle version. Un message un peu équivalent existe également sur les systèmes ELF :
ftp: can't load library 'libreadline.so.2'
warning using incompatible library version xxx
(seulement a.out) Vous avez un numéro de version de bibliothèque (mineur) inférieur à la version avec laquelle a été compilé le programme. Le programme fonctionnera sûrement. Une mise à jour est toutefois conseillée.
Il existe certaines variables d'environnements que le chargeur dynamique
utilise. Beaucoup sont exploitées par le programme ldd
lorsqu'il
s'agit de particularités de l'environnement de l'utilisateur, ce qui
peuvent être positionnées pour lancer ldd avec des options
particulières. Voici une description des différentes variables d'environnement
que vous pouvez rencontrer :
LD_BIND_NOW
--- normalement, les fonctions ne sont
pas cherchées dans les bibliothèques avant leur appel. En positionnant
cette option, vous vérifiez que toutes les fonctions employées dans
votre programmes se trouvent bien dans la bibliothèque lors de son
chargement, ce qui ralentit le lancement du programme. C'est utile lorsque
vous voulez tester que l'édition de liens s'est parfaitement déroulée
et que tous les symboles sont bien associés.
LD_PRELOAD
peut être défini avec un nom de fichier
qui contient des fonctions surchargeant des fonctions déjà existantes.
Par exemple, si vous testez une stratégie d'allocation mémoire,
et que vous voulez remplacer le malloc de la bibliothèque C par le
vôtre situé dans un module ayant pour nom malloc.o
, il vous suffit
de faire :
$ export LD_PRELOAD=malloc.o
$ test_mon_malloc
LD_ELF_PRELOAD
et LD_AOUT_PRELOAD
sont similaires, mais
leur utilisation est spécifique au type de binaire utilisé. Si
LD_
TypeBinaire_PRELOAD
et LD_PRELOAD
sont positionnés,
celui correspondant le mieux à la machine est utilisé.
LD_LIBRARY_PATH
contient une liste de répertoires contenant
les bibliothèques dynamiques. Cela n'affecte pas l'édition de liens :
cela n'a qu'un effet lors de l'exécution. Il faut noter qu'elle est
désactivée pour des programmes qui s'exécutent avec un setuid ou un setgid.
Enfin, LD_ELF_LIBRARY_PATH
et
LD_AOUT_LIBRARY_PATH
peuvent être utilisés pour orienter le mode de
compilation du binaire. LD_LIBRARY_PATH
ne devrait pas être nécessaire en principe : ajoutez les répertoires dans le
fichier /etc/ld.so.conf/
et relancez ldconfig.
LD_NOWARN
s'applique au format a.out uniquement. Lorsqu'elle
est positionnée (c.a.d si elle existe par exemple avec
LD_NOWARN=true; export LD_NOWARN
) cela arrête le chargeur du programme
même sur des avertissements insignifiants (tels que des messages
d'incompatibilités de numéros mineurs de version).
LD_WARN
s'applique à ELF uniquement. Lorsqu'elle est
positionnée, on transforme le message habituellement fatal Can't find
library en un avertissement. Ce n'est pas positionné par défaut mais
c'est important pour un programme comme ldd.
LD_TRACE_LOADED_OBJECTS
s'applique à ELF uniquement, et
permet de simuler l'exécution des programmes comme s'ils l'étaient
par ldd
:
$ LD_TRACE_LOADED_OBJECTS=true /usr/bin/lynx
libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
libc.so.5 => /lib/libc.so.5.2.18
Cela ressemble énormément au système de chargement dynamique
utilisé sous Solaris 2.x. Ce système est décrit d'une
manière précise dans le document expliquant la programmation
avec ELF écrit par H J Lu et dans la page de manuel
dlopen(3)
, qui se trouve dans le paquetage ld.so.
Voici un exemple simple : pensez à faire l'édition de liens avec
-ldl
#include <dlfcn.h>
#include <stdio.h>
main()
{
void *libc;
void (*printf_call)();
if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
{
printf_call = dlsym(libc,"printf");
(*printf_call)("Bonjour ! Ha ben ca marche pil poil sous Linux !\n");
}
}