2.13 Edition des liens 3/5
-
Bibliothèques statiques
- Algorithme d’édition des liens :
-
entrée : fichiers objets (variables et fonctions) ;
- entrée : bibliothéques (variables et fonctions) ;
- sortie : un exécutable (chargé par le système) ;
- entités considérées de gauche à droite ;
- 2 ensembles : symboles collectés, symboles indéfinis ;
- si l’entité est un fichier objet F :
-
les symboles exportés par F sont :
-
ajoutés aux symboles collectés ;
- retranchés des symboles indéfinis.
- erreur si un même symbole est collecté deux fois ;
- les symboles importés par F sont :
-
ajoutés aux symboles indéfinis ;
- sauf si présents comme symboles collectés.
- si l’entité est une bibliothèque B :
-
chaque objet de la bibliothèque est considéré ;
- si l’objet exporte un symbole indéfini, on le traite ;
- oubli des objets n’exportant aucun symbole indéfini ;
- si la liste des symboles indéfinis est modifiée ...
- ... la bibliothèque est examinée à nouveau.
- quand il ne reste plus d’entité à analyser :
-
erreur s’il reste des symboles indéfinis ;
- sinon l’exécutable est créé :
-
les sections de même nom sont agrégées ;
- les agrégats de même type sont agrégés ;
- une adresse est affectée à chaque agrégat ;
- les références aux symboles sont calculés.
- Création d’une bibliothéque : commande ar
- Exercice "programme sans main" :
-
écrivez un programme sans fonction main ;
- tentez de le compiler, que se passe-t-il ?
- en utilisant l’option -v de gcc ...
- ... trouvez où se cache le symbole _start.
- Exercice "compilation séparée" :
-
reprenez le programme multiplier.c ;
- séparez les deux fonctions dans 2 fichiers ;
- fabriquez les deux fichiers objets ;
- générez l’exécutable avec les deux objets ;
- l’ordre des objets est-il important ?
- Exercice "ma première bibliothèque" :
-
créez une bibliothèque pour la fonction multiplier ;
- compilez le fichier restant avec la bibliothèque ;
- l’ordre entre l’objet et la bibliothèque est-il important ?
- créez une fonction puissance utilisant multiplier ;
- créez une bibliothèque pour la fonction puissance ;
- modifiez le main pour utiliser puissance ;
- compilez le fichier avec les deux bibliothèques ;
- l’ordre des bibliothèques est-il important ?
- Exercice "mais en pratique, il fait quoi ld ?" :
-
repartez du programme "piste noire" (copié sous le nom embryon.c) ;
- encapsulez l’appel assembleur dans la fonction sortir ;
- dans un fichier ecrire.c créez une autre fonction ;
- la fonction ecrire qui affiche une chaîne de caractères ...
- ... en utilisant l’appel système write (code 0x04 en 32 bits et code 1 en 64 bits) ;
- dans la fonction _start appelez ecrire avant sortir ;
- compilez séparément les deux sources C en ...
- ... utilisant les options pour réduire le nombre de sections ;
- utilisez readelf -x pour afficher les sections .text ;
- que remarquez vous pour le fichier objet embryon.o ?
- utilisez objdump -d pour désassembler le code de embryon.o ;
- utilisez readelf -r pour afficher les repositionnements ;
- pointez les repositionnements dans le code ;
- trouvez l’agrégation effectuée par ld (utilisez readelf -l) ;
- intuitez les déplacements des sections .text et .rodata ;
- comparez avec la réalité (utilisez readelf -s sur l’exécutable) ;
- avec ces données effectuez manuellement les repositionnements ;
- comparez avec la réalité (utilisez objdump -d sur l’exécutable).
- Exercice "mieux contrôler ld" :
-
lancez ld avec l’option -verbose ;
- comprenez-vous d’où vient le nom du point d’entrée ?
- comprenez-vous d’où vient le décalage du premier segment ?
- écrivez un script plus simple pour ld ...
- en vous basant sur http://sourceware.org/binutils/docs/ld/ ;
- changez le nom du point d’entrée, supprimez le décalage ;
- liez votre programme en utilisant ce script.