Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » fx-CG50 Manager PLUS - gdbserver : débuggez vos add-ins et CASIOWIN
Redoste Hors ligne Membre Points: 49 Défis: 0 Message

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 ).




1, 2, 3 Suivante
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 06/12/2020 00:19 | #


Salut Redoste, bienvenue sur Planète Casio et dans sa petite communauté de reverse-engineering !

Pour éviter toute surprise (et comme tu as clairement déjà touché à pas mal de choses !), note qu'on fait très attention à ne pas discuter/publier d'information susceptible d'être détournée en un contournement du mode examen. Donc pas de détails sur des protocoles d'installation d'OS modifiés, pas de détails sur la LED, et pas de détails sur le fonctionnement du mode examen. Le bon déroulement des épreuves reste prioritaire et on ne veut pas créer de la triche, j'espère que tu comprends.

Tout ce qui a trait à l'émulateur n'est pas un problème ici, je le mentionne simplement parce que tu racontes avoir modifié l'OS et je préfère que le protocole ne se balade pas en public !

Du reste, wow. Alors ça c'est impressionnant. Je ne sais pas comment GDB marche en interne donc une partie des trucs m'échappent. Tu as reverse-engineer suffisamment de CPU73050.dll pour intégrer dans leur système CPU/mémoire des commandes de GDB ? Je suppose que tu es limité à un ensemble de commandes supporté par le script que tu as mis à la sortie du socket ?

Ce qu'on a sorti de CPU73050.dll jusqu'ici c'est surtout des modules périphériques, j'ai aperçu le CPU sans y toucher, et je connais les principales structures de données utilisées dans la mémoire, mais clairement pas assez pour faire tout ça. Franchement, bravo -- combien de temps as-tu passé sur ce projet ?

Indépendamment, est-ce que tu as partagé ce projet sur d'autres forums/communautés ? C'est juste pour garder une trace de qui est où.

Yatis racontait il y a tout juste quelques jours que le debugger intégré du SH7305 (le UBC) est pas émulé, tu tombes à pic. Ça me fait vraiment regretter que l'émulateur ne soit pas disponible sous Linux, parce que je ne suis que moyennement confiant en la possibilité de le faire tourner dans wine et d'y coller ton debugger en plus.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Redoste Hors ligne Membre Points: 49 Défis: 0 Message

Citer : Posté le 06/12/2020 15:43 | #


Salut Lephenixnoir,

Lephenixnoir a écrit :
Pour éviter toute surprise (et comme tu as clairement déjà touché à pas mal de choses !), note qu'on fait très attention à ne pas discuter/publier d'information susceptible d'être détournée en un contournement du mode examen. Donc pas de détails sur des protocoles d'installation d'OS modifiés, pas de détails sur la LED, et pas de détails sur le fonctionnement du mode examen. Le bon déroulement des épreuves reste prioritaire et on ne veut pas créer de la triche, j'espère que tu comprends.

Bien sûr, je ne veux ni qu'il y ai de la triche durant les examens ni que Planète Casio ne se retrouve au tribunal.

Lephenixnoir a écrit :
Du reste, wow. Alors ça c'est impressionnant. Je ne sais pas comment GDB marche en interne donc une partie des trucs m'échappent. Tu as reverse-engineer suffisamment de CPU73050.dll pour intégrer dans leur système CPU/mémoire des commandes de GDB ? Je suppose que tu es limité à un ensemble de commandes supporté par le script que tu as mis à la sortie du socket ?

Le protocole utilisé par GDB est très simple, bien qu'il y a des commandes plutôt avancées utilisées par le "vrai" gdbserver (pour envoyer un fichier sur la machine débuggée par exemple) on peut se limiter aux commandes de base (je me limite à ?, q, m, p, G, P, c pour le moment).
L'avantage d'utiliser GDB plutôt que d'implémenter moi même l'interface utilisateur c'est que GDB possède déjà beaucoup de fonctionnalités avancées. Par exemple (une fois l'écriture en mémoire implémentée) on peut y importer un ELF contenant des sections DWARF et donc obtenir toutes les fonctionnalités d'un "debuggeur complet" comme la possibilité de placer des breakpoints sur des lignes de C au lieu d'instruction assembleur, la localisation automatique des variables ou l'interprétation des structures.

Lephenixnoir a écrit :
Ce qu'on a sorti de CPU73050.dll jusqu'ici c'est surtout des modules périphériques, j'ai aperçu le CPU sans y toucher, et je connais les principales structures de données utilisées dans la mémoire, mais clairement pas assez pour faire tout ça.

Je suis loin d'avoir complètement reverse-engineer la DLL, j'ai utilisé beaucoup de raccourcis pour être honnête.
Par exemple pour sortir l’adresse des registres, j'ai écrit un add-in qui écrit une valeur spécifique dans chaque registres puis j'ai utilisé la fonction de recherche mémoire de Cheat Engine. Pour la lecture de la mémoire, j'ai fait un autre add-in avec l'instruction mov.b @Rm,Rn dans une boucle infinie puis j'ai placé un breakpoint hardware sur l’adresse de Rn. En remontant un peu avant l'instruction ayant écrit la valeur finale, on peut trouver la fonction responsable de lire un octet en mémoire qui prend en paramètre l’adresse. Comme je ne lis qu'un octet à la fois, le debugger est encore super lent et lire à des adresses louches peut faire segfault sachant que j'ai patché la fonction pour éviter qu'elle ne lâche un interrupt si l’adresse lue est problématique. Il faudrait que j'arrive à comprendre comment le MMU fonctionne pour accélérer le processus, le rendre plus stable et surtout de pouvoir y écrire. J'ai cru voir un cache d'instruction, j’espère qu'un ocbwb suffira à l'invalider.
Concernant les modules périphériques je les ai aperçus (notamment via l'utilisation abusive de pointeurs de fonctions à chaque I/O) sans réellement chercher à les comprendre, je pense que je devrai plus me pencher dessus notamment si je veux directement communiquer avec la RAM ou la ROM pour placer les breakpoints.

Lephenixnoir a écrit :
Franchement, bravo -- combien de temps as-tu passé sur ce projet ?

Si j'en crois ext4, j'ai créé le projet Ghidra pour CPU73050.dll le 24 novembre, sachant que j'y avais déjà réfléchis un peu avant je dirais environ 2 semaines.

Lephenixnoir a écrit :
Indépendamment, est-ce que tu as partagé ce projet sur d'autres forums/communautés ? C'est juste pour garder une trace de qui est où.

Non, c'est la première fois que j'en parle publiquement. Penses tu que je devrai en parler autre part ? Je n'ai aucune idée de si il existe des communautés spécialisées dans le reverse-engineing de calculatrices CASIO.

Lephenixnoir a écrit :
Yatis racontait il y a tout juste quelques jours que le debugger intégré du SH7305 (le UBC) est pas émulé, tu tombes à pic.

Preuve que je ne fais pas correctement mes recherches, je n'avais aucune idée que le SH7305 avait un debugger intégré ...

Lephenixnoir a écrit :
Ça me fait vraiment regretter que l'émulateur ne soit pas disponible sous Linux, parce que je ne suis que moyennement confiant en la possibilité de le faire tourner dans wine et d'y coller ton debugger en plus.

Je viens d'essayer avec Wine 6.0-rc1, dans un préfixe vide sans aucun winetricks : ça fonctionne sans problème. J’utilisais une VM pour pouvoir y attacher x64dbg.
Screenshot Wine
Cliquer pour enrouler
Yatis Hors ligne Membre Points: 581 Défis: 0 Message

Citer : Posté le 07/12/2020 12:30 | #


Incroyable !!

J'ai vraiment envie de refaire ton projet, juste pour apprendre à modifier des DLL et comprendre un peu mieux l'environnement de Windows parce que, pour l'instant, j'aide Lephenixnoir de loin mais sans plus.

Aussi, présente-toi ici -> (https://www.planet-casio.com/Fr/forums/topic11464-2-presentations.html), ça te donnera 30 points et tu pourras venir discuter avec nous dans le channel dev (https://www.planet-casio.com/Fr/shoutbox/dev)

Yatis racontait il y a tout juste quelques jours que le debugger intégré du SH7305 (le UBC) est pas émulé, tu tombes à pic

Effectivement, il ne me semble pas que l'UBC soit émulé (comme le SPU, l'USB, le SCIF, le KEYSC, ... (et probablement d'autres modules obscurs)). Mais depuis quelque temps maintenant, j'ai un prototype de débogueur / traceur "on-calc" qui utilise l'UBC, me permettant de poser des Breakpoint hardware et ainsi suivre rapidement le déroulement de l'exécution de l'OS.

Je suis en train de voir pour le porter sur la Graph90+E avec Gint, on pourrait facilement arriver à un point où on pourra tracer plusieurs syscalls en parallèle avec beaucoup d'informations en plus (TLB, RAM, ROM, registre, bref ça peux être incroyablement pété) et j'avais fait un proto de traceur permettant de suivre les interruptions (quand j'essayais de faire la RE du driver USB) mais j'avais beaucoup de problème avec mon gestionnaire d'interruption (parce que je ne gérais pas tous les contextes et ça posait des problèmes avec le KEYSC, le RTC et les TMU pour certaines raisons). Bref, à voir !

Non, c'est la première fois que j'en parle publiquement. Penses tu que je devrai en parler autre part ? Je n'ai aucune idée de si il existe des communautés spécialisées dans le reverse-engineing de calculatrices CASIO.

Ho tu sais, on est sympas ici...on n'est pas beaucoup mais on est sympas, je pense que tu devrais rester...on...fait des kernels ? Puis on a Lephenixnoir (c'est un argument ? Absolument)

Je viens d'essayer avec Wine 6.0-rc1, dans un préfixe vide sans aucun winetricks : ça fonctionne sans problème. J’utilisais une VM pour pouvoir y attacher x64dbg.

Il y a quelques jours, j'ai passé une bonne journée à essayer de faire fonctionner ce foutu émulateur avec Wine sans succès (j'avais un "A problem occured while accessing the registry. Check to make sure that the emulator is installed correctly"), je suis vraiment curieux de savoir exactement comment tu t'y es pris

Je suis curieux, quel est ton parcours dans l'informatique ? Qu'est-ce qui t'a motivé pour t'intéresser aux calculatrices Casio au point de vouloir comprendre le fonctionnement de l'OS ?
Redoste Hors ligne Membre Points: 49 Défis: 0 Message

Citer : Posté le 07/12/2020 21:08 | #


Yatis a écrit :
Effectivement, il ne me semble pas que l'UBC soit émulé (comme le SPU, l'USB, le SCIF, le KEYSC, ... (et probablement d'autres modules obscurs)). Mais depuis quelque temps maintenant, j'ai un prototype de débogueur / traceur "on-calc" qui utilise l'UBC, me permettant de poser des Breakpoint hardware et ainsi suivre rapidement le déroulement de l'exécution de l'OS.

Je suis en train de voir pour le porter sur la Graph90+E avec Gint, on pourrait facilement arriver à un point où on pourra tracer plusieurs syscalls en parallèle avec beaucoup d'informations en plus (TLB, RAM, ROM, registre, bref ça peux être incroyablement pété) et j'avais fait un proto de traceur permettant de suivre les interruptions (quand j'essayais de faire la RE du driver USB) mais j'avais beaucoup de problème avec mon gestionnaire d'interruption (parce que je ne gérais pas tous les contextes et ça posait des problèmes avec le KEYSC, le RTC et les TMU pour certaines raisons). Bref, à voir !

Ton debugger a l'air beaucoup plus complet que le mien, ça a l'air vraiment cool ! C'est sur que le désavantage d'utiliser GDB c'est que celui-ci est platform agnostic et pour obtenir les informations spécifiques à la plateforme il faut aller manuellement peek/poke et quand on en a mare, développer un script python pour automatiser tous ça. Utiliser un breakpoint software qui se base sur une instruction obscure non implémentée parait un peu hackish à côté de l'UBC, mais bon au moins il n'y a pas besoin de matériel.

Yatis a écrit :
Ho tu sais, on est sympas ici...on n'est pas beaucoup mais on est sympas, je pense que tu devrais rester...on...fait des kernels ? Puis on a Lephenixnoir (c'est un argument ? Absolument)

Ce n’était pas que je voulais partir , je me demandais juste si il y avait d'autres communautés sur Internet qui seraient intéressées par ce projet.

Yatis a écrit :
Il y a quelques jours, j'ai passé une bonne journée à essayer de faire fonctionner ce foutu émulateur avec Wine sans succès (j'avais un "A problem occured while accessing the registry. Check to make sure that the emulator is installed correctly"), je suis vraiment curieux de savoir exactement comment tu t'y es pris

J'ai aussi eu ce problème en voulant lancer l'émulateur avec x64dbg, en fait il a besoin d'un argument, faut donc l'exécuter comme ça :
"C:\Program Files (x86)\CASIO\fx-CG Manager PLUS Subscription for fx-CG50series\fx-CG_Manager_PLUS_Subscription_for_fx-CG50series.exe" /n"fx-CG Manager PLUS Subscription for fx-CG50series"
Donc ça n'a absolument aucun rapport avec le registre, merci CASIO pour le message d'erreur utile !

Yatis a écrit :
Je suis curieux, quel est ton parcours dans l'informatique ?

Arf, pour moi c'est toujours la question piège... Beaucoup de temps libre au collège je pense
Plus sérieusement, j'ai pas réellement eu de "parcours", j'ai appris en autodidacte en faisant plein de trucs différents en fonction de mes envies. Avoir des bases solides dans plein de domaines différents est beaucoup plus avantageux que d'être spécialisé dans un seul d'après moi.

Yatis a écrit :
Qu'est-ce qui t'a motivé pour t'intéresser aux calculatrices Casio au point de vouloir comprendre le fonctionnement de l'OS ?

J'aime bien le reverse-engineering et l'embarqué et je trouvais CASIOWIN un peu "mystérieux" (avec son système de fichiers (qui ne sont pas des fichiers) que je trouve plutôt bizarre par exemple). J'ai commencé durant le 1er confinement, donc le temps n'était clairement plus une contrainte avec la fermeture des lycées.
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 08/12/2020 22:27 | #


Redoste a écrit :
L'avantage d'utiliser GDB plutôt que d'implémenter moi même l'interface utilisateur c'est que GDB possède déjà beaucoup de fonctionnalités avancées. Par exemple (une fois l'écriture en mémoire implémentée) on peut y importer un ELF contenant des sections DWARF et donc obtenir toutes les fonctionnalités d'un "debuggeur complet" comme la possibilité de placer des breakpoints sur des lignes de C au lieu d'instruction assembleur, la localisation automatique des variables ou l'interprétation des structures.

Je me doutais que ça donnerait ça mais le niveau est vraiment pas mal là ! Est-ce que (et si oui comment) est-ce que tu déclares des mappings entre le g1a et l'ELF ? Je me sers souvent des mes ELFs mais seulement à coup de binutils dessus, avoir le debugger me serait utile... là où l'émulateur se comporte comme la calto (du point de vue d'un noyau c'est une plateforme à part, on ne peut pas tester que là).

Par exemple pour sortir l’adresse des registres, j'ai écrit un add-in qui écrit une valeur spécifique dans chaque registres puis j'ai utilisé la fonction de recherche mémoire de Cheat Engine. Pour la lecture de la mémoire, j'ai fait un autre add-in avec l'instruction mov.b @Rm,Rn dans une boucle infinie puis j'ai placé un breakpoint hardware sur l’adresse de Rn.

Ooookay, tu me rassures un peu, j'ai eu peur que tu te poses avec le RE complet du système CPU+mémoire qui nous semblait pas du tout évident avec Yatis. Remarque la frayeur me remet à ma place aussi, c'est pas plus mal.

Il faudrait que j'arrive à comprendre comment le MMU fonctionne pour accélérer le processus, le rendre plus stable et surtout de pouvoir y écrire. J'ai cru voir un cache d'instruction, j’espère qu'un ocbwb suffira à l'invalider.

Je sais où est la pagination de la mémoire physique (... parce qu'évidemment l'espace d'adressage physique du MPU est mappé à la main dans l'espace d'adresse virtuel de l'émulateur), entre ça et les registres périphériques du MMU ça devrait pouvoir se faire assez bien. Mais la mémoire physique en elle-même n'est pas encore 100% claire.

Concernant les modules périphériques je les ai aperçus (notamment via l'utilisation abusive de pointeurs de fonctions à chaque I/O) (...)

Je présume que ces pointeurs sont ce qui sort de la gestion de la mémoire physique. Y'a beaucoup de structures assez complexes dans le tas, et des pointeurs sur fonction partout.

Non, c'est la première fois que j'en parle publiquement. Penses tu que je devrai en parler autre part ? Je n'ai aucune idée de si il existe des communautés spécialisées dans le reverse-engineing de calculatrices CASIO.

Tu peux toujours en parler sur Casiopeia ou Cemetech mais il y a très peu d'activité sur le premier et très peu d'activité Casio sur le second. Critor, qui écrit quasiment tous les articles de TI-Planet, sera avide d'informations. Mais dans l'ensemble pour le RE c'est ici qu'il y a le plus d'activité, je demande surtout parce que souvent les projets non triviaux comme celui-ci ne sortent pas de nulle part et j'aime bien comprendre qui vient d'où.

Je viens d'essayer avec Wine 6.0-rc1, dans un préfixe vide sans aucun winetricks : ça fonctionne sans problème. J’utilisais une VM pour pouvoir y attacher x64dbg.

Yatis a écrit :
Il y a quelques jours, j'ai passé une bonne journée à essayer de faire fonctionner ce foutu émulateur avec Wine sans succès (j'avais un "A problem occured while accessing the registry. Check to make sure that the emulator is installed correctly"), je suis vraiment curieux de savoir exactement comment tu t'y es pris

Redoste a écrit :
J'ai aussi eu ce problème en voulant lancer l'émulateur avec x64dbg, en fait il a besoin d'un argument, faut donc l'exécuter comme ça :
"C:\Program Files (x86)\CASIO\fx-CG Manager PLUS Subscription for fx-CG50series\fx-CG_Manager_PLUS_Subscription_for_fx-CG50series.exe" /n"fx-CG Manager PLUS Subscription for fx-CG50series"

Hmm j'ai aussi le problème de Yatis et cette méthode m'envoie un segfault (peut-être juste un autre problème qui apparaît ensuite). Je chercherai, mais les choses Windows m'échappent pas mal donc c'est pas gagné.

Plus sérieusement, j'ai pas réellement eu de "parcours", j'ai appris en autodidacte en faisant plein de trucs différents en fonction de mes envies. Avoir des bases solides dans plein de domaines différents est beaucoup plus avantageux que d'être spécialisé dans un seul d'après moi.

C'est le cas de beaucoup d'entre nous ici ! Perso j'adorais le vieil ordi sous Windows 95 qu'on avait à la maison alors mon père m'a appris à programmer en C. Et de test en test, me voilà.

J'aime bien le reverse-engineering et l'embarqué et je trouvais CASIOWIN un peu "mystérieux" (avec son système de fichiers (qui ne sont pas des fichiers) que je trouve plutôt bizarre par exemple). J'ai commencé durant le 1er confinement, donc le temps n'était clairement plus une contrainte avec la fermeture des lycées.

Le BFile original est en effet mystique et surtout une énorme saloperie, perso je le fuis comme la peste mais c'est difficile de s'en défaire complètement.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Critor En ligne Administrateur Points: 2673 Défis: 18 Message

Citer : Posté le 09/12/2020 13:16 | #


Lephenixnoir a écrit :
Tu peux toujours en parler sur Casiopeia ou Cemetech mais il y a très peu d'activité sur le premier et très peu d'activité Casio sur le second. Critor, qui écrit quasiment tous les articles de TI-Planet, sera avide d'informations. Mais dans l'ensemble pour le RE c'est ici qu'il y a le plus d'activité, je demande surtout parce que souvent les projets non triviaux comme celui-ci ne sortent pas de nulle part et j'aime bien comprendre qui vient d'où.


Je confirme. Hélas peu d'activité et membres actifs sur Casiopeia, sans doute les suites du conflit à la naissance avec le site Casio Kingdom aujourd'hui disparu, ainsi que du départ d'au moins 2 des rares membres les plus actifs ces dernières années.

Cemetech est en pratique plus orienté TI, mais rien n'empêche d'en parler.

TI-Planet malgré le nom est ouvert à tous. Je ne manquerai pas de traiter le gdb Graph 90+E dans le flux d'actualités.
Après, l'actualité est chargée en ce moment, et il y a des créneaux stratégiques dans la semaine pour ce genre d'événement historique.
Je pense donc traiter la chose plutôt en début de semaine prochaine, et je lierai ce que tu as mis ici. Donc pas la peine de t'embêter à cross-poser là-bas, sauf si tu y tiens.
Redoste Hors ligne Membre Points: 49 Défis: 0 Message

Citer : Posté le 09/12/2020 22:04 | #


Lephenixnoir a écrit :
Est-ce que (et si oui comment) est-ce que tu déclares des mappings entre le g1a et l'ELF ?

Normalement il faut utiliser la commande file de GDB pour manuellement indiquer dans quel ELF aller chercher les symboles / informations DWARF. Après GDB est très facilement scriptable, il devrait être possible d'écrire un simple script responsable de lire en mémoire une valeur et de l'utiliser pour identifier quel add-in est chargé. Ça nécessiterait de rajouter une section à chaque add-in qui serait chargée à une adresse fixe et mettre en place une lookup table liant l'identifiant dans le g3a au chemin du fichier ELF correspondant.
Théoriquement il devrait aussi pouvoir être possible de trouver quelque part dans CASIOWIN un endroit en mémoire où est écrit l'add-in actuellement chargé.

Je présume que ces pointeurs sont ce qui sort de la gestion de la mémoire physique. Y'a beaucoup de structures assez complexes dans le tas, et des pointeurs sur fonction partout.

Je pense que ces pointeurs sont aussi beaucoup utilisés pour faire le lien entre les DLLs.
De ce que j'ai compris DLSim32E.dll se charge de charger les DLLs de chaque module et à l'aide de 2 exports (DLDriverInfo et DLDriverInfoCall) a assez d'informations pour faire le lien entre eux (comme décrit dans les fichiers CGM.dlm et CGM.dlp). Comme actuellement beaucoup d'offsets sont hard-codés, j'hésite à RE DLSim32E.dll de manière à éviter de hard-coder des offsets des DLLs de la RAM et de la ROM en plus de celle du CPU car devoir mettre à jour tous les offsets à la moindre mise à jour de l'une des trois me semble plutôt fastidieux.

Hmm j'ai aussi le problème de Yatis et cette méthode m'envoie un segfault (peut-être juste un autre problème qui apparaît ensuite). Je chercherai, mais les choses Windows m'échappent pas mal donc c'est pas gagné.

J'ai voulu confirmer que je n'avais pas quelque chose d'installé sur ma machine (Void Linux avec Wine 6.0-rc1) qui serait requis pour faire fonctionner l'émulateur mais que je n'avais pas remarqué. J'ai donc essayé dans une VM Debian 10 avec Wine 4.0 et le seul problème que j'ai rencontré c'est que l'installateur plantait après l'extraction du MSI. Après avoir vidé le wineprefix et en le reconstruisant en mode 32 bits uniquement (export WINEARCH=win32) tout fonctionnait sans problème.
Tu dois probablement avoir une vielle version de Wine ou une version patchée même si je trouve plutôt louche que cela entraine un segfault car généralement les erreurs de compatibilité de Wine bombardent stderr de messages sans planter.

Critor a écrit :
Je pense donc traiter la chose plutôt en début de semaine prochaine, et je lierai ce que tu as mis ici.

Merci ! (Même si je doute que ce debuggeur, qui est loin d'être pleinement fonctionnel, mérite autant de visibilité )
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 09/12/2020 22:12 | #


Normalement il faut utiliser la commande file de GDB pour manuellement indiquer dans quel ELF aller chercher les symboles / informations DWARF. Après GDB est très facilement scriptable, il devrait être possible d'écrire un simple script responsable de lire en mémoire une valeur et de l'utiliser pour identifier quel add-in est chargé.

Ce qui me pose question c'est ce qu'on fait des données dont l'adresse n'est pas fixée dans l'ELF mais seulement déterminée au runtime. Il y a quelques régions comme ça, en gros tout ce qui bypasse le MMU est dépendent de la plateforme et de la version de l'OS. C'est pas capital mais c'est pour savoir, je suppose qu'il y a de quoi les déclarer dans gdb mais sans doute à la main.

Merci pour les infos Wine, je tenterai avec un OS plus clean.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Redoste Hors ligne Membre Points: 49 Défis: 0 Message

Citer : Posté le 14/12/2020 20:25 | #


Lephenixnoir a écrit :
Ce qui me pose question c'est ce qu'on fait des données dont l'adresse n'est pas fixée dans l'ELF mais seulement déterminée au runtime. Il y a quelques régions comme ça, en gros tout ce qui bypasse le MMU est dépendent de la plateforme et de la version de l'OS. C'est pas capital mais c'est pour savoir, je suppose qu'il y a de quoi les déclarer dans gdb mais sans doute à la main.

Oui tu peut facilement le faire :
(gdb) set $foo = (struct bar_t*) 0x12345678
(gdb) print *$foo


Concernant le projet, je viens de finir d'implementer la possibilité d'écrire en mémoire. J'ai complètement réecris la manière dont je lisais et j'ai implémenté une petite partie du MMU de manière à rendre le processus le plus rapide possible. Le cache utilisé pour les instructions est lui aussi mis à jour ce qui permet de modifier le code depuis le debugger :
Program received signal SIGTRAP, Trace/breakpoint trap.
0x00300000 in ?? ()
(gdb) x/3i $pc
=> 0x300000:    .word 0x003b
   0x300002:    bra    0x300000
   0x300004:    nop    
(gdb) set $r0 = 0
(gdb) print $r0
$1 = 0
(gdb) c
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00300000 in ?? ()
(gdb) print $r0
$2 = 0
(gdb) c
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00300000 in ?? ()
(gdb) print $r0
$3 = 0
(gdb) set *((unsigned short*)0x300004) = 0x7001
(gdb) x/3i $pc
=> 0x300000:    .word 0x003b
   0x300002:    bra    0x300000
   0x300004:    add    #1,r0
(gdb) c
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00300000 in ?? ()
(gdb) print $r0
$4 = 1
(gdb) c
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00300000 in ?? ()
(gdb) print $r0
$5 = 2


La prochaine feature importante dont je vais me charger sont les breakpoints mais j'hésite entre deux méthodes.

Utiliser un breakpoint software, comme j'ai fait jusqu’à présent : le debugger écrira 0x003b à l'endroit du breakpoint et se déclenchera au passage sur l'instruction. Celui-ci a l'avantage d'être simple à implémenter mais je ne sais pas comment exécuter l'instruction qui était censé être à la place du 0x003b ni comment correctement gérer les singlesteps car il faudrait prévoir les jumps conditionnels.

Ou alors utiliser un breakpoint "hardware" : trouver une fonction dans CPU73050.dll que je pourrai facilement remplacer qui est exécutée à chaque instruction et je déclencherai le debugger à ce moment. Cela nécessiterait beaucoup plus de RE mais cela rendra le singlestepping et l'exécution de l'instruction "sous" le breakpoint plus facile.
Critor En ligne Administrateur Points: 2673 Défis: 18 Message

Citer : Posté le 16/12/2020 13:48 | #


Voilà comme promis, c'est annoncé et à la une ce mercredi - j'ai crédité au mieux comme d'hab :
https://tiplanet.org/forum/viewtopic.php?p=258071#p258071

J'espère juste ne pas avoir raconté trop de bêtises car ne développant pas à ce niveau.
Redoste Hors ligne Membre Points: 49 Défis: 0 Message

Citer : Posté le 22/12/2020 00:20 | #


J'ai pu pas mal avancer ce week-end et je pense pouvoir affirmer que fx-CG50 Manager PLUS - gdbserver est maintenant utilisable en tant que "vrai" debuggeur.

J'ai donc choisi d’implémenter les deux types de breakpoint, hardware et software.
Le breakpoint hardware est plus robuste car mappé sur une adresse, si le code présent à celle-ci est modifié, le breakpoint se déclenchera quand même.
Le breakpoint software est plus rapide car il n'est pas nécessaire de vérifier la liste des breakpoints à l’exécution de chaque instruction.

J'en ai aussi profité pour corriger quelque problèmes : on peut maintenant attacher GDB quand on veut, il n'est pas nécessaire d'être synchro au lancement de l'émulateur et on peut déclencher le debuggeur manuellement avec Ctrl+C dans GDB sans placer de breakpoint à l'avance.

Pour faire le point sur l'avancée, j'ai fait une autre vidéo ou je debuggue un add-in écrit en C comme dans un "vrai" debuggeur (interprétation des structures, placement des breakpoints sur les lignes de C, etc.)



Le seul problème majeur actuellement c'est la vitesse. Il est possible d’accélérer la chose en désactivant la stdout mais le gain reste négligeable. Je n'ai aucune idée de comment profiler ça correctement, ce qui pourrait m'aider à localiser les endroits à optimiser.
J'ai déjà pas mal amélioré la chose en évitant le changement de contexte (si on peut appeler un pauvre pusha/popa un changement de contexte...) à chaque instruction lorsque aucun breakpoint hardware n'est présent.
Je suspecte la partie peek/poke (dont GDB abuse à chaque arrêt) d'être plutôt lente, je devrai essayer de mettre en cache les traductions du MMU car actuellement elle est réeffectuée à chaque lecture d'un uint32_t.

N'hésitez pas à me dire si vous trouvez des endroits extrêmement mal optimisés dans mon code
Parisse Hors ligne Membre Points: 506 Défis: 0 Message

Citer : Posté le 22/12/2020 15:33 | #


Ce serait extremement interessant pour la mise au point de KhiCAS sur les Casio ou je n'ai pas de support gdb jusqu'a present contrairement a la TI Nspire (avec firebird-emu) ou Numworks (sur le simulateur) ce qui rend la mise au point tres fastidieuse.
Est-ce que c'est compatible avec la mise au point sur le source en C/C++? Ce que je fais avec firebird-emu
1/ attacher le process de l'emulateur dans un sous-processus gdb de emacs sur le PC
2/ ctrl-x ctrl-a ctrl-b dans emacs pour mettre un breakpoint a cet endroit dans le source C/C++
3/ c pour continue, et au breakpoint possibilite de visualiser les variables C avec p varname, de remonter dans les frames, d'appeler une fonction C/C++ ...
Redoste Hors ligne Membre Points: 49 Défis: 0 Message

Citer : Posté le 23/12/2020 18:53 | #


Parisse a écrit :
Est-ce que c'est compatible avec la mise au point sur le source en C/C++? Ce que je fais avec firebird-emu
1/ attacher le process de l'emulateur dans un sous-processus gdb de emacs sur le PC
2/ ctrl-x ctrl-a ctrl-b dans emacs pour mettre un breakpoint a cet endroit dans le source C/C++
3/ c pour continue, et au breakpoint possibilite de visualiser les variables C avec p varname, de remonter dans les frames, d'appeler une fonction C/C++ ...


Tout devrait fonctionner mise à part appeler une fonction C/C++ car je n'ai pas pris en compte la possibilité de modifier le registre pc (car celui-ci est géré différemment des autres). Ça ne devrait pas être compliqué à implémenter et comme je ne savais pas qu'il était possible d’appeler une fonction depuis GDB je n'avais pas cherché à le faire.

Le seul réel problème au quel tu risques d'être confronté c'est la lenteur du debuggeur, ce n'est pas impossible de l'utiliser mais pour de longue session de debuggage ça peut vite être insupportable.
Redoste Hors ligne Membre Points: 49 Défis: 0 Message

Citer : Posté le 16/04/2021 17:57 | # | Fichier joint


Je reviens faire une petite update de ces 4 derniers mois sur le projet.

Parmi les changements les plus importants, il est maintenant possible de changer pc et donc d'appeler une fonction via GDB via la commande call, j'ai rajouté le support de MSVC pour ceux qui n’aimeraient pas MinGW et j'ai effectué plusieurs petites optimisations.

J'ai beaucoup stagné car je n'arrive pas à déterminer la cause de la lenteur des lectures dans la mémoire de l'émulateur. Après avoir rajouté le support pour MSVC, j'ai pu profiler fxCG50gdb avec les outils de Microsoft mais la où EIP passe tout son temps est dans recv, send et printf. (J'ai bien sûr essayé en désactivant le logging, ce qui ne produit pas de différence de lenteur notable).

Le dernier changement que j'ai effectué aujourd'hui me semble être le plus majeur même si c'est le plus simple. La sortie série du SH7305 est maintenant écrite sur stderr. Je pense que ça peut être plutôt utile pour faire du bon vieux printf debugging notamment. Seul le registre SCFTDR est pris en compte donc ce n'est pas très réaliste mais ça fait le travail.

Juste par principe voici une très simple démo de la chose en fonctionnement :
Code
Cliquer pour enrouler
int main() {
  unsigned char mode[6] = {0, 5, 0, 0, 0, 0};
  Serial_Open(mode);
  int foo = 0xDEADC0DE;
  for (;;) {
    unsigned char msg[10];

    static const char hex[] = "0123456789ABCDEF";
    for (int i = 0; i < sizeof(foo); i++) {
      msg[(i * 2) + 0] = hex[(((char *)&foo)[i] & 0xF0) >> 4];
      msg[(i * 2) + 1] = hex[((char *)&foo)[i] & 0x0F];
    }
    msg[8] = '\n';
    msg[9] = 0;

    Serial_Write(msg, sizeof(msg) - 1);
    GetKey(&foo);
  }
}

GIF Demo
Cliquer pour enrouler


Je me demande si ça vaut le coup d’implémenter SCFRDR car cela pourrait être utilisé pour connecter plusieurs instances de l'émulateur entre elles et donc aider au développement de jeux multijoueurs par exemple. Si ça intéresse quelqu’un n'hésitez pas à me la dire, j'essayerai de l’implémenter.
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 16/04/2021 18:12 | #


Je vois pas mal de shenanigans émulateur ici qui rappellent pas mal les saletés que j'y trouvait avec Ghidra. Tu parles de handlers pour le registre, est-ce que tu as plus de détails ? Dans le modèle mémoire que j'avais établi, chaque page de mémoire émulée de 4k est accompagnée d'un autre buffer de 4k (situé juste après) et chaque octet de données a son "octet de contrôle" dual dans lequel des bits indiquent entre autres chaque fois qu'on fait un accès et chaque fois qu'on fait une modification. Est-ce qu'ensuite c'est routé vers des handlers à la fin de chaque cycle ?
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Redoste Hors ligne Membre Points: 49 Défis: 0 Message

Citer : Posté le 16/04/2021 18:53 | #


Dans la seconde partie de 4k les octets sont traités par deux. L'un des deux est utilisé comme "cache d'instruction" ce qui permet d'indiquer quelle est l'entrée du tableau de pointeurs de fonctions des instructions qui correspond à l'instruction présente dans ces deux octets. Le second semble être des flags que je n'ai pas vraiment pris le temps d'identifier (je sais seulement que pour la RAM et la ROM c'est à 0), il est probable que l'un d'entre eux provoque le routage vers les handlers de registres.

Ce sur quoi je me suis basé pour la sortie série, ce sont des structures qui documentent tous les registres (ce sur quoi cette liste de la bible semble être basée). Dans ces structures on trouve simplement des pointeurs vers les fonctions de lecture et d'écriture du registre et c'est ce que je remplace dans serial_init.
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 16/04/2021 19:09 | #


Merci pour ces détails. Effectivement c'est de ces structures de registres que la liste est issue (pour être exact il y a une table de modules, et pour chaque module une tables de registres, une table de pins d'entrée, une table de pins de sortie, et une table de paramètres pour l'émulateur). Rerouter les fonctions de lecture/écriture est malin ! C'est fou ce qu'on peut faire sur un programme quand il n'y a pas de versions futures pour lesquelles on doit assurer de la compatibilité. xD
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Parisse Hors ligne Membre Points: 506 Défis: 0 Message

Citer : Posté le 14/12/2021 07:43 | #


Les etapes pour utiliser gdb pour Casio sous linux avec wine semblent etre les suivantes:
1/ installer l'emulateur casio avec wine

2/ installer l'equivalent de gdb-server
cd .wine/drive_c/Program\ Files\ \(x86\)/CASIO/fx-CG\ Manager\ PLUS\ Subscription\ for\ fx-CG50series/
mv CPU73050.dll CPU73050.real.dll
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/casio/CPU73050.dll
(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)

3/ compiler gdb pour sh3:
wget https://ftp.gnu.org/gnu/gdb/gdb-11.1.tar.gz
cd casio (ou autre repertoire de build)
tar xvfz ../gdb-11.1.tar.gz
mkdir sh3eb-gdb
cd sh3eb-gdb
../gdb-11.1/configure --srcdir=../gdb-11.1 --target=sh3eb-elf
make
sudo make install (ajouter --prefix=chemin dans la commande configure si on n'a pas les droits sur /usr/local/bin)

Ensuite
alias casioemu='wine "C:\Program Files (x86)\CASIO\fx-CG Manager PLUS Subscription for fx-CG50series\fx-CG_Manager_PLUS_Subscription_for_fx-CG50series.exe" /n"fx-CG Manager PLUS Subscription for fx-CG50series" &'
(a mettre dans .bashrc)

4/ Pour utiliser:
casioemu
sh3eb-elf-gdb
puis target remote localhost:31188

Maintenant je vais essayer de creer les infos de debug pour khicas et voir si j'arrive a debugguer!
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 14/12/2021 08:52 | #


Merci beaucoup ! C'est plus dur que ce que je m'imaginais, tu as comblé pas mal de trous. Ce sera définitivement utile !
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Parisse Hors ligne Membre Points: 506 Défis: 0 Message

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-g++ -g -static -nostdlib -Tprizm.ld -Wl,-Map=khicas.map -Wl,--print-memory-usage catalogfr.o -L. -L/home/parisse/casiolocal/lib -Wl,--start-group -lgui -lcas -ltommath -lustl -lm -lc -lgcc -Wl,--end-group -o khicas.elf
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
1, 2, 3 Suivante

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 249 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

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