Logiciels Libres et Systèmes Embarqués


B.3. Méthode "artisanale"

Cette méthode est "artisanale" dans le sens où il faut modifier à la main ses sources d'origines pour que le programme puisse fonctionner. Prenons le code de Prog1 ci-dessous :

int add(int a, int b)
{
    return a+b;
}

int main(void)
{
    while(1);

    return 0;
}

Ce code est très simple, puisqu'il ne fait rien ! Ce qui est intéressant, c'est la fonction add. Je vais faire en sorte que le processus Prog0 puisse l'appeler alors qu'elle est contenue dans Prog1. Cela signifie qu'il faudra bien évidemment que les deux processus résident en mémoire.

Pour connaître l'adresse de add, on doit utiliser les utilitaires des Binutils (ce sur quoi se base GCC). Dans un premier temps, il faut compiler le projet Prog1. Une fois cela terminé, il faut exécuter la commande suivante :

bash# powerpc-eabi-readelf -s Prog1/executable.elf|grep add
    42: 01000000    56 FUNC    GLOBAL DEFAULT    1 add

La commande readelf -s affiche la table des symboles d'un programme. Etant donné qu'elle est très longue, je la filtre avec la commande grep. On peut alors voir que la fonction add est à l'adresse 0x01000000, c'est à dire en début de l'espace d'adressage du processus Prog1.

Il suffit alors de préciser dans le code source de Prog0 que la fonction add se situe à cette adresse. On déclare pour cela un pointeur de fonction que l'on initialise avec 0x01000000. Ainsi le code de Prog0 se présente de la manière suivante :

int main(void)
{
    int c = 0;
    int (* add)(int a, int b);

    add = 0x01000000;
    c = add(13, 2);

    while(1);

    return 0;
}

Il ne reste plus qu'à compiler Prog0, et à charger les deux programmes en mémoire. On peut alors voir avec GBD que c=15 après l'appel à la fonction add. Cependant, on peut s'apercevoir qu'on ne peut pas déboguer (facilement) cette fonction car le débogueur ne connaît pas son code source. Le solution serait d'utiliser la commande add-symbole-file, comme on l'a déjà vu dans les sections 4.8 et 5.13.

B.3.1. Synthèse

Il y a deux inconvénients majeurs à cette méthode :

  • il faut connaître l'adresse de la fonction partagée, ce qu'il veut dire qu'il faut compiler dans un premier temps un programme puis modifier l'autre ce qui rend cette technique difficile pour de grands projets. En revanche, la mise en oeuvre est très rapide pour de petits projets.
  • lors du débogage du processus Prog0, le débogueur de Xilinx ne sait pas que le source de la fonction est disponible dans l'autre projet, ce qui veut dire qu'on ne peut pas déboguer facilement les fonctions partagées par l'autre projet.