web-dev-qa-db-fra.com

Où les exécutables recherchent-ils des objets partagés lors de l'exécution?

Je comprends comment définir des objets partagés au moment de la liaison/compilation. Cependant, je me demande toujours comment les exécutables recherchent l'objet partagé (*.so bibliothèques) au moment de l'exécution.

Par exemple, mon application a.out appelle les fonctions définies dans le lib.so bibliothèque. Après la compilation, je déplace lib.so vers un nouveau répertoire dans mon $HOME.

Comment puis-je dire a.out pour aller le chercher là-bas?

120
rahmu

Le HOWTO de la bibliothèque partagée explique la plupart des mécanismes impliqués, et le manuel du chargeur dynamique va plus en détail. Chaque variante Unix a sa propre façon, mais la plupart utilisent le même format exécutable ( ELF ) et ont des linkers dynamiques (dérivés de Solaris). Ci-dessous, je vais résumer le comportement courant en mettant l'accent sur Linux; consultez les manuels de votre système pour l'histoire complète.

En bref, quand il cherche une bibliothèque dynamique (.so fichier), l'éditeur de liens essaie:

  • répertoires répertoriés dans le LD_LIBRARY_PATH variable d'environnement (DYLD_LIBRARY_PATH sur OSX);
  • répertoires répertoriés dans l'exécutable rpath ;
  • répertoires sur le chemin de recherche du système, qui (au moins sous Linux) se compose des entrées dans /etc/ld.so.conf plus /lib et /usr/lib.

Le rpath est stocké dans l'exécutable (c'est le DT_RPATH ou DT_RUNPATH attribut dynamique). Il peut contenir des chemins absolus ou des chemins commençant par $Origin pour indiquer un chemin par rapport à l'emplacement de l'exécutable (par exemple, si l'exécutable est dans /opt/myapp/bin et son chemin d'accès est $Origin/../lib:$Origin/../plugins alors l'éditeur de liens dynamique cherchera dans /opt/myapp/lib et /opt/myapp/plugins). Le chemin d'accès est normalement déterminé lors de la compilation de l'exécutable, avec le -rpath option à ld, mais vous pouvez la changer ensuite avec chrpath .

Dans le scénario que vous décrivez, si vous êtes le développeur ou le conditionneur de l'application et que vous prévoyez de l'installer dans un …/bin, …/lib structure, puis liez avec -rpath='$Origin/../lib'. Si vous installez un binaire précompilé sur votre système, placez la bibliothèque dans un répertoire sur le chemin de recherche (/usr/local/lib si vous êtes l'administrateur système, sinon un répertoire que vous ajoutez à $LD_LIBRARY_PATH), ou essayez chrpath.

Sous Linux, le comportement est expliqué dans la page de manuel ld(1)

       The linker uses the following search paths to locate required
       shared libraries:

       1.  Any directories specified by -rpath-link options.

       2.  Any directories specified by -rpath options.  The difference
           between -rpath and -rpath-link is that directories specified by
           -rpath options are included in the executable and used at
           runtime, whereas the -rpath-link option is only effective at
           link time. Searching -rpath in this way is only supported by
           native linkers and cross linkers which have been configured
           with the --with-sysroot option.

       3.  On an ELF system, for native linkers, if the -rpath and
           -rpath-link options were not used, search the contents of the
           environment variable "LD_RUN_PATH".

       4.  On SunOS, if the -rpath option was not used, search any
           directories specified using -L options.

       5.  For a native linker, the search the contents of the environment
           variable "LD_LIBRARY_PATH".

       6.  For a native ELF linker, the directories in "DT_RUNPATH" or
           "DT_RPATH" of a shared library are searched for shared
           libraries needed by it. The "DT_RPATH" entries are ignored if
           "DT_RUNPATH" entries exist.

       7.  The default directories, normally /lib and /usr/lib.

       8.  For a native linker on an ELF system, if the file
           /etc/ld.so.conf exists, the list of directories found in that
           file.

       If the required shared library is not found, the linker will issue
       a warning and continue with the link.
16
enzotib

Je suis sûr que la réponse ici est ldconfig.

ldconfig crée les liens et le cache nécessaires vers les bibliothèques partagées les plus récentes trouvées dans les répertoires spécifiés sur la ligne de commande, dans le fichier /etc/ld.so.conf et dans les répertoires approuvés (/ lib et/usr/lib). Le cache est utilisé par l'éditeur de liens d'exécution, ld.so ou ld-linux.so. ldconfig vérifie l'en-tête et les noms de fichiers des bibliothèques rencontrées lors de la détermination des versions dont les liens doivent être mis à jour.

http://linux.die.net/man/8/ldconfig

3
Sean C.

Pour exécuter des applications, le fichier /proc/1234/maps contient toutes les bibliothèques liées dynamiquement.

1234 est le pid de l'exécutable en cours d'exécution.

Linux suit LD_LIBRARY_PATH et d'autres variables, comme indiqué en réponse par Gilles.

0
user138692