fx-CG50 Manager PLUS - gdbserver : débuggez vos add-ins et CASIOWIN
Posté le 05/12/2020 23:57
En voulant effectuer de la rétro-ingénierie sur l'OS de ma GRAPH90+ E ( ne me demandez pas pourquoi, même moi je ne sais pas ), je me suis retrouvé plusieurs fois à patcher l'OS et à le reflasher sur ma calculatrice pour valider des théories sur le fonctionnement de celui-ci. Ce processus est plutôt dangereux pour des tas de raisons ( coupure de courant durant le flash, usure excessive de la flash, modifier un bout de code qu'il ne fallait pas qui mène à la corruption du bootloader, etc. ) or comme je ne me vois pas avec un fer à souder pour réparer tout ça, je me suis lancé dans le développement de cet outil.
Il s’agit d'une DLL qui remplace CPU73050.dll de fx-CG50 Manager PLUS et qui implémente les fonctions de base du GDB remote serial protocol. Il devient alors possible d'utiliser GDB pour débugger CASIOWIN mais aussi des add-ins sans abimer utiliser de matériel.
Comme indiqué sur le repo GitHub, il manque encore beaucoup de fonctionnalités importantes ( comme écrire en mémoire et donc placer des breakpoints à l’exécution ) mais la base est là et je poste donc ici pour voir si des gens sont intéressés ( ou si quelque chose de similaire existe déjà et donc que je viens de passer 2 semaines sur un projet inutile ).
Pour ceux intéressés mais qui ne veulent pas mettre en place tout l’environnement nécessaire, j'ai mis une très simple vidéo de démo sur Youtube qui montre ce qui fonctionne à ce jour ( lecture de la mémoire, lecture et écriture des registres ainsi que l'arrêt sur des breakpoints intégrés dans l'add-in à l'avance ).
Le debug ne marche pas pour le moment.
En suivant les conseils de Lephenixnoir, j'ai cree un elf puis un binaire (au lieu d'un binaire directement), puis l'addin
Au passage, j'ai gagne 5K de taille sur l'addin, je ne sais pas trop pourquoi mais c'est une excellente nouvelle (je vais pouvoir publier une mise a jour alpha de KhiCAS qui double la taille du tas en utilisant un allocateur custom).
Donc ensuite je lance casioemu, je transfere khicas.g3a dans l'emulateur, je lance sh3eb-elf-gdb, puis target remote localhost:31188, puis file khicas.elf puis b run, puis cont et la paf erreur il ne veut pas inserer le breakpoint, voici l'output de gdb
(gdb) target remote localhost:31188
Remote debugging using localhost:31188
[fxCG50gdb] recv <- qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+
[fxCG50gdb] send -> PacketSize=255
[fxCG50gdb] recv <- vMustReplyEmpty
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- Hg0
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- qTStatus
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- ?
[fxCG50gdb] send -> S05
[fxCG50gdb] recv <- qfThreadInfo
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- qL1200000000000000000
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- Hc-1
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- qC
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- qAttached
[fxCG50gdb] send -> ((empty))
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
[fxCG50gdb] recv <- g
[fxCG50gdb] send -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxA0000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[fxCG50gdb] recv <- qL1200000000000000000
[fxCG50gdb] send -> ((empty))
0xa0000000 in ?? ()
(gdb) file khicas.elf
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from khicas.elf...
[fxCG50gdb] recv <- qSymbol::
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- g
[fxCG50gdb] send -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxA0000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(gdb) b run
[fxCG50gdb] recv <- m310718,2
[fxCG50gdb] send -> ((empty))
Breakpoint 1 at 0x310718: file main.cc, line 1591.
(gdb) cont
Continuing.
[fxCG50gdb] recv <- Z0,310718,2
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- m310718,2
[fxCG50gdb] send -> ((empty))
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x310718
Au cas ou, je mets mon archive source de giac ici
Ajouté le 14/12/2021 à 09:03 :
Update: ca a l'air de marcher avec hbreak au lieu de break
Au passage, j'ai gagne 5K de taille sur l'addin, je ne sais pas trop pourquoi mais c'est une excellente nouvelle (je vais pouvoir publier une mise a jour alpha de KhiCAS qui double la taille du tas en utilisant un allocateur custom).
Sans doute la section .bss. Vérifie que ça marche toujours sur ta calto mais si oui alors ouais c'est gratuit.
Tant mieux si ça marche ! Je ne suis pas hyper familier avec le protocole GDB, idéalement en cas de problème il faudrait voir avec Redoste.
Ca marche sur l'emulateur en tout cas, je vais essayer sur une vraie calculatrice, mais il n'y a pas de raison...
Donc j'ai un peu essaye gdb (dans un emacs), l'emulation est effectivement tres lente, et comme je suis oblige de compiler avec -Os pour ne pas depasser la taille maxi de l'addin, c'est loin d'etre aussi pratique que par exemple le debug sur l'emulateur arm de ti nspire cx (ou le simulateur de Numworks), mais ca devrait quand meme etre tres utile pour debugger des crash specifiques a casio (et il y en aura forcement parce que l'UI n'est plus la meme que sur Nspire ou Numworks ou on n'a pas de contrainte forte sur la taille du code).
Oui ça devrait marcher sur la calculatrice, c'est juste un formalité en principe. C'est surtout que si jamais il y a un bug là il serait difficile à trouver plus tard, donc autant tester immédiatement.
Si tu arrives à couper ton add-in en deux et à le charger sur le RAM, tu auras peut-être assez de marge pour compiler avec -O0 ? Quelle taille ça fait si tu enlèves -Os actuellement ?
Ah oui c'est vrai qu'il y a ça aussi ! Compiler avec -ffunction-sections permet aussi de gagner en combinaison avec --gc-sections s'il y a des fonctions non utilisées. Par contre faut surveiller le linker script au cas où il ne soit pas pensé pour ça (celui du PrizmSDK l'est IIRC).
Lephenixnoir a écrit : Ah oui c'est vrai qu'il y a ça aussi ! Compiler avec -ffunction-sections permet aussi de gagner en combinaison avec --gc-sections s'il y a des fonctions non utilisées. Par contre faut surveiller le linker script au cas où il ne soit pas pensé pour ça (celui du PrizmSDK l'est IIRC).
oui c'est vrai, mais Bernard a déjà activé cette option de GCC/G++ donc j'en ai pas parlé ;-)
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
En effet, je suis a 2860209 octets maintenant, donc presque 11000 de marge, merci! Resultat: https://www-fourier.univ-grenoble-alpes.fr/~parisse/tmp/khicas.g3a
De quoi pouvoir envisager compiler au moins 1 ou 2 fichiers sans -Os pour aider a debugger une fois un bug repere.
Ajouté le 14/12/2021 à 13:37 :
Par contre si on met -O0 au lieu de -Os, l'addin ferait plus que 4M
Non sans mal j'ai réussi à installer la toolchain de Bernard sur ma machine (Ubuntu 20.03) et réussi à recompiler Khicas/Khicasen pour les amener sous les 2048Ko fatidique.
La toolchain de Bernard basée sur gcc 7.3.0 donne des tailles de 1.98M (2.081.908 octets pour khicas.g3a et 2.079.520 octets pour khicasen.g3a).
Ma toolchain usuelle basée sur gcc 11.1.0 donne un khicas.g3a de 2.097.152 octets soit tout de même 11Ko d'écart qui serait certainement plus utiles ailleurs, surtout quand chaque octet compte.
j'ai gratté en particulier 5Ko avec l'ajout de "-s -ffast-math" dans la ligne des CXXFLAGS, je ne sais pas si cette seconde option est acceptable dans le cadre de Khicas car elle retire certaines vérifications lors des calculs, mais peut être toujour bonne à prendre.
j'ai essayé de virer le "-g" des LDFLAGS pour mettre "-Os -s", mais cela n'a aucune influence sur la taille des g3a.
Pour info mon makefile est le suivant (j'utilise "make clean; make stepkhicas; make stepkhicasen" comme cibles). Les chemins seront à ajuster selon votre arborescence locale.
Je ne voulais pas proposer de version précompilée car je considère pas vraiment l'outil comme utilisable actuellement mais je suis conscient que j'aurais surement dû mieux détailler les instructions de compilation dans le README.
Pour les intéressés, les étapes (mais expliqué très rapidement) :
Windows avec MSVC
Cliquer pour enrouler
Installer nasm et s'assurer qu'il soit dans le PATH.
Ouvrir fx-CG50_Manager_PLUS-gdbserver.sln dans Visual Studio et cliquer sur Build.
Windows avec mingw
Cliquer pour enrouler
Installer Cygwin avec les paquets ninja, nasm et mingw64-i686-gcc-core
Dans un terminal Cygwin, cd vers le projet puis ninja.
Linux avec mingw
Cliquer pour enrouler
Installer les paquets ninja, nasm et mingw-w64-gcc. (ninja et nasm devraient se trouver dans toutes les distribs mais mingw-w64-gcc peut se nommer différemment. Ce qui compte c'est qu'il y ai le cross compiler i686-w64-mingw32-gcc).
Dans un terminal, cd vers le projet, puis ninja.
Si je trouve le temps j'essayerai de faire une vraie version détaillée pour le README.
Parisse a écrit :
Update: ca a l'air de marcher avec hbreak au lieu de break
En fait hbreak va mémoriser l'adresse du breakpoint et s'arrêter lorsque l'on s'apprête à exécuter une instruction à cet endroit alors que break remplace l'instruction à l'adresse indiquée par une autre qui va appeler le debugger. hbreak est donc plus lent car le debugger devra constamment sauvegarder le contexte de l'émulateur, vérifier si l'adresse est dans la liste des breakpoints, puis restaurer le contexte. break lui n'a pas ce problème mais ne fonctionnera pas si la mémoire qui est mappée à cette adresse change, par exemple du self-modifying code ou (ce qui est surement le cas ici) le changement de la config du MMU avant de lancer l'add-in.
Je recommande donc de placer un hbreak à son entry point puis dès que l'add-in est chargé de le désactiver pour éviter de ralentir encore plus le debugger qu'il ne l'est déjà. À part dans certains cas particuliers, une fois l'add-in chargé il n'y a aucune raison que break ne fonctionne pas.
Ah c'etait avec cygwin que c'etait suppose compiler facilement... moi je suis parti avec une install de mingw!
Personnellement, je ne vois pas de raison de ne pas mettre en ligne un binaire d'un soft en version alpha ou beta, du moment que les gens le savent (surtout la, un cross debugger ca s'adresse a des gens experts), ca leur rend service.
Je vais reessayer avec hbreak puis break, mais il me semble que j'avais tente de mettre le point d'arret une fois l'addin lance
Comme recommandé par Parisse, je viens de mettre en place des prébuilts de la fausse CPU73050.dll, elles sont disponibles dans les releases GitHub et sont construites automatiquement par GitHub Actions, donc il suffit littéralement d'un clic pour en proposer de nouvelle, j'essayerai de le faire à chaque nouvelle feature ou bug fix plutôt important. (Si le projet reprend de l'activité ).
J'ai aussi étoffé le README de manière à ce que les instructions de compilation soient (beaucoup) plus claires et détaillées.
je "up" le sujet car cela fait un moment que je voulais regarder cela et j'avais jamais trop eu de temps à y consacrer.
Je reprends donc la base par rapport à la procédure décrite par B. Parisse pour faire fonctionner GDB avec l'émulateur.
Pour info, ma config de base est remise à plat et propre sur fxsdk / gint dans leur dernières versions actuelles : à savoir 2.9.0 (branches master).
Le fx-CG Manager PLUS est lui dans sa version 3.60.2202.
Pour le début du tuto, à savoir obtenir le SH73050.dll "patché", pas de problème avec la méthode de Parisse, j'ai juste dévié de la méthode en prenant la version de la DLL issue du github de Redoste afin avoir la dernière version. J'ai pris celle de la dernière release pour ne pas avoir à la recompiler.
Bon cette partie est OK.
Maintenant, créer une version de GDB pour architecture SH3.
Alors première "galère", quand on passe par le système GiteaPC, il y a un petit ajustement des noms des outils pour la compilation, à savoir que la ligne
ne passera pas car les outils en standard ne s'appellent pas sh3eb-elf-XXX (par exemple sh3eb-elf-g++) mais sh-elf-XXX
il faut donc convertir la ligne en
Deuxième point, je ne sais pas si Bernard a aussi expérimenté cette déconvenue, le "make" sort sur une erreur dans le fichier 'sh3eb-gdb/sim/sh/targ-map.c' pour le signal "SIGSTKSZ" (ligne 433 du dit fichier). Malheureusement je n'ai pas trouvé de meilleure méthode pour contourner l'erreur que de commenter ce bloc.
le code initial :
après cette modification "à la cochon", le make arrive au bout et génére bien un gbd pour architecture SH en version 11.1.
pour cette partie c'est OK. Juste un petit lien symbolique pour avoir un sh-elf-gdb dans le SDK et zou.... ça roule.
On lance l'émulateur, puis gdb (via donc la commande "sh-elf-gdb" et pas gdb) et on se connecte à l'émulateur via une commande "target remote localhost:31188" : tout roule aussi : juste un petit cri en passant
(gdb) target remote localhost:31188
Remote debugging using localhost:31188
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0xa0000000 in ?? ()
tout à fait normal car je lui ai pas fait de "file".
Donc là il ne reste qu'a tester un petit addin avec les infos de debuggage, donc compilé avec l'option "-g".
mais la ça coince sur la commande file de gdb
toujours le meme message d'erreur :
(gdb) file build-cg/myaddin
Reading symbols from build-cg/myaddin...
(No debugging symbols found in build-cg/myaddin)
(gdb)
C'est balot !! si près du but.
Si quelqu'un a une idée pour déverrouiller cette dernière étape, ce serait cool. Car là je vois pas d'où vient le problème.
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Bon en fait je vois que Bernard a essuyé les plâtres et que a priori la compilation directe "perd" les infos de debug et que le -g ne suffit pas.
Je vais investiguer cela d'un peu plus près
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Ouh non non c'est pas supposé être possible ça. Le nom sh-elf- c'est une distinction cosmétique, la cible c'est un triplet BFD avec un format particulier et des valeurs prédéfinies. Je suis surpris que sh-elf soit même accepté. Quand on compile GCC il faut en effet fournir des liens symboliques pour combler l'écart, mais c'est tout. Ici je ne crois pas que ce soit un problème majeur mais c'est définitivement un truc à surveiller et à considérer en cas de problème.
Ok, bon donc j'ai fait les liens symboliques sh3eb-elf-XXX manquants (effectivement dans l'installation manuelle c'est précisé, mais via GiteaPC ça passe à la trappe).
Et cette fois configure détecte bien les version sh3eb-elf ...
(pour info avec mon --target=sh-elf, il trouvait bien les versions sh-elf-gcc/ar/ld) et il ne me gueulait pas dessus lors du make).
Du coup si je comprends bien pour avoir les infos de debuggage, il faudrait que l'on crée deux cibles différentes pour fxsdk ?
Par exemple pour la CG-50 :
- fxsdk build-cg qui se ferait avec le fxcg50.ld usuel : qui ferait alors un g3a normal (version release dirons nous)
- fxsdk build-cg-dbg qui se ferait avec un fxcg50bdg.ld et qui aurait des règles pour ne pas virer les infos de debug et qui ferait un g3a debug (plus gros mais utilisable avec gdb)
Ce serait automatisable un truc du genre ?
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Du coup si je comprends bien pour avoir les infos de debuggage, il faudrait que l'on crée deux cibles différentes pour fxsdk ?
Ouaip ce serait une façon facile de le faire. On pourrait aussi ne pas mettre ces sections dans /DISCARD/ et les supprimer à la place quand on passe de l'ELF au binaire flat mais c'est moins pratique.
Donc, si je cherche à comprendre un peu plus profondément, pour créer ces fameuses cibles "debug"
Il faudrait que je fasse :
1/ dans fxsdk.sh ( ~/.local/share/giteapc/Lephenixnoir/fxsdk/fxsdk ) :
je dois commencer par créer une cible supplémentaire : par exemple transformer les lignes 130 à 150 pour la partie fxsdk_build()
2/ dans le depot gint je dois mettre la jour les cibles de manière parallèles:
je dois ajouter dans CMakeLists.txt au niveau de la ligne 257 (juste après la cible fxCG50) une nouvelle cible
Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd
Citer : Posté le 14/12/2021 08:56 | #
Le debug ne marche pas pour le moment.
En suivant les conseils de Lephenixnoir, j'ai cree un elf puis un binaire (au lieu d'un binaire directement), puis l'addin
sh3eb-elf-objcopy -O binary -R .bss -R .gint_bss -R .debug_info -R .debug_abbrev -R .debug_loc -R .debug_aranges -R .debug_ranges -R .debug_line -R .debug_str -R.comment -R debug_frame khicas.elf khicas.bin
mkg3a -n basic:Khicas -n internal:KHICAS -V 1.5.1 -i uns:khicasio.png -i sel:khicasio1.png khicas.bin khicas.g3a
Au passage, j'ai gagne 5K de taille sur l'addin, je ne sais pas trop pourquoi mais c'est une excellente nouvelle (je vais pouvoir publier une mise a jour alpha de KhiCAS qui double la taille du tas en utilisant un allocateur custom).
Donc ensuite je lance casioemu, je transfere khicas.g3a dans l'emulateur, je lance sh3eb-elf-gdb, puis target remote localhost:31188, puis file khicas.elf puis b run, puis cont et la paf erreur il ne veut pas inserer le breakpoint, voici l'output de gdb
(gdb) target remote localhost:31188
Remote debugging using localhost:31188
[fxCG50gdb] recv <- qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+
[fxCG50gdb] send -> PacketSize=255
[fxCG50gdb] recv <- vMustReplyEmpty
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- Hg0
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- qTStatus
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- ?
[fxCG50gdb] send -> S05
[fxCG50gdb] recv <- qfThreadInfo
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- qL1200000000000000000
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- Hc-1
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- qC
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- qAttached
[fxCG50gdb] send -> ((empty))
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
[fxCG50gdb] recv <- g
[fxCG50gdb] send -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxA0000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[fxCG50gdb] recv <- qL1200000000000000000
[fxCG50gdb] send -> ((empty))
0xa0000000 in ?? ()
(gdb) file khicas.elf
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from khicas.elf...
[fxCG50gdb] recv <- qSymbol::
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- g
[fxCG50gdb] send -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxA0000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(gdb) b run
[fxCG50gdb] recv <- m310718,2
[fxCG50gdb] send -> ((empty))
Breakpoint 1 at 0x310718: file main.cc, line 1591.
(gdb) cont
Continuing.
[fxCG50gdb] recv <- Z0,310718,2
[fxCG50gdb] send -> ((empty))
[fxCG50gdb] recv <- m310718,2
[fxCG50gdb] send -> ((empty))
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x310718
Au cas ou, je mets mon archive source de giac ici
Ajouté le 14/12/2021 à 09:03 :
Update: ca a l'air de marcher avec hbreak au lieu de break
Citer : Posté le 14/12/2021 09:05 | #
Sans doute la section .bss. Vérifie que ça marche toujours sur ta calto mais si oui alors ouais c'est gratuit.
Tant mieux si ça marche ! Je ne suis pas hyper familier avec le protocole GDB, idéalement en cas de problème il faudrait voir avec Redoste.
Citer : Posté le 14/12/2021 09:54 | #
Ca marche sur l'emulateur en tout cas, je vais essayer sur une vraie calculatrice, mais il n'y a pas de raison...
Donc j'ai un peu essaye gdb (dans un emacs), l'emulation est effectivement tres lente, et comme je suis oblige de compiler avec -Os pour ne pas depasser la taille maxi de l'addin, c'est loin d'etre aussi pratique que par exemple le debug sur l'emulateur arm de ti nspire cx (ou le simulateur de Numworks), mais ca devrait quand meme etre tres utile pour debugger des crash specifiques a casio (et il y en aura forcement parce que l'UI n'est plus la meme que sur Nspire ou Numworks ou on n'a pas de contrainte forte sur la taille du code).
Citer : Posté le 14/12/2021 11:04 | #
Oui ça devrait marcher sur la calculatrice, c'est juste un formalité en principe. C'est surtout que si jamais il y a un bug là il serait difficile à trouver plus tard, donc autant tester immédiatement.
Si tu arrives à couper ton add-in en deux et à le charger sur le RAM, tu auras peut-être assez de marge pour compiler avec -O0 ? Quelle taille ça fait si tu enlèves -Os actuellement ?
Citer : Posté le 14/12/2021 11:21 | #
Je m'incruste un peu, mais ayant aussi qq galère de taille de fichier, j'ai vu que remplacer
-Wl,--print-memory-usage
par
-Wl,--gc-sections,--print-memory-usage
m'a permis de gagner 3Ko.
Je vais essayer la technique de Bernard pour voir si je peux gratter qq kilos supplémentaires.
Citer : Posté le 14/12/2021 11:26 | #
Ah oui c'est vrai qu'il y a ça aussi ! Compiler avec -ffunction-sections permet aussi de gagner en combinaison avec --gc-sections s'il y a des fonctions non utilisées. Par contre faut surveiller le linker script au cas où il ne soit pas pensé pour ça (celui du PrizmSDK l'est IIRC).
Citer : Posté le 14/12/2021 12:06 | #
Ah oui c'est vrai qu'il y a ça aussi ! Compiler avec -ffunction-sections permet aussi de gagner en combinaison avec --gc-sections s'il y a des fonctions non utilisées. Par contre faut surveiller le linker script au cas où il ne soit pas pensé pour ça (celui du PrizmSDK l'est IIRC).
oui c'est vrai, mais Bernard a déjà activé cette option de GCC/G++ donc j'en ai pas parlé ;-)
Citer : Posté le 14/12/2021 13:35 | #
En effet, je suis a 2860209 octets maintenant, donc presque 11000 de marge, merci! Resultat: https://www-fourier.univ-grenoble-alpes.fr/~parisse/tmp/khicas.g3a
De quoi pouvoir envisager compiler au moins 1 ou 2 fichiers sans -Os pour aider a debugger une fois un bug repere.
Ajouté le 14/12/2021 à 13:37 :
Par contre si on met -O0 au lieu de -Os, l'addin ferait plus que 4M
Citer : Posté le 14/12/2021 14:51 | #
oui c'est vrai, mais Bernard a déjà activé cette option de GCC/G++ donc j'en ai pas parlé ;-)
Ah ! Bien vu.
Par contre si on met -O0 au lieu de -Os, l'addin ferait plus que 4M
omg ça passera jamais ça, faudra être sélectif. xD
Citer : Posté le 14/12/2021 18:01 | #
Non sans mal j'ai réussi à installer la toolchain de Bernard sur ma machine (Ubuntu 20.03) et réussi à recompiler Khicas/Khicasen pour les amener sous les 2048Ko fatidique.
La toolchain de Bernard basée sur gcc 7.3.0 donne des tailles de 1.98M (2.081.908 octets pour khicas.g3a et 2.079.520 octets pour khicasen.g3a).
Ma toolchain usuelle basée sur gcc 11.1.0 donne un khicas.g3a de 2.097.152 octets soit tout de même 11Ko d'écart qui serait certainement plus utiles ailleurs, surtout quand chaque octet compte.
j'ai gratté en particulier 5Ko avec l'ajout de "-s -ffast-math" dans la ligne des CXXFLAGS, je ne sais pas si cette seconde option est acceptable dans le cadre de Khicas car elle retire certaines vérifications lors des calculs, mais peut être toujour bonne à prendre.
j'ai essayé de virer le "-g" des LDFLAGS pour mettre "-Os -s", mais cela n'a aucune influence sur la taille des g3a.
Pour info mon makefile est le suivant (j'utilise "make clean; make stepkhicas; make stepkhicasen" comme cibles). Les chemins seront à ajuster selon votre arborescence locale.
CXX = /home/sylvain/opt/Casio/sh3eb-elf/bin/sh3eb-elf-g++
AR = /home/sylvain/opt/Casio/sh3eb-elf/bin/sh3eb-elf-gcc-ar
RANLIB = /home/sylvain/opt/Casio/sh3eb-elf/bin/sh3eb-elf-gcc-ranlib
OBJCOPY = /home/sylvain/opt/Casio/sh3eb-elf/bin/sh3eb-elf-objcopy
RM = /bin/rm
CXXFLAGS = -Os -s -mb -m4a-nofpu -mhitachi -std=c++11 -fpermissive -flto -fno-use-cxa-atexit -fno-strict-aliasing -fno-rtti -fno-exceptions -DHAVE_CONFIG_H -DTIMEOUT -DRELEASE -I. -I/home/sylvain/opt/Casio/sh3eb-elf/include -I/home/sylvain/opt/Casio/sh3eb-elf/include/ustl -DFILEICON -DKMALLOC -DNO_TEMPLATE_MULTGCD -DGIAC_GENERIC_CONSTANTS -fno-zero-initialized-in-bss -ffunction-sections -fdata-sections -ffast-math
LDFLAGS = -g -static -nostdlib -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -Tprizm.ld -Wl,--gc-sections,--print-memory-usage
LIBS = -L. -L/home/sylvain/opt/Casio/sh3eb-elf/lib -Wl,--gc-sections,--start-group -lgui -lcas -ltommath -lustl -lm -lc -lgcc -Wl,--gc-sections,--end-group
CAS_OBJS = ksym2poly.o kgausspol.o kthreaded.o kcsturm.o kmaple.o krpn.o kmoyal.o kmisc.o kpermu.o kdesolve.o input_parser.o ksymbolic.o index.o kmodpoly.o kmodfactor.o kezgcd.o kderive.o ksolve.o kintg.o kintgab.o klin.o kseries.o ksubst.o kvecteur.o kglobal.o kifactor.o kalg_ext.o kgauss.o khelp.o kti89.o kplot.o kprog.o kunary.o kusual.o kidentificateur.o kgen.o krisch.o input_lexer.o first.o # memmgr.o mem.o
# old console: kmisc.cc should be compiled with -DOLD_CONSOLE
#GUI_OBJS = fileGUI.o inputGUI.o menuGUI.o textGUI.o fileProvider.o graphicsProvider.o stringsProvider.o history.o kdisplay.o dConsole.o dmain.o
# new console
GUI_OBJS = fileGUI.o menuGUI.o textGUI.o fileProvider.o graphicsProvider.o stringsProvider.o kdisplay.o console.o main.o
.PRECIOUS: libcas.a libgui.a
all: khicasen.g3a khicas.g3a # pour la version console, supprimer le lien iostream -> iostream.new
%.o: %.cc
$(CXX) $(CXXFLAGS) -c $<
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $<
libgui.a: $(GUI_OBJS)
$(RM) -f $@
$(AR) cru $@ $^
$(RANLIB) $@
libcas.a: $(CAS_OBJS)
$(RM) -f $@
$(AR) cru $@ $^
$(RANLIB) $@
khicas.elf: libcas.a libgui.a catalogfr.o
$(CXX) $(LDFLAGS) -Wl,-Map=khicas.map catalogfr.o $(LIBS) -o $@
sh3eb-elf-objdump -C -t khicas.elf | sort > dump_t
khicasen.elf: libcas.a libgui.a catalogen.o
$(CXX) $(LDFLAGS) -Wl,-Map=khicasen.map catalogen.o $(LIBS) -o $@
sh3eb-elf-objdump -C -t khicasen.elf | sort > dumpen_t
OBJFLAGS= -O binary -R .bss -R .gint_bss -R .debug_info -R .debug_abbrev -R .debug_loc -R .debug_aranges -R .debug_ranges -R .debug_line -R .debug_str -R.comment -R debug_frame
khicas.bin: khicas.elf
$(OBJCOPY) $(OBJFLAGS) khicas.elf khicas.bin
khicasen.bin: khicasen.elf
$(OBJCOPY) $(OBJFLAGS) khicasen.elf khicasen.bin
khicas.g3a: khicas.bin
mkg3a -n basic:Khicas -n internal:KHICAS -V 1.5.1 -i uns:khicasio.png -i sel:khicasio1.png $^ $@
khicasen.g3a: khicasen.bin
mkg3a -n basic:Khicasen -n internal:KHICASEN -V 1.5.1 -i uns:khicasio.png -i sel:khicasio1.png $^ $@
clean:
$(RM) -f *.o libcas.a libgui.a khicas.g3a khicasen.g3a *.bin *.elf
allstep: stepkhicas stepkhicasen
stepkhicas: libcas.a libgui.a catalogfr.o
$(CXX) $(LDFLAGS) -Wl,-Map=khicas.map catalogfr.o $(LIBS) -o khicas.elf
sh-elf-objdump -C -t khicas.elf | sort > dump_t
sh-elf-objcopy -O binary -R .bss -R .gint_bss -R .debug_info -R .debug_abbrev -R .debug_loc -R .debug_aranges -R .debug_ranges -R .debug_line -R .debug_str -R.comment -R debug_frame khicas.elf khicas.bin
mkg3a -n basic:Khicas -n internal:KHICAS -V 1.5.1 -i uns:khicasio.png -i sel:khicasio1.png khicas.bin khicas.g3a
stepkhicasen: libcas.a libgui.a catalogen.o
$(CXX) $(LDFLAGS) -Wl,-Map=khicasen.map catalogen.o $(LIBS) -o khicasen.elf
sh-elf-objdump -C -t khicasen.elf | sort > dumpen_t
sh-elf-objcopy -O binary -R .bss -R .gint_bss -R .debug_info -R .debug_abbrev -R .debug_loc -R .debug_aranges -R .debug_ranges -R .debug_line -R .debug_str -R.comment -R debug_frame khicasen.elf khicasen.bin
mkg3a -n basic:Khicasen -n internal:KHICASEN -V 1.5.1 -i uns:khicasio.png -i sel:khicasio1.png khicasen.bin khicasen.g3a
Citer : Posté le 14/12/2021 18:03 | #
est-ce que vous avez aussi des soucis de performanes pour fx manager sur linux?
Citer : Posté le 14/12/2021 18:14 | #
est-ce que vous avez aussi des soucis de performanes pour fx manager sur linux?
en fait je suis un "faux linux" car ma toolchain tourne sur WSL, donc sous win10.
fx manager est donc nativement sous win10 chez moi sans émulation.
Citer : Posté le 15/12/2021 00:06 | #
Woa je suis un peu surpris de revoir de l'activité sur ce thread !
(j'ai mis la dll sur ma page, parce que j'ai eu un peu de mal a le compiler, le source est https://github.com/redoste/fx-CG50_Manager_PLUS-gdbserver)
Je ne voulais pas proposer de version précompilée car je considère pas vraiment l'outil comme utilisable actuellement mais je suis conscient que j'aurais surement dû mieux détailler les instructions de compilation dans le README.
Pour les intéressés, les étapes (mais expliqué très rapidement) :
Installer nasm et s'assurer qu'il soit dans le PATH.
Ouvrir fx-CG50_Manager_PLUS-gdbserver.sln dans Visual Studio et cliquer sur Build.
Installer Cygwin avec les paquets ninja, nasm et mingw64-i686-gcc-core
Dans un terminal Cygwin, cd vers le projet puis ninja.
Installer les paquets ninja, nasm et mingw-w64-gcc. (ninja et nasm devraient se trouver dans toutes les distribs mais mingw-w64-gcc peut se nommer différemment. Ce qui compte c'est qu'il y ai le cross compiler i686-w64-mingw32-gcc).
Dans un terminal, cd vers le projet, puis ninja.
Si je trouve le temps j'essayerai de faire une vraie version détaillée pour le README.
Update: ca a l'air de marcher avec hbreak au lieu de break
En fait hbreak va mémoriser l'adresse du breakpoint et s'arrêter lorsque l'on s'apprête à exécuter une instruction à cet endroit alors que break remplace l'instruction à l'adresse indiquée par une autre qui va appeler le debugger.
hbreak est donc plus lent car le debugger devra constamment sauvegarder le contexte de l'émulateur, vérifier si l'adresse est dans la liste des breakpoints, puis restaurer le contexte.
break lui n'a pas ce problème mais ne fonctionnera pas si la mémoire qui est mappée à cette adresse change, par exemple du self-modifying code ou (ce qui est surement le cas ici) le changement de la config du MMU avant de lancer l'add-in.
Je recommande donc de placer un hbreak à son entry point puis dès que l'add-in est chargé de le désactiver pour éviter de ralentir encore plus le debugger qu'il ne l'est déjà. À part dans certains cas particuliers, une fois l'add-in chargé il n'y a aucune raison que break ne fonctionne pas.
Citer : Posté le 15/12/2021 08:16 | #
Ah c'etait avec cygwin que c'etait suppose compiler facilement... moi je suis parti avec une install de mingw!
Personnellement, je ne vois pas de raison de ne pas mettre en ligne un binaire d'un soft en version alpha ou beta, du moment que les gens le savent (surtout la, un cross debugger ca s'adresse a des gens experts), ca leur rend service.
Je vais reessayer avec hbreak puis break, mais il me semble que j'avais tente de mettre le point d'arret une fois l'addin lance
Citer : Posté le 20/12/2021 23:17 | #
Comme recommandé par Parisse, je viens de mettre en place des prébuilts de la fausse CPU73050.dll, elles sont disponibles dans les releases GitHub et sont construites automatiquement par GitHub Actions, donc il suffit littéralement d'un clic pour en proposer de nouvelle, j'essayerai de le faire à chaque nouvelle feature ou bug fix plutôt important. (
Si le projet reprend de l'activité).J'ai aussi étoffé le README de manière à ce que les instructions de compilation soient (beaucoup) plus claires et détaillées.
Citer : Posté le 28/08/2022 13:14 | #
Hello,
je "up" le sujet car cela fait un moment que je voulais regarder cela et j'avais jamais trop eu de temps à y consacrer.
Je reprends donc la base par rapport à la procédure décrite par B. Parisse pour faire fonctionner GDB avec l'émulateur.
Pour info, ma config de base est remise à plat et propre sur fxsdk / gint dans leur dernières versions actuelles : à savoir 2.9.0 (branches master).
Le fx-CG Manager PLUS est lui dans sa version 3.60.2202.
Pour le début du tuto, à savoir obtenir le SH73050.dll "patché", pas de problème avec la méthode de Parisse, j'ai juste dévié de la méthode en prenant la version de la DLL issue du github de Redoste afin avoir la dernière version. J'ai pris celle de la dernière release pour ne pas avoir à la recompiler.
Bon cette partie est OK.
Maintenant, créer une version de GDB pour architecture SH3.
Alors première "galère", quand on passe par le système GiteaPC, il y a un petit ajustement des noms des outils pour la compilation, à savoir que la ligne
ne passera pas car les outils en standard ne s'appellent pas sh3eb-elf-XXX (par exemple sh3eb-elf-g++) mais sh-elf-XXX
il faut donc convertir la ligne en
Deuxième point, je ne sais pas si Bernard a aussi expérimenté cette déconvenue, le "make" sort sur une erreur dans le fichier 'sh3eb-gdb/sim/sh/targ-map.c' pour le signal "SIGSTKSZ" (ligne 433 du dit fichier). Malheureusement je n'ai pas trouvé de meilleure méthode pour contourner l'erreur que de commenter ce bloc.
le code initial :
{ "SIGSEGV", SIGSEGV, TARGET_SIGSEGV },
#endif
#ifdef SIGSTKSZ
{ "SIGSTKSZ", SIGSTKSZ, TARGET_SIGSTKSZ },
#endif
#ifdef SIGSTOP
{ "SIGSTOP", SIGSTOP, TARGET_SIGSTOP },
#endif
devenant donc
{ "SIGSEGV", SIGSEGV, TARGET_SIGSEGV },
#endif
/*
#ifdef SIGSTKSZ
{ "SIGSTKSZ", SIGSTKSZ, TARGET_SIGSTKSZ },
#endif
*/
#ifdef SIGSTOP
{ "SIGSTOP", SIGSTOP, TARGET_SIGSTOP },
#endif
après cette modification "à la cochon", le make arrive au bout et génére bien un gbd pour architecture SH en version 11.1.
pour cette partie c'est OK. Juste un petit lien symbolique pour avoir un sh-elf-gdb dans le SDK et zou.... ça roule.
On lance l'émulateur, puis gdb (via donc la commande "sh-elf-gdb" et pas gdb) et on se connecte à l'émulateur via une commande "target remote localhost:31188" : tout roule aussi : juste un petit cri en passant
Remote debugging using localhost:31188
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0xa0000000 in ?? ()
tout à fait normal car je lui ai pas fait de "file".
Donc là il ne reste qu'a tester un petit addin avec les infos de debuggage, donc compilé avec l'option "-g".
mais la ça coince sur la commande file de gdb
toujours le meme message d'erreur :
(gdb) file build-cg/myaddin
Reading symbols from build-cg/myaddin...
(No debugging symbols found in build-cg/myaddin)
(gdb)
C'est balot !! si près du but.
Si quelqu'un a une idée pour déverrouiller cette dernière étape, ce serait cool. Car là je vois pas d'où vient le problème.
Citer : Posté le 28/08/2022 13:39 | #
Bon en fait je vois que Bernard a essuyé les plâtres et que a priori la compilation directe "perd" les infos de debug et que le -g ne suffit pas.
Je vais investiguer cela d'un peu plus près
Citer : Posté le 28/08/2022 13:55 | #
Ouh non non c'est pas supposé être possible ça. Le nom sh-elf- c'est une distinction cosmétique, la cible c'est un triplet BFD avec un format particulier et des valeurs prédéfinies. Je suis surpris que sh-elf soit même accepté. Quand on compile GCC il faut en effet fournir des liens symboliques pour combler l'écart, mais c'est tout. Ici je ne crois pas que ce soit un problème majeur mais c'est définitivement un truc à surveiller et à considérer en cas de problème.
Et pour les infos de debug c'est facile lol, le linker de script de gint les supprime parce que sinon elles se retrouveraient dans le g3a.
Citer : Posté le 28/08/2022 14:28 | #
Ok, bon donc j'ai fait les liens symboliques sh3eb-elf-XXX manquants (effectivement dans l'installation manuelle c'est précisé, mais via GiteaPC ça passe à la trappe).
Et cette fois configure détecte bien les version sh3eb-elf ...
(pour info avec mon --target=sh-elf, il trouvait bien les versions sh-elf-gcc/ar/ld) et il ne me gueulait pas dessus lors du make).
Du coup si je comprends bien pour avoir les infos de debuggage, il faudrait que l'on crée deux cibles différentes pour fxsdk ?
Par exemple pour la CG-50 :
- fxsdk build-cg qui se ferait avec le fxcg50.ld usuel : qui ferait alors un g3a normal (version release dirons nous)
- fxsdk build-cg-dbg qui se ferait avec un fxcg50bdg.ld et qui aurait des règles pour ne pas virer les infos de debug et qui ferait un g3a debug (plus gros mais utilisable avec gdb)
Ce serait automatisable un truc du genre ?
Citer : Posté le 28/08/2022 14:45 | #
Ouaip ce serait une façon facile de le faire. On pourrait aussi ne pas mettre ces sections dans /DISCARD/ et les supprimer à la place quand on passe de l'ELF au binaire flat mais c'est moins pratique.
Citer : Posté le 28/08/2022 17:07 | #
Donc, si je cherche à comprendre un peu plus profondément, pour créer ces fameuses cibles "debug"
Il faudrait que je fasse :
1/ dans fxsdk.sh ( ~/.local/share/giteapc/Lephenixnoir/fxsdk/fxsdk ) :
je dois commencer par créer une cible supplémentaire : par exemple transformer les lignes 130 à 150 pour la partie fxsdk_build()
[[ ! -e build-fx && ! -e build-cg && ! -e build-cg-dbg ]]
none_exists=$?
if [[ -e build-fx || $none_exists == 0 ]]; then
echo "$TAG Making into build-fx"
fxsdk_build_fx "$@"
fi
if [[ -e build-cg || $none_exists == 0 ]]; then
echo "$TAG Making into build-cg"
fxsdk_build_cg "$@"
fi
if [[ -e build-cg-dbg || $none_exists == 0 ]]; then
echo "$TAG Making into build-cg With Debug Information"
fxsdk_build_cg_debug "$@"
fi
}
fxsdk_build_fx() {
fxsdk_build_in "fx" "FX9860G" "$@"
}
fxsdk_build_cg() {
fxsdk_build_in "cg" "FXCG50" "$@"
}
fxsdk_build_cg_debug() {
fxsdk_build_in "cgdbg" "FXCG50DEBUG" "$@"
}
2/ dans le depot gint je dois mettre la jour les cibles de manière parallèles:
je dois ajouter dans CMakeLists.txt au niveau de la ligne 257 (juste après la cible fxCG50) une nouvelle cible
add_compile_definitions(FXCG50)
# je pense qu'il faut que je mette mon -g ici en supplément pour avoir les infos de debug qui se génèrent
add_compile_options(-g)
add_library(gint-cg-debug STATIC ${SOURCES_COMMON} ${SOURCES_CG} ${ASSETS_CG})
set(NAME "gint-cg-debug")
set(LINKER_SCRIPT "fxcg50debug.ld")
endif()
avec bien entendu le script fxcg50debug.ld où je retire du DISCARD toute la partie d'info de debug
du coup le je pense avoir un gint-cg-debug.a qui me servira pour la génération de ma cible de projet
et 3/ dans un projet que je veux debugger, je rajoute la cible DEBUG dans le CMakeLists.txt :
add_executable(myaddin ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}})
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os)
target_link_libraries(myaddin Gint::Gint)
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
generate_g1a(TARGET myaddin OUTPUT "MyAddin.g1a"
NAME "MyAddin" ICON assets-fx/icon.png)
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
generate_g3a(TARGET myaddin OUTPUT "MyAddin.g3a"
NAME "MyAddin" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50DEBUG)
generate_g3a(TARGET myaddin OUTPUT "MyAdDBG.g3a"
NAME "MyAddin" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)
endif()
C'est ça ou j'ai rien pané à comment fonctionne cmake et tous les depots du fxsdk/gint entre eux ?