Passage d’arguments GCC != SAS/C

8 sujets de 1 à 8 (sur un total de 8)

  • Gofromiel

      #4372

      Afin de faciliter le portage, je suis en train de passer la version 68k de Feelin sous GCC. Tout allait pour le mieux jusqu’à ce que, horreur et crème de banane, la démo « thread » me pose des problèmes:

      07-Jan-30 18:07:28 [test.thread] Thread{1046DD8C}.Send> thread_main: Obj (0x1046DD8C), userdata (0x104632DC)

      07-Jan-30 18:07:28 [test.thread] Thread{1046DD8C}.Send> entry(0x1046DD8C, 0x104632DC, 0x1046DD8C)

      07-Jan-30 18:07:28 [test.thread] Thread{1046DD8C}.Send> Thread_Main(0x10427C60, 0x1046E0C8, 0x1046DD8C)

      07-Jan-30 18:07:28 [test.thread] Thread{1046DD8C}.Send> (db)F_DoA() 0x10427C60 is not an Object !! Class 0x61727900 - Method 0xD0000041 (Pop)

      07-Jan-30 18:07:28 [test.thread] Thread{1046DD8C}.Send> waiting...

      07-Jan-30 18:07:28 [test.thread] Thread{1046DD8C}.Send> (db)F_DoA() 0x10427C60 is not an Object !! Class 0x61727900 - Method 0xD0000042 (Wait)

      07-Jan-30 18:07:28 [test.thread] Thread{1046DD8C}.Send> (db)F_DoA() 0x10427C60 is not an Object !! Class 0x61727900 - Method 0xD0000041 (Pop)

      07-Jan-30 18:07:28 [test.thread] Thread{1046DD8C}.Send> waiting...

      Après une demi-heure à me pourquoi les arguments reçus pas Thread_Main() ne corresponde pas à ceux passés, je tente une recompilation de la démo par GCC, c’est la stupéfaction:

      07-Jan-30 07-Jan-30 NEW SESSION ***

      07-Jan-30 18:16:56 [test.thread] Thread{105D45B4}.Send> thread_main: Obj (0x105D45B4), userdata (0x10650C3C)

      07-Jan-30 18:16:56 [test.thread] Thread{105D45B4}.Send> entry(0x105D45B4, 0x10650C3C, 0x105D45B4)

      07-Jan-30 18:16:56 [test.thread] Thread{105D45B4}.Send> Thread_Main(0x105D45B4, 0x10650C3C, 0x105D45B4)

      07-Jan-30 18:16:56 [test.thread] Thread{105D45B4}.Send> Msg 0x10650A82 - Action 0xFFFFFFFE

      07-Jan-30 18:16:56 [test.thread] waiting...

      07-Jan-30 18:16:56 [test.thread] waiting...

      07-Jan-30 18:17:01 [test.thread] Msg 0x10650AEE - Action 0xFFFFFFFF

      07-Jan-30 18:17:01 [test.thread] bye

      07-Jan-30 18:17:01 [test.thread] THREAD_MAIN: EXIT - process (0x106AB6A8) thread port (0x105D7E28) >> BEGIN

      07-Jan-30 18:17:01 [test.thread] THREAD_MAIN: EXIT - FLUSH MSG PORT

      07-Jan-30 18:17:01 [test.thread] THREAD_MAIN: EXIT - RELEASE ARBITER

      07-Jan-30 18:17:01 [test.thread] DEATH MSG (0x10650AEE)

      07-Jan-30 18:17:01 [test.thread] .0xD0000042> THREAD_MAIN: EXIT - PURGE THREAD PORT: port (0x105D7E28)

      07-Jan-30 18:17:01 [test.thread] .0xD0000042> THREAD_MAIN: EXIT >> DONE

      Ben voilà, là ça marche parfaitement ! Est-ce que quelqu’un pourrait m’expliquer pourquoi le passage d’arguments ne se fait pas de la même façon entre GCC et SAS/C ? Ce qui est très ennuyeux !! :'(

      Une solution serait également la bienvenue. :-D

      Merci Ô dieux de la programmation !

      henes

        #75861

        Par défaut, SAS/C passe les arguments sur la pile et GCC (68k) par des registres.

        Gofromiel

          #75862

          Crotte bleu ! Bêtement j’imaginais que si le code était « extérieur » il passait les arguments par la pile… il va donc falloir que je force le passage par les registres… Pff c’est moche pour la portabilité :-( En même temps je peux utiliser des registres pour m68k et laisser tel quel pour les autres, vu qu’ils compilent tous avec GCC. Heureusement la définition de la fonction d’entrée du Thread est une macro 8-)

          Merci Henes !! T’es le plus beau (de loin) ! ;-)

          henes

            #75863

            Très mauvaise idée.

            Cela voudrait dire que la lib 68k utiliserait l’ABI X, que le programme PPC utiliserait l’ABI Y et que les deux ne marcheraient pas ensemble.

            Pareil avec une lib PPC et un prog 68k.

            Deux solutions :

            1) Toujours tout passer par la pile 68k. Mais cela oblige à utiliser je ne sais plus quel argument de GCC pour générer ce genre de code. De plus cela oblige à un peu bidouiller les programmes PPC qui iront manipuler ces arguments (et aux dernières nouvelles sur utilitybase, ils n’ont toujours pas trouvé comment faire sur hyperos alors que c’est pourtant super simple…)

            2) Toujours tout passer par les registres 68k. Les manipuler depuis les OSes PPC est très simple.

            Eloigne toi vite de ton écran maintenant et admire.

            centaurz

              #75864

              1) Toujours tout passer par la pile 68k. Mais cela oblige à

              utiliser je ne sais plus quel argument de GCC pour générer ce genre de code. De plus cela oblige à un peu bidouiller les programmes PPC qui iront manipuler ces arguments (et aux dernières nouvelles sur utilitybase, ils n’ont toujours pas trouvé comment faire sur hyperos alors que c’est pourtant super simple…)

              mé… tous les appels systèmes se font de cette manière sous OS4…

              @ gofromiel

              avec GCC, le mot clé magique est VARARGS68K pour passer les arguments dans la pile.

              henes

                #75865

                mé… tous les appels systèmes se font de cette manière sous OS4…

                Non. Depuis le ppc, les appels se font via une version modifiée de l’abi sysv. Le premier entier est dans r4 au lieu de r3, le 2e dans r5 au lieu de r4, etc… et je ne sais plus quel argument caché est passé dans r3 (la libbase ?).

                avec GCC, le mot clé magique est VARARGS68K pour passer les arguments dans la pile.

                C’est un define qui cache la véritable extension apportée au gcc hyperos. Extension qui n’existe pas dans le gcc 68k de gofromiel.

                Et de toute façon, un tel exe passe une vararg par la pile ppc. Ce qui n’aide pas trop à récupérer tout argument passé sur la pile 68k :-)

                Pour cela il faut aller jouer avec le a7 émulé.

                Alex

                  #75866

                  et je ne sais plus quel argument caché est passé dans r3 (la libbase ?).

                  Je ne sais pas si c’est dans r3 ou ailleurs, mais l’argument « caché » c’est l’interface à laquelle appartient la fonction appellée. D’ailleurs je ne sais pas si c’est également le cas pour les fonctions « internes » à son code (i.e. quand on fait pas appel à des fonctions appartenant à une interface), je n’ai pas désassemblé mes progs (et puis ça m’avancerait pas beaucoup je n’y connais rien en ASM PPC ;-)

                  Et de toute façon, un tel exe passe une vararg par la pile ppc. Ce qui n’aide pas trop à récupérer tout argument passé sur la pile 68k :-)

                  Je ne comprends pas trop ce que tu veux dire :-? mais toujours est-il qu’il est possible de récupérer le tout (plutôt que un à un) en utilisant va_startlinear()/va_getlinearva() plutôt que va_start()/va_arg().

                  henes

                    #75867

                    D’ailleurs je ne sais pas si c’est également le cas pour les fonctions « internes » à son code (i.e. quand on fait pas appel à des fonctions appartenant à une interface)

                    Je crois que cela concerne uniquement les fonctions dont le prototype est décoré avec l’hyperionesque extention « LIBCALL » ou quelque chose de similiaire.

                    Les autres utilisent sans doute l’abi naturelle du compilateur. Donc sysv.

                    Je ne comprends pas trop ce que tu veux dire mais toujours est-il qu’il est possible de récupérer le tout (plutôt que un à un) en utilisant va_startlinear()/va_getlinearva() plutôt que va_start()/va_arg().

                    Normalement, ce genre d’extension a uniquement été introduit pour facilement adapter les sources passant les arguments de leur taglist via une vararg.

                    Les contraintes d’alignement de la pile étant différentes pour 68k et ppc, je ne sais pas s’il est possible de l’utiliser dans hyperos pour faire ce que gofromiel avait à l’esprit.

                    Et il faudrait que la même pile soit utilisée par les codes 68k et ppc, comme c’est le cas dans warpup. Ce qui expliquerait que tous les programmes 68k plantent hyperos lorsqu’on ne les lance pas avec une pile plus importante que celle pour laquelle ils ont été conçus, au passage :-)

                    En tout cas, le plus simple et compatible reste d’implémenter cela comme les hooks : les arguments dans des registres 68k et voilà.

                  8 sujets de 1 à 8 (sur un total de 8)

                  • Vous devez être connecté pour répondre à ce sujet.

                  Forums AmigaOS, MorphOS et AROS Développement Passage d’arguments GCC != SAS/C

                  Amiga Impact