2016-08-09 1 views
2

Est-ce que Dynamic Linker (aka Programme Interpreter, Link Loader) fait partie du noyau ou de la bibliothèque GCC?Dynamic Linker fait-il partie du noyau ou de la bibliothèque GCC sur les systèmes Linux?

MISE À JOUR (28-08-16):

j'ai trouvé que le chemin par défaut pour éditeur de liens dynamique que chaque binaire (ie lié à une bibliothèque partagée) utilise /lib64/ld-linux-x86-64.so.2 est un lien vers la commune bibliothèque /lib/x86_64-linux-gnu/ld-2.23.so qui est le lieur dynamique réel. Il fait partie du package libc6 (2.23-0ubuntu3). GNU C Library: Shared libraries dans ubuntu pour les architectures AMD64.

Ma question réelle a été

ce qui arriverait à toutes les applications qui sont liées dynamiquement (tous, maintenant un jours), si ce programme d'aide (ld-2.23.so) n'existe pas?

Et répondez à cela "aucune application ne fonctionnera, même le programme shell". Je l'ai essayé sur une machine virale.

+0

'ld.so' ne fait pas partie du noyau, mais est chargé par celui-ci. –

+0

Cela fait partie de GNU libc sous Linux; voir http://www.cs.virginia.edu/~dww4s/articles/ld_linux.html – nephtes

Répondre

5

Dans un exécutable ELF, il est appelé "interpréteur ELF". Sur linux (par exemple) est ce /lib64/ld-linux-x86-64.so.2

C'est pas partie du noyau et glibc et [généralement]. Al.

Lorsque le noyau exécute un exécutable ELF, il doit mapper l'exécutable dans la mémoire de l'espace utilisateur. Il regarde ensuite à l'intérieur pour une sous-section spéciale connue sous le nom INTERP [qui contient une chaîne qui est le chemin complet].

Le noyau mappe ensuite l'interpréteur dans la mémoire de l'espace utilisateur et lui transfère le contrôle. Ensuite, l'interprète effectue la liaison/chargement nécessaire et démarre le programme.

Parce que ELF signifie «format de lien extensible», cela permet de nombreuses sous-sections différentes avec le fichier ELF.

Plutôt que de charger le noyau d'avoir à connaître toutes les innombrables extensions, l'interpréteur ELF associé au fichier le sait.

Bien que généralement un seul format soit utilisé sur un système donné, il peut y avoir plusieurs variantes différentes de fichiers ELF sur un système, chacun avec son propre interpréteur ELF. Cela permettrait [disons] qu'un fichier BSD ELF soit exécuté sur un système Linux [avec d'autres ajustements/support] car le fichier ELF pointe vers l'interpréteur BSD ELF plutôt que vers linux.


MISE À JOUR:

tous les processus (lecteur vlc, chrome) avait le ld.so de bibliothèque partagée dans le cadre de leur espace d'adressage.

Oui. Je suppose que vous regardez /proc/<pid>/maps. Ce sont les applications (par ex.comme en utilisant mmap) pour les fichiers. C'est quelque peu différent de "chargement", ce qui peut impliquer [symbole] reliant.

donc principalement chargeur après le chargement du fichier exécutable (code & données) sur la mémoire, il charge & cartes de liens dynamiques (.so) à son espace d'adressage

La meilleure façon de comprendre est reformule ce que vous venez de dire:

donc principalement le noyau après mapping le fichier exécutable (code & données) sur mémo ry, le noyau cartes de liens dynamiques (.so) pour le programme espace d'adressage

qui est essentiellement correcte. Le noyau cartographie également d'autres éléments, tels que le segment bss et la pile. Il "pousse" argc, argv, et envp [l'espace pour les variables d'environnement] sur la pile. Puis, ayant déterminé l'adresse de début de ld.so [en lisant une section spéciale du fichier], il définit cela comme l'adresse de reprise et lance le thread.

Jusqu'à maintenant, c'était le noyau qui faisait les choses. Le noyau fait peu ou pas de symbole reliant.

Maintenant, ld.so prend le relais ...

qui plus charges bibliothèques partagées, carte & résoudre les références aux bibliothèques. Elle appelle ensuite la fonction d'entrée (_start)

Parce que l'exécutable d'origine (par exemple vlc) a été cartographié en mémoire, ld.so peut examiner la liste des bibliothèques partagées dont il a besoin. Il cartes ces en mémoire, mais ne pas nécessairement lien les symboles tout de suite.

Le mappage est simple et rapide - il suffit d'un appel mmap.

L'adresse de début de l'exécutable [ne pas confondre avec l'adresse de début de ld.so], est tiré d'une section spéciale de l'exécutable ELF. Bien que, le symbole associé à cette adresse de départ a été traditionnellement appelé _start, il pourrait en fait être quelque chose nommé (par exemple __my_start) car il est ce qui est dans les données de la section qui détermine l'adresse de départ et pas adresse du symbole _start

Lier des références de symbole à des définitions de symbole est un processus qui prend du temps. Donc, ceci est différé jusqu'à ce que le symbole soit réellement utilisé.Autrement dit, si un programme a des références à printf, l'éditeur de liens ne cherche pas réellement à lier dans printf jusqu'à ce que la première fois que le programme fait appelsprintf

Cela est parfois appelé « lien sur demande » ou " liaison à la demande ". Voir ma réponse ici: Which segments are affected by a copy-on-write? pour une explication plus détaillée de cela et ce qui se passe réellement quand un exécutable est mappé dans l'espace utilisateur.

Si vous êtes intéressé, vous pouvez faire ldd /usr/bin/vlc pour obtenir la liste des bibliothèques partagées qu'il utilise. Si vous avez regardé la sortie de readelf -a /usr/bin/vlc, vous verrez ces mêmes bibliothèques partagées. De plus, vous obtiendrez le chemin complet de l'interpréteur ELF et pourrez faire readelf -a <full_path_to_interpreter> et noter quelques-unes des différences. Vous pouvez répéter le processus pour tous les fichiers .so voulus par vlc.

Combinant tout cela avec /proc/<pid>maps et. Al. pourrait aider avec votre compréhension.

+0

@criag. Comme je l'ai remarqué, tous les processus (lecteur vlc, chrome) avaient la bibliothèque partagée ** ld.so ** dans leur espace d'adressage. Donc principalement chargeur après chargement de l'exécutable (code et données) sur la mémoire, il charge et mappe ** éditeur de liens dynamiques (.so) ** à son espace d'adressage qui charge en outre les bibliothèques partagées, mappez et résolvez les références aux bibliothèques. Il appelle ensuite la fonction d'entrée (_start). Est-ce correct ? –

+1

Merde bonne explication Craig. –

+0

@craig. Merci craig, la mise à jour a été utile :) –