Entre les deux formats de binaires incompatibles, biblioth�ques statiques et dynamiques, on peut comparer l'op�ration d'�dition de lien en fait � un jeu ou l'on se demanderait qu'est-ce qui se passe lorsque je lance le programme ? Cette section n'est pas vraiment simple...
Pour dissiper la confusion qui r�gne, nous allons nous baser sur ce qui se passe lors d'ex�cution d'un programme, avec le chargement dynamique. Vous verrez �galement la description de l'�dition de liens dynamiques, mais plus tard. Cette section est d�di�e � l'�dition de liens qui intervient � la fin de la compilation.
La derni�re phase de construction d'un programme est de r�aliser
l'�dition de liens, ce qui consiste � assembler tous les morceaux
du programme et de chercher ceux qui sont manquants. Bien �videment,
beaucoup de programmes r�alisent les m�mes op�rations comme
ouvrir des fichiers par exemple, et ces pi�ces qui r�alisent ce genre
d'op�rations sont fournies sous la forme de biblioth�ques. Sous Linux,
ces biblioth�ques peuvent �tre trouv�es dans les r�pertoires
/lib
et/usr/lib/
entre autres.
Lorsque vous utilisez une biblioth�que statique, l'�diteur de liens
cherche le code dont votre programme a besoin et en effectue
une copie dans le programme physique g�n�r�. Pour les biblioth�ques
partag�es, c'est le contraire : l'�diteur de liens laisse du code
qui lors du lancement du programme chargera automatiquement la
biblioth�que. Il est �vident que ces biblioth�ques permettent
d'obtenir un ex�cutable plus petit; elles permettent �galement
d'utiliser moins de m�moire et moins de place disque. Linux
effectue par d�faut une �dition de liens dynamique s'il peut trouver
les biblioth�ques de ce type sinon, il effectue une �dition de liens
statique. Si vous obtenez des binaires statiques alors que vous les
voulez dynamiques v�rifiez que les biblioth�ques existent
(*.sa
pour le format a.out, et *.so
pour le format ELF) et
que vous poss�dez les droits suffisants pour y acc�der (lecture).
Sous Linux, les biblioth�ques statiques ont pour nom libnom.a
,
alors que les biblioth�ques dynamiques sont appel�es
libnnom.so.x.y.z
o� x.y.z
repr�sente le num�ro de
version. Les biblioth�ques dynamiques ont souvent des liens logiques qui
pointent dessus, et qui sont tr�s importants. Normalement, les biblioth�ques
standards sont livr�es sous la double forme dynamique
et statique.
Vous pouvez savoir de quelles biblioth�ques dynamiques un programme a besoin
en utilisant la commande ldd
(List Dynamic Dependencies)
$ ldd /usr/bin/lynx
libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
libc.so.5 => /lib/libc.so.5.2.18
Cela indique sur mon syst�me que l'outil lynx
(outil WWW)
a besoin des biblioth�ques dynamiques libc.so.5
(la biblioth�que C)
et de libncurses.so.1
(n�cessaire pour le contr�le du terminal).
Si un programme ne poss�de pas de d�pendances, ldd
indiquera
`statically linked' (�dition de liens statique).
sin()
?') nm
nomdebiblioth�que vous donne tous les symboles r�f�renc�s dans
la biblioth�que. Cela fonctionne que cela soit du code statique ou dynamique.
Supposez que vous vouliez savoir o� se trouve d�finie la fonction
tcgetattr()
:
$ nm libncurses.so.1 |grep tcget
U tcgetattr
La lettre U
vous indique que c'est ind�fini (Undefined)
--- cela indique que la biblioth�que ncurses l'utilise mais ne la d�finit pas.
Vous pouvez �galement faire :
$ nm libc.so.5 | grep tcget
00010fe8 T __tcgetattr
00010fe8 W tcgetattr
00068718 T tcgetpgrp
La lettre `W
' indique que le symbole est d�fini mais de telle
mani�re qu'il peut �tre surcharg� par une autre d�finition de la fonction
dans une autre biblioth�que (W pour weak : faible).
Une d�finition normale est marqu�e par la lettre `T
'
(comme pour tcgetpgrp
).
La r�ponse � la question situ�e dans le titre est
libm.(so|a)
. Toutes les fonctions d�finies dans le fichier
d'en-t�te <math.h>
sont impl�ment�es dans la
biblioth�que math�matique donc vous devrez effectuer l'�dition de liens
gr�ce � -lm
.
Supposons que vous ayez le message d'erreur suivant de la part de l'�diteur de liens :
ld: Output file requires shared library `libfoo.so.1`
La strat�gie de recherche de fichiers de ld ou de ses copains
diff�re de la version utilis�e, mais vous pouvez �tre s�r
que les fichiers situ�s dans le r�pertoire /usr/lib
seront trouv�s. Si vous d�sirez que des fichiers situ�s � un endroit
diff�rent soient trouv�s, il est pr�f�rable d'ajouter l'option
-L
� gcc ou ld.
Si cela ne vous aide pas clairement, v�rifiez que vous avez le bon
fichier � l'endroit sp�cifi�. Pour un syst�me a.out,
effectuer l'�dition de liens avec -ltruc
implique que ld recherche
les biblioth�ques libtruc.sa
(biblioth�ques partag�es), et si elle
n'existe pas, il recherche libtruc.a
(statique). Pour le format
ELF, il cherche libtruc.so
puis libtruc.a
.
libtruc.so
est g�n�ralement un lien symbolique vers
libtruc.so.x
.
Comme tout programme, les biblioth�ques ont tendance � avoir quelques bogues qui sont corrig�s au fur et � mesure. De nouvelles fonctionnalit�s sont ajout�es et qui peuvent changer l'effet de celles qui existent ou bien certaines anciennes peuvent �tres supprim�es. Cela peut �tre un probl�me pour les programmes qui les utilisent.
Donc, nous introduisons la notion de num�ro de version. Nous
r�pertorions les modifications effectu�es dans la biblioth�ques
comme �tant soit mineures soit majeures. Cela signifie qu'une
modification mineure ne peut pas modifier le fonctionnement d'un
programme (en bref, il continue � fonctionner comme avant). Vous pouvez
identifier le num�ro de la version de la biblioth�que en regardant
son nom (en fait c'est un mensonge pour les biblioth�ques ELF... mais
continuez � faire comme si !) : libtruc.so.1.2
a pour version
majeure 1 et mineure 2. Le num�ro de version mineur peut �tre
plus ou moins �lev� --- la biblioth�que C met un num�ro de patch,
ce qui produit un nom tel que libc.so.5.2.18
, et c'est �galement
courant d'y trouver des lettres ou des blancs soulign�s ou tout
autre caract�re ASCII affichable.
Une des principales diff�rences entre les formats ELF et a.out se trouve dans la mani�re de construire la biblioth�que partag�e. Nous traiterons les biblioth�ques partag�es en premier car c'est plus simple.
ELF (Executable and Linking Format) est format de binaire initialement con�u et d�velopp� par USL (UNIX System Laboratories) et utilis� dans les syst�mes Solaris et System R4. En raison de sa facilit� d'utilisation par rapport � l'ancien format dit a.out qu'utilisait Linux, les d�veloppeurs de GCC et de la biblioth�que C ont d�cid� l'ann�e derni�re de basculer tout le syst�me sous le format ELF. ELF est d�sormais le format binaire standard sous Linux.
Ce paragraphe provient du groupe '/news-archives/comp.sys.sun.misc'.
ELF (Executable Linking Format) est le � nouveau et plus performant � format de fichier introduit dans SVR4. ELF est beaucoup plus puissant que le sacro-saint format COFF, dans le sens o� il est extensible. ELF voit un fichier objet comme une longue liste de sections (plut�t qu'un tableau de taille fixe d'�l�ments). Ces sections, � la diff�rence de COFF ne se trouvent pas � un endroit constant et ne sont pas dans un ordre particulier, etc. Les utilisateurs peuvent ajouter une nouvelle section � ces fichiers objets s'il d�sirent y mettre de nouvelles donn�es. ELS poss�de un format de d�bogage plus puissant appel� DWARF (Debugging With Attribute Record Format) - par encore enti�rement g�r� par Linux (mais on y travaille !). Une liste cha�n�e de � DWARF DIEs � (ou Debugging Information Entries - NdT... le lecteur aura s�rement not� le jeu de mot assez noir : dwarf = nain; dies = morts) forment la section .debug dans ELF. Au lieu d'avoir une liste de petits enregistrements d'information de taille fixes, les DWARF DIEs contiennent chacun une longue liste complexe d'attributs et sont �crits sous la forme d'un arbre de donn�es. Les DIEs peuvent contenir une plus grande quantit� d'information que la section .debug du format COFF ne le pouvait (un peu comme les graphes d'h�ritages du C++).
Les fichiers ELF sont accessibles gr�ce � la biblioth�que d'acc�s de SVR4 (Solaris 2.0 peut-�tre ?), qui fournit une interface simple et rapide aux parties les plus complexes d'ELF. Une des aubaines que permet la biblioth�que d'acc�s ELF est que vous n'avez jamais besoin de conna�tre les m�andres du format ELF. Pour acc�der � un fichier Unix, on utilise un Elf *, retourn� par un appel � elf_open(). Ensuite, vous effectuez des appels � elf_foobar() pour obtenir les diff�rents composants au lieu d'avoir � triturer le fichier physique sur le disque (chose que beaucoup d'utilisateurs de COFF ont fait...).
Les arguments pour ou contre ELF, et les probl�mes li�s � la mise � jour d'un syst�me a.out vers un syst�me ELF sont d�crits dans le ELF-HOWTO et je ne veux pas effectuer de copier coller ici (NdT: ce HowTo est �galement traduit en fran�ais). Ce HowTo se trouve au m�me endroit que les autres.
Pour construire libtruc.so
comme une biblioth�que dynamique,
il suffit de suivre les �tapes suivantes :
$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname,libtruc.so.1 -o libtruc.so.1.0 *.o
$ ln -s libtruc.so.1.0 libtruc.so.1
$ ln -s libtruc.so.1 libtruc.so
$ LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH ; export LD_LIBRARY_PATH
Cela va g�n�rer une biblioth�que partag�e appel�e libtruc.so.1.0
,
les liens appropri�s pour ld (libtruc.so
) et
le chargeur dynamique (libtruc.so.1
) pour le trouver.
Pour tester, nous ajoutons le r�pertoire actuel � la
variable d'environnement LD_LIBRARY_PATH
.
Lorsque vous �tes satisfait et que la biblioth�que fonctionne, vous
n'avez plus qu'� la d�placer dans le r�pertoire par exemple,
/usr/local/lib
, et de recr�er les liens appropri�s. Le lien
de libtruc.so.1
sur libtruc.so.1.0
est enregistr� par
ldconfig
, qui sur bon nombre de syst�mes est lanc� lors
du processus d'amor�age. Le lien libfoo.so
doit �tre mis � jour
� la main. Si vous faites attention lors de la mise � jour de la
biblioth�que la chose la plus simple � r�aliser est de cr�er le lien
libfoo.so -> libfoo.so.1
, pour que ldconfig conserve les liens
actuels. Si vous ne faites pas cela, vous aurez des probl�mes plus
tard. Ne me dites pas que l'on ne vous a pas pr�venu !
$ /bin/su
# cp libtruc.so.1.0 /usr/local/lib
# /sbin/ldconfig
# ( cd /usr/local/lib ; ln -s libtruc.so.1 libtruc.so )
Chaque biblioth�que poss�de un nom propre (soname).
Lorsque l'�diteur de liens en trouve un qui correspond � un nom
cherch�, il enregistre le nom de la biblioth�que dans le code binaire
au lieu d'y mettre le nom du fichier de la biblioth�que. Lors de
l'ex�cution, le chargeur dynamique va alors chercher un fichier ayant
pour nom le nom propre de la biblioth�que, et pas le nom du fichier
de la biblioth�que. Par exemple, une biblioth�que ayant pour nom
libtruc.so
peut avoir comme nom propre libbar.so
, et tous
les programmes li�s avec vont alors chercher libbar.so
lors de leur ex�cution.
Cela semble �tre une nuance un peu pointilleuse mais c'est la clef
de la compr�hension de la coexistence de plusieurs versions
diff�rentes de la m�me biblioth�que sur le m�me syst�me.
On a pour habitude sous Linux d'appeler une biblioth�que
libtruc.so.1.2
par exemple, et de lui donner comme
nom propre libtruc.so.1
. Si cette biblioth�que est rajout�e
dans un r�pertoire standard (par exemple dans /usr/lib
),
le programme ldconfig
va cr�er un lien symbolique
entre libtruc.so.1 -> libtruc.so.1.2
pour que l'image
appropri�e soit trouv�e lors de l'ex�cution. Vous aurez �galement besoin
d'un lien symbolique libtruc.so -> libtruc.so.1
pour que ld
trouve le nom propre lors de l'�dition de liens.
Donc, lorsque vous corrigez des erreurs dans la biblioth�que ou
bien lorsque vous ajoutez de nouvelles fonctions (en fait, pour
toute modification qui n'affecte pas l'ex�cution des programmes d�j�
existants), vous reconstruisez la biblioth�que, conservez le nom propre
tel qu'il �tait et changez le nom du fichier. Lorsque vous effectuez des
modifications que peuvent modifier le d�roulement des programmes
existants, vous pouvez tout simplement incr�menter le nombre situ�
dans le nom propre --- dans ce cas, appelez la nouvelle version de la
biblioth�que libtruc.so.2.0
, et donnez-lui comme nom propre
libtruc.so.2
. Maintenant, faites pointer le lien de
libfoo.so
vers la nouvelle version et tout est bien dans
le meilleur des mondes !
Il est utile de remarquer que vous n'�tes pas oblig� de nommer les biblioth�ques de cette mani�re, mais c'est une bonne convention. Elf vous donne une certaine libert� pour nommer des biblioth�ques tant et si bien que cela peut perturber certains utilisateurs, mais cela ne veut pas dire que vous �tes oblig� de le faire.
R�sum� : supposons que choisissiez d'adopter la m�thode traditionnelle avec les mises � jour majeures qui peuvent ne pas �tre compatibles avec les versions pr�c�dentes et les mises � jour mineures qui ne posent pas ce probl�me. Il suffit de cr�er la biblioth�que de cette mani�re :
gcc -shared -Wl,-soname,libtruc.so.majeur -o libtruc.so.majeur.mineur
et tout devrait �tre parfait !La facilit� de construire des biblioth�que partag�es est la raison principale de passer � ELF. Ceci dit, il est toujours possible de cr�er des biblioth�ques dynamiques au format a.out. R�cup�rez le fichier archive ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.17.tar.gz et lisez les 20 pages de documentation que vous trouverez dedans apr�s l'avoir d�sarchiv�. Je n'aime pas avoir l'air d'�tre aussi partisan, mais il est clair que je n'ai jamais aim� ce format :-).
QMAGIC est le format des ex�cutables qui ressemble un peu aux vieux binaires a.out (�galement connu comme ZMAGIC), mais qui laisse la premi�re page libre. Cela permet plus facilement de r�cup�rer les adresses non affect�es (comme NULL) dans l'intervalle 0-4096 (NdT : Linux utilise des pages de 4Ko).
Les �diteurs de liens d�suets ne g�rent que le format ZMAGIC, ceux un peu moins rustiques g�rent les deux, et les plus r�cents uniquement le QMAGIC. Cela importe peu car le noyau g�re les deux types.
La commande file
est capable d'identifier si un programme est
de type QMAGIC.
Une biblioth�que dynamique a.out (DLL) est compos�e de
deux fichiers et d'un lien symbolique. Supposons que l'on
utilise la biblioth�que truc, les fichiers seraient
les suivants : libtruc.sa
et libtruc.so.1.2
; et le
lien symbolique aurait pour nom libtruc.so.1
et pointerait
sur le dernier des fichiers. Mais � quoi servent-ils ?
Lors de la compilation, ld
cherche libtruc.sa
.
C'est le fichier de description de la biblioth�que : il contient
toutes les donn�es export�es et les pointeurs vers les fonctions
n�cessaires pour l'�dition de liens.
Lors de l'ex�cution, le chargeur dynamique cherche libtruc.so.1
.
C'est un lien symbolique plut�t qu'un r�el fichier pour que les
biblioth�ques puissent �tre mise � jour sans avoir � casser les
applications qui utilisent la biblioth�que. Apr�s la mise � jour,
disons que l'on est pass� � la version libfoo.so.1.3
,
le lancement de ldconfig va positionner le lien. Comme
cette op�ration est atomique, aucune application fonctionnant
n'aura de probl�me.
Les biblioth�ques DLL (Je sais que c'est une tautologie... mais pardon !)
semblent �tre tr�s souvent plus importantes que leur �quivalent
statique. En fait, c'est qu'elles r�servent de la place pour les
extensions ult�rieures sous la simple forme de trous qui sont
fait de telle mani�re qu'ils n'occupent pas de place disque (NdT :
un peu comme les fichiers core
). Toutefois, un
simple appel � cp
ou � makehole
les remplira...
Vous pouvez effectuer une op�ration de strip
apr�s la construction
de la biblioth�que, comme les adresses sont � des endroits fixes.
Ne faites pas la m�me op�ration avec les biblioth�ques ELF !
Une � libc-lite � (contraction de libc et little)
est une version �pur�e et r�duite de la biblioth�que
libc construite de telle mani�re qu'elle puisse tenir sur
une disquette avec un certain nombre d'outil Unix.
Elle n'inclut pas curses, dbm, termcap, ...
Si votre /lib/libc.so.4
est li�e avec une biblioth�que de ce genre
il est tr�s fortement conseill� de la remplacer avec une version compl�te.
Envoyez-les moi !
V�rifiez que vous avez les bons liens pour que ld
puisse
trouver les biblioth�ques partag�es. Pour ELF cela veut dire que
libtruc.so
est un lien symbolique sur son image,
pour a.out un fichier libtruc.sa
. Beaucoup de personnes
ont eu ce probl�me apr�s �tre pass�s des outils ELF 2.5 � 2.6
(binutils
) --- la derni�re version effectue une recherche
plus intelligente pour les biblioth�ques dynamiques et donc ils
n'avaient pas cr�� tous les liens symboliques n�cessaires.
Cette caract�ristique avait �t� supprim�e pour des raisons de compatibilit�
avec d'autres architectures et parce qu'assez souvent cela ne marchait
pas bien. En bref, cela posait plus de probl�mes qu'autre chose.
Comme libc.so.4.5.x
et suivantes, libgcc n'est pas une
biblioth�que partag�e. Vous devez remplacer les `-lgcc
'
sur la ligne de commande par
`gcc -print-libgcc-file-name`
(entre quotes)
Egalement, d�truisez tous les fichiers situ�s dans /usr/lib/libgcc*
.
C'est important.
__NEEDS_SHRLIB_libc_4 multiply defined
Sont une cons�quence du m�me probl�me.
Ce message �nigmatique signifie qu'un �l�ment de votre table jump
a d�pass� la table car trop peu de place �tait r�serv�e dans le fichier
jump.vars
file. Vous pouvez trouver le(s) coupable(s) en lan�ant
la commande getsize
fournie dans le paquetage tools-2.17.tar.gz.
La seule solution est de passer � une nouvelle version majeure,
m�me si elle sera incompatible avec les pr�c�dentes.
ld: output file needs shared library libc.so.4
Cela arrive lorsque vous effectuez l'�dition de liens avec des biblioth�ques
diff�rentes de la libc (comme les biblioth�ques X) et que vous utilisez
l'option -g
sans utiliser l'option -static
.
Les fichiers .sa
pour les biblioth�ques dynamiques ont un symbole
non r�solu _NEEDS_SHRLIB_libc_4
qui est d�fini dans
libc.sa
. Or, lorsque vous utilisez -g
vous faites l'�dition
de liens avec libg.a
ou libc.a
et donc ce symbole n'est jamais
d�fini.
Donc, pour r�soudre le probl�me, ajoutez l'option -static
lorsque vous compilez avec l'option -g
, ou n'utilisez pas
-g
lors de l'�dition de liens !
Hosting by: Hurra Communications GmbH
Generated: 2007-01-26 18:01:30