Sur les systèmes Linux 32 bits, l'appel de cette
$ /lib/libc.so.6
et sur les systèmes 64 bits cette
$ /lib/x86_64-linux-gnu/libc.so.6
dans un shell, fournit une sortie comme celle-ci:
GNU C Library stable release version 2.10.1, by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.4.0 20090506 (Red Hat 4.4.0-4).
Compiled on a Linux >>2.6.18-128.4.1.el5<< system on 2009-08-19.
Available extensions:
The C stubs add-on version 2.1.2.
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
RT using linux kernel aio
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
Pourquoi et comment cela se produit-il et comment est-il possible de faire la même chose dans d'autres bibliothèques partagées?
J'ai regardé /usr/lib
pour trouver des exécutables, et j'ai trouvé /usr/lib/libvlc.so.5.5.0
. L'exécuter a conduit à une erreur de segmentation . : - /
Réponses:
Cette bibliothèque a une
main()
fonction ou un point d’entrée équivalent et a été compilée de telle sorte qu’elle soit utile à la fois comme exécutable et comme objet partagé.Voici une suggestion sur la façon de procéder, bien que cela ne fonctionne pas pour moi.
Voici une autre réponse à une question similaire sur SO , que je vais plagier sans vergogne, peaufiner et ajouter un peu d'explication.
Tout d’abord, source pour notre exemple de bibliothèque
test.c
,:Compiler que:
Ici, nous compilons une bibliothèque partagée (
-fPIC
), mais nous disons à l'éditeur de liens qu'il s'agit d'un exécutable (-pie
) régulier et nous rendons sa table de symboles exportable (-Wl,-E
), de manière à ce qu'elle puisse être liée utilement.Et, bien que
file
dira que c'est un objet partagé, cela fonctionne comme un exécutable:Maintenant, nous devons voir si cela peut vraiment être lié dynamiquement. Un exemple de programme
program.c
,:L'utilisation
extern
nous évite d'avoir à créer un en-tête. Maintenant compilez ça:Avant de pouvoir l'exécuter, nous devons ajouter le chemin de
libtest.so
pour le chargeur dynamique:Maintenant:
Et
ldd a.out
montrera le lien verslibtest.so
.Notez que je doute que c’est ainsi que glibc soit réellement compilée, car elle n’est probablement pas aussi portable que glibc elle-même (voir
man gcc
en ce qui concerne les commutateurs-fPIC
et-pie
), mais elle illustre le mécanisme de base. Pour plus de détails, vous devriez regarder le fichier makefile source.la source
nm
sur la bibliothèque partagée, mais ce n'était pas une version de débogage. Alors, pourquoilibvlc
et d'autres crash?libc
est une exception.ld
etlibpthread
.ld.so
est spécial à d'autres égards. Dans une certaine mesure, il s’agit plus d’un véritable exécutable que d’un exécutable normal lié dynamiquement.Plongeons-nous pour une réponse dans un dépôt aléatoire glibc dans github. Cette version fournit une "bannière" dans le fichier
version.c
.Dans le même fichier, il y a quelques points intéressants:
__libc_print_version
la fonction qui permet d’imprimer sur stdin le même texte et le même symbole,__libc_main (void)
documentés comme point d’entrée. Donc, ce symbole est appelé lors de l'exécution de la bibliothèque.Alors, comment l'éditeur de liens / compilateur sait-il qu'il s'agit exactement d'une fonction de point d'entrée?
Nous allons plonger dans le makefile . Dans les drapeaux de l'éditeur de liens, il y a un drapeau intéressant:
Il s’agit donc d’un indicateur d’éditeur de liens pour la définition du point d’entrée dans la bibliothèque. Lors de la construction d'une bibliothèque, vous pouvez fournir
-e function_name
à l'éditeur de liens un comportement exécutable. Qu'est-ce que ça fait vraiment? Regardons le manuel (un peu daté mais toujours valable) :(la documentation actuelle peut être trouvée ici )
Vraiment, l'
ld
éditeur de liens crée un exécutable avec une fonction de point d'entrée si vous lui fournissez une option de ligne de commande-e
(solution la plus pratique), un symbole de fonctionstart
ou une adresse de symbole dans l'assembleur.Cependant, veuillez noter qu'il n'est clairement pas garanti de travailler avec d'autres linkers (je ne sais pas si llvm's lld a le même drapeau). Pourquoi cela devrait-il être utile à des fins autres que la fourniture d'informations sur un fichier, je ne le sais pas.
la source