Le langage SMS est exclu sur les forums ProgBoards, tout message ne respectant pas la charte sera déplacé, modifié, ou supprimé par nos modérateurs.

Forum Langages » Assembleur » problème de linkage

Amwus
ProgBoarder
Citer - Posté le 14/08/2005 à 18:42
Bonjour !
Voila, en liant les différents fichiers objets obtenus par compilation avec g++ et nasm, j'arrive à un certain nombre d'erreurs alors que la compilation indépendante des fichiers ne me donne pas d'erreur. Apparement, certaines fonctions ne sont pas accessibles par d'autres ! Voila ce que j'obtient lors du linkage :


amwus@armada1750:~/DATA/Programmation/ASM/OS/src$ ld --oformat binary -Ttext 1000 fct_aff.o fct_ports.o kernel.o kstart.o -o kernel.bin
ld: AVERTISSEMENT: ne peut trouver le symbole d'entrée _start; utilise par défaut 0000000000001000
fct_aff.o(.text+0x36): In function `objAff::setcursor(int, int)':
: undefined reference to `objPort::outportb(unsigned int, unsigned char)'
fct_aff.o(.text+0x51): In function `objAff::setcursor(int, int)':
: undefined reference to `objPort::outportb(unsigned int, unsigned char)'
fct_aff.o(.text+0x6c): In function `objAff::setcursor(int, int)':
: undefined reference to `objPort::outportb(unsigned int, unsigned char)'
fct_aff.o(.text+0x8d): In function `objAff::setcursor(int, int)':
: undefined reference to `objPort::outportb(unsigned int, unsigned char)'
kstart.o(.text+0x1): In function `start':
: undefined reference to `kmain'
fct_aff.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
kernel.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'



Qqun peut il m'aider à résoudre le problème ? Je rappelle que les sources actuelles se trouvent là : http://neosoft.amw.free.fr/os

Merci (clein d'oeil)
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore
Strixouney
Visiteur
RemonterCiter - Posté le 14/08/2005 à 20:33
en C, lorsqu'on exporte une fonction, elle est accessible en asm à condition de rajouter un _ devant.
Ainsi, si tu à une fonction genre
void maFonction(void);

Pour l'appeler en asm, il faudra :
EXTERN _maFonction
et non EXTERN maFonction

De même, pour que les fonctions asm soit correctement exporté, il me semble quellent doivent commencé par un _ pour pouvoir être appelé depuis une fonction en C (j'en suis plus sur, à vérifier donc).
Ainsi, ta fonction start doit dans ton fichier asm s'appeler _start.
Par contre, dans le fichier C, au contraire, tu dois enlever le _, et donc appeler 'start', et non '_start'

En espérant avoir été clair (ce qui je crois, n'est pas le cas ! mdr)
amwus
Visiteur
RemonterCiter - Posté le 14/08/2005 à 22:55
donc si je veux a partir de mon fichier kstart.asm appeler une foncion kmain qui se trouve d smon fichier kernel.cpp, je dois appeler en faisait EXTERN _kmain() c ca ?

Et pr mes fonctions de chaines de caract, toutes les fonctions asm doivent commencer par _ comme par ex _strlen() c ca ? J'essaierai ca ce soir (sourire)

merci
Amwus
ProgBoarder
RemonterCiter - Posté le 15/08/2005 à 10:11
waip ben ca n'a pas marché lol. Mon fichier kstart.asm débute à l'adresse 0x1000 et il appelle les diverses fonctions de fichier kernel.cpp

La fonction principale étant main, je fais donc ds le fichier asm :


[BITS 32]
[global start]
[extern _main]

start:
call _main
...



et la ca ne fonctionne pas lol...
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore
Strixouney
Visiteur
RemonterCiter - Posté le 15/08/2005 à 13:00
Bon alors, on commence par le lien : http://f.dorin.free.fr/os.tar

Ensuite, les explications du pourquoi ca marchait pas :
1) Le kernel est en C++, et non en C. Le truc avec _ ne marche que pour le C. En C++, c'est plus compliqué, à cause de la surcharge des fonctions.
Si on gardait le même système qu'en C, toutes les fonctions surchargées pointeraient vers la même fonctions dans le fichier en asm !
Je n'explique par les détails de la génération des noms de fonctions et de variables en C++, car je ne sais moi-meme pas les générés. J'utilise "objdump -t" puis je cherche ce qu'il me faut !

2) Les fonctions INLINE doivent se trouver, non pas dans un fichier .cpp, mais bel et bien de l'header .h ! En effet, les fonctions INLINE sont automatiquement remplacées. C'est une sorte de macro, mais avec la vérification du typage. Si tu mets ca dans un fichier .cpp, lors de la génération du fichier objet, ton fichier sera vide !
Pour que les fonctions soient remplacées, il est nécessaire de mettre le code des fonctions inline dans le fichier .h.
Petite note au passage : les fonctios inline sont les seules dont le code doit apparaitre dans un fichier .h. Ce n'est pas faut de mettre le code d'une fonction non inline, mais bon, c'est pas propre.

3) Dans le tar, il y a un petit fichier makefile, fait vite fait mal fait.
- make clean pour virer les fichiers .o
- make pour créer kernel.bin

4) Il faut définir un point d'entré, grace à l'option -e ou --entry
parce que sinon, bah c'est pas bon !

5) j'ai virer le --oformat binary, car chez moi, cela me créer des erreur (bon, je suis sous cygwin aussi (langue))

6) je crois que c'est tout ^^

Bonne programmation !
Amwus
ProgBoarder
RemonterCiter - Posté le 16/08/2005 à 10:14
merci !
Tu crois donc que c'est possible que ca déconne juste par le fait que ce soit du c++ ? Dans ce cas, je peux décider de ne pas passer par un "chargeur de noyau" en asm et directement linker le fichier kernel en lui indiquant l'adresse de démarrage avec -Ttext 1000 non ? Mais alors j'ai d'autres problèmes de linkage avec les autres fonctions c++ qui sont ds les autres fichiers. Mais ça ne relève plus de l'asm je v donc poster un message dans la zone c++ (clein d'oeil)

Je vais aller voir ton fichier (sourire)

Merci pr ces renseignements (sourire)

Amwus
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore
Amwus
ProgBoarder
RemonterCiter - Posté le 16/08/2005 à 10:40
Bon j'ai repris l'archive (j'avais pas capté que ct mon os lol), et j'ai effectué quelques modif sur l'"original" (clein d'oeil)

Mais il y a des trucs que j'ai pas compris. Notamment ton histoire de fonction que tu appelle Z5 je ne sais plus quoi ! Tu l'appelle ou celle la ds le kernel C ou CPP ?

Toujours est il que je n'ai plus le problème des fonctions inline, c corrigé (merci Strixounet (clein d'oeil) ) mais pr l'instant, j'ai toujours un fichier kernel.cpp et c tout lol. Et donc, kstart ne me charge pas le noyau lol (clein d'oeil)

voici donc je que j'obtiens :


ld --entry start -Ttext 0x1000 kstart.o kernel.o fct_aff.o -o kernel.bin
kstart.o(.text+0x1): In function `start':
: undefined reference to `_main'
kernel.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
fct_aff.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'



J'ai réactualisé mon code à http://neosoft.amw.free.fr/os

tu peux jeter un oeil stp ? Merci (clein d'oeil)


Edité par Amwus (16/08/2005 10:46:33)
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore
Strixouney
Visiteur
RemonterCiter - Posté le 16/08/2005 à 16:58
En fait, Z5kstart... correspond à ta fonction kmain défini dans le fichier kernel.cpp. Mais comme je te l'ai dis plus haut, l'interfacage entre asm/c++ est chiant, car les noms ne sont pas simple, à cause de la surcharge possible des fonctions.

par exemple, en C++ tu peux déclarer :
void maFonction(int);
void maFonction(string);

Ainsi, tu peux appeler une fonction agissant sur 2 types d'objet différent. Ceci grace au typage.. En fait, de cette manière tu définit 2 fonctions porttant le même nom. Le choix d'une fonction ou d'une autre se fera au niveau du code grace au type des arguments.

En Asm, pas de typage, pas de surcharge. Les 2 fonctions ne peuvent donc pas avoir le même nom. Ainsi, une fonction dont le nom est simple en C++ sera compliqué en asm.

Pour en revenir à ton code, dans kernel.cpp, j'ai pas compris le coup de kmain qui appelle juste main. Ca ne sert à rien. Appelle directement kmain dans le fichier asm kstart.asm et tout roule ! Regarde ce que j'ai fait dans l'archive (exclamation) (héhé

Normalement, pas mal d'erreur devrait disparaitre. Sauf peut-etre :
kernel.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
fct_aff.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
qui doivent provenir de fonction appeler à l'ainsu du plein gré du programmeur. Je ne sais pas comment t'en débarrasser. Si jamais j'ai le temps je regarde, mais la ca va etre chaud....
Amwus
ProgBoarder
RemonterCiter - Posté le 16/08/2005 à 17:48
oki je vais essayer ca. Mais si je veux appeler la fonction main du cpp, je dois donc faire ca :

CALL Z5main

?
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore
Strixouney
Visiteur
RemonterCiter - Posté le 16/08/2005 à 21:39
regarde avec l'utilitaire objdump.
Tappe objdump -t kernel.o

Cela te donnera la liste des liens exportés. Tu pourra alors reconnaitre le lien qui s'apparente à la fonction main...
Amwus
ProgBoarder
RemonterCiter - Posté le 17/08/2005 à 09:12
oki... Ce objdump fonctionne sous linux aussi ? Bah de toute façon je v pas tarder à etre fixé lol (clein d'oeil)

Merci
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore

Poster une réponse

STOP aux fautes volontaires !
Message
Formatage
Note: pour partager du code source, merci d'utiliser le wall !
Smileys (sourire) (yekyek) (clein d'oeil) (désapprouve) (triste) (cool) (langue) (confus) (gêné) (neutre) (eek) (surpris) (diable) (flèche) (exclamation) (question) (diable) (idée) (méchant)
Pseudonyme
Recopiez le code
v6 © Computaid SPRL 2005-2008 - Tous droits réservés - Hébergé par eTigris - Page générée en 0,047 s - Crédits - Stats
1 connecté