Page suivantePage pr�c�denteTable des mati�res

6. Edition de liens

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.

6.1 Biblioth�ques partag�es contre biblioth�ques statiques

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).

6.2 A la recherche des fonctions... ou dans quelle biblioth�que se trouve la fonction 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.

6.3 Trouver les fichiers

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.

6.4 Compiler votre propre biblioth�que

Num�ro de la version

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, qu'est-ce que c'est ?

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.

ELF, le retour !

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.

Les biblioth�que partag�es ELF

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 )

Les num�ros de version, les noms et les liens

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 !

a.out. Le bon vieux format

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 :-).

ZMAGIC contre QMAGIC

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.

Gestion des fichiers

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 !

� libc-lite � ?

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.

Edition de liens : probl�me courants

Envoyez-les moi !

Des programmes statiques lorsque vous les voulez partag�s

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.

Le programme `mkimage' n'arrive pas � trouver libgcc

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.

Le message __NEEDS_SHRLIB_libc_4 multiply defined

Sont une cons�quence du m�me probl�me.

Le message ``Assertion failure'' appara�t lorsque vous reconstruisez une DLL

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 !


Page suivantePage pr�c�denteTable des mati�res

Hosting by: Hurra Communications GmbH
Generated: 2007-01-26 18:01:30