Pour compiler un programme au format ELF, il n'y a rien de spécial
à faire : utilisez gcc
comme d'habitude. Pour obtenir
un binaire a.out
, utilisez gcc -b i486-linuxaout
.
$ cat >hello.c
main() { printf("Hello, world.\n"); }
^D
$ gcc -o hello hello.c
$ file hello
hello: ELF 32-bit LSB executable i386 (386 and up) Version 1
$ ./hello
Hello, world.
Certains doivent se poser la question suivante : " si les
compilateurs a.out
produisent par défaut un programme
nommé a.out
, quel est le nom utilisé par les versions
ELF dans ce cas ?". Eh bien, c'est toujours a.out
.
Dur, dur :-)
Pour créer libtoto.so sous forme de bibliothèque partagée, les étapes à suivre se présentent comme suit :
$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname,libtoto.so.1 -o libtoto.so.1.0 *.o
$ ln -s libtoto.so.1.0 libtoto.so.1
$ ln -s libtoto.so.1 libtoto.so
$ export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
Une bibliothèque partagée nommée libtoto.so.1.0
sera générée,
ainsi que les liens appropriés pour que ld (libtoto.so
) et
l'éditeur de liens dynamiques (libtoto.so.1
) puissent la
trouver. Pour les tests, nous ajoutons le répertoire courant à
LD_LIBRARY_PATH
.
Lorsque la bibliothèque est bien au point, vous devez la déplacer
dans (par exemple) /usr/local/lib
, et recréer les liens
nécessaires. Notez que le lien libtoto.so
doit pointer sur
libtoto.so.1
, de cette façon il ne sera pas nécessaire de
le mettre à jour à chaque changement de numéro mineur de la
version de la bibliothèque. Le lien de libtoto.so.1
vers
libtoto.so.1.0
est maintenu à jour par ldconfig
, qui est
exécuté lors du démarrage du système dans de nombreuses installations
de Linux.
$ su
# cp libtoto.so.1.0 /usr/local/lib
# /sbin/ldconfig
# ( cd /usr/local/lib ; ln -s libtoto.so.1 libtoto.so )
Le sujet est couvert avec beaucoup de détails dans le document
sur la programmation ELF de H.J. Lu, ainsi que dans la page de
manuel de dlopen(3)
, que l'on trouve dans le paquetage
ld.so
. Voici toutefois un petit exemple : faites
l'édition de liens avec l'option -ldl
.
#include <dlfcn.h>
#include <stdio.h>
main()
{
void *libc;
void (*appel_printf)();
if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
{
appel_printf=dlsym(libc,"printf");
(*appel_printf)("Salut, patron.\n");
}
}
Simple et explicite, n'est-ce-pas ? Pour ceux qui feraient un blocage,
voici comment compiler cet exemple, et le résultat de son exécution :
plux:/tmp $ cc truc.c -o truc -ldl
plux:/tmp $ ./truc
Salut, patron.
La version de gdb
que vous avez coutume d'utiliser devrait
fonctionner avec les programmes ELF. La nouvelle version se trouvant
dans le répertoire GCC
des sites archive Linux, est toutefois
conseillée. Elle permet de déboguer les programmes utilisant le
chargement dynamique, et comprend les core dump
ELF.
Notez que les noyaux de la série 1.2 ne peuvent pas générer de core dumps ELF. Pour cela, il vous faut une version 1.3.
Chapitre suivant, Chapitre Précédent
Table des matières de ce chapitre, Table des matières générale
Début du document, Début de ce chapitre