Retro-engineering sur fx9860G_library.lib
Posté le 17/07/2017 18:46
Bonjour à tous !
Actuellement, je bosse sur un assembleur SH4 sous forme d'add-in, et le linker nécessite d'étudier la forme des bibliothèques utilisées par le SDK. Voilà un peu d'infos sur les libs conçues par Hitachi
Pour rappel, les librairies contiennent des fonctions que vous pouvez appeler depuis votre programme (comme fxlib pour notre calto). Le rôle du linker est de faire le lien entre votre programme et les fonctions appelées, en les copiant dans l’exécutable généré et en modifiant quelques adresses pour que tout coïncide.
A ma connaissance, il y a deux fichiers linkés de base quand vous compilez votre projet sur le SDK :
1/ fx-9860G SDK/OS/FX/lib/setup.obj
C'est le fichier objet de base qui sert à setup votre add-in. Il contient des fonctions qui seront appelées en tout premier avant l'exécution de votre code ! Comme il est indispensable, Casio l'a séparé de l'autre lib. Il est au format ELF, ouf 8)
Si vous voulez l'inspecter vous-même c'est très facile avec des utilitaires dédiés. (je laisserai le mien en fichier joint)
Par contre, il reste une section OPT dans cet objet, ça doit être lié à l' "Optimization" de chez Hitachi, mais je vois pas trop comment c'est fichu. Si quelqu'un a bossé dessus, n'hésitez pas à m'éclairer sur ce point
2/ fx-9860G SDK/OS/FX/lib/fx9860G_library.lib
Le gros de la bibliothèque ! C'est un trésor à sous-routines obscures, en fait c'est un peu un gros dossier à fichiers ELF. On dirait qu'ils ont leur propre format de library, puisque le fichier est signé avec le magic number "HLIB". Voilà comment se compose le header :
0x0 : Magic number : HLIB
0x4 : Des métadonnées qui ressemblent à celles du ELF, sûrement l'endianness et la portée des adresses
0x8 : La quantité de fichiers objet, ici 396
0xc : Offset dans le fichier qui renvoie vers le début de la table des symboles globaux, ici 0x1f04
0x10 : Taille de cette table, ici 11181 bytes.
La suite est une suite de 20 octets x 396, qui référence quelques données relatives aux 396 objets référencés.
Voici leur composition :
0x0 : Offset dans la table des symboles, renvoie vers une strtab qui contient les noms des symboles globaux déclarés dans l'objet
0x4 : Taille de la strtab indiquée ci-dessus
0x8 : Offset dans le fichier indiquant le début de l'objet
0xc : Taille de l'objet ci-dessus
0x10 : 4 octets un peu mystérieux..
Et ça se répète comme ça.
Alors ensuite, quand aux fichiers objet en soi, j'ai repéré deux-trois trucs utiles.
Tout d'abord, c'est du ELF, mais c'est la définition des symboles globaux qui est assez étrange à noter.
(Un minimum de connaissances sur le format ELF est requis pour la suite, attention.)
Résumé grossièrement, je rappelle que les symboles sont des données ou du code à insérer dans l'exécutable, et qu'on peut faire référence à un symbole global pour obtenir son adresse finale. Il y a des symboles locaux, c'est à dire visibles uniquement dans l'objet où ils sont déclarés, et des symboles globaux, visibles par tous les objets linkés. Pour les symboles globaux, il ne suffit de les déclarer qu'une fois pour qu'un autre objet puisse y faire référence.
Ce qui va nous intéresser, c'est comment Hitachi a tagué les déclarations de symboles globaux. Dans fx9860G_library.lib, ces symboles sont bindés en "weak symbol", un type proche du global. C'est ainsi qu'est défini un symbole global, pour y faire référence, on utilise le bind "global symbol".
Étrangement, les symboles globaux ne sont pas définis de la même manière dans setup.obj. Tous les symboles (sauf ceux des sections de code, données, et deux/trois trucs triviaux) sont bindés en global. Pour savoir si un symbole est défini dans cet objet, il faut se pencher sur son type : si un type quelconque est spécifié, alors il est bien défini ici, sinon la déclaration de ce symbole se trouve autre part.
Voilà, c'est à peu près tout, merci pour votre lecture !
J'espère que ça servira à quelqu'un, pourquoi ne pas rendre compatible cette bibliothèque SH4 ?
Ça pourrait être utile à mon humble avis
Fichier joint
Citer : Posté le 17/07/2017 18:59 | #
Bienvenue à toi Fmc_
C'est pas souvent qu'on voit des gens aussi compétents popper de nulle part. As-tu déjà participé à une autre communauté ? (lol si en fait t'es super connu ailleurs, je suis jamais au courant de rien de toute façon)
Sympa le coup de l'assembleur. Pas de support du FPU/DSP, j'imagine (ça n'aurait pas beaucoup d'intérêt) ? Je n'ai pas tout à fait compris si ton assembleur+linker tourne sur le PC ou la calto. Le « un assembleur SH4 sous forme d'add-in » laisse à penser qu'il tourne sur la calto, mais ça présente à la fois peu d'intérêt et un paquet de difficultés (ou comment se payer tout fxlib dans la mémoire de stockage, ahrem).
En vrai, j'avais remarqué qu'on pouvait utiliser cette lib directement dans les projets compilés avec la toolchain GCC, donc pas de surprise sur les ELF. Mais il reste des hacks bizarres, des fonctions qui marchent pas telles quelles (type IsKeyDown() qui segfault sur de la mémoire non-initialisée ou sprintf() qui génère n'importe quoi), sans doute parce qu'il y a des choses différentes dans leur format de bibliothèque.
Petite note sur la section OPT : tu la linkes dans quelle zone de la mémoire du coup si tu ne connais pas son rôle (qui m'est aussi inconnu par ailleurs) ? (Ou tu piques ça dans les listings produits par le linker d'Hitachi peut-être ?)
C'est vrai qu'aujourd'hui pour la compatibilité SH4 on n'a que l'outil de Ziqumu qui remplace bourrinement le binaire de certaines fonctions conflictuelles par un autre qui marche sur SH4, et c'est vraiment étonnant qu'il ait toujours marché à merveille. Cela dit pour porter entièrement fxlib, il faudra se lever assez tôt, surtout si on n'a pas d'outil pour ré-archiver la bibliothèque.
Quel est le taux de compatibilité de ton outil avec le SDK du coup ? Est-il possible d'utiliser entièrement ton linker pour assembler et linker des « versions SH4 » d'add-ins compilés par le SDK ?
Citer : Posté le 17/07/2017 19:15 | #
Il existe un outil pour convertir les libs statiques au format HLIB à un format COFF plus commun que GCC sait alors gérer, sh3eb-elf-renesasconv.exe ou un truc comme ça (que tu peux lancer via wine sous GNU/Linux), disponible sur gcc-renesas.com (qui propose pas mal de ressources utiles pour du SDK -> GCC). C'est ainsi qu'on a obtenu l'équivalent "Linux" de la fx9860G_library.lib, qui a par ailleurs déjà été en grande partie analysé par Simon Lothar dans cette référence un peu bordélique mais riche en informations ou le projet de documentation fxReverse qu'il a mené avec quelqu'un d'autre.
J'en profite pour dire que la toolchain de Renesas (SHC, Asmsh, OptLnk, ...) a également une documentation publique que je viens de copier ici.
Par ailleurs, n'hésites pas à te présenter sur le topic adapté (même une ou deux phrases rapides c'est bien), ça te donnera accès plus rapidement à notre espace de messagerie instantanée, où on pourra répondre à tes questions plus directement, et où tu auras une idée de ce qui a déjà été fait et ce qui reste à faire.
Mon blog ⋅ Mes autres projets
Citer : Posté le 17/07/2017 19:23 | #
@Lephenixnoir
Salut
Alors en fait, ouais je poppe un peu de nulle part. J'ai pas mal improve mon niveau en Basic en piochant sur ce site en fait, maintenant j'en ai marre d'être solo, go partager mes projets :]
Sinon, ouaip pas de support du FPU, il me semble que c'est géré en soft par quelques fonctions, tu sais si c'est documenté ?
Le projet vise effectivement à faire un assembleur sur calto, c'est du suicide avec aussi peu de place dans le heap mais pourquoi pas
Après, les 350 ko de fxlib dans le stockage, outch je sais..
Pour la section OPT, en fait elle sert pas à grand chose. Y'a déjà une section .rela où je prend toutes les relocations dedans, et apparemment, y'a pas besoin de plus Je pense que c'est une fonction un peu triviale de leur compilateur pour le marketing (Renesas le martèle sur son site sans plus d'explications..).
Et quand au réarchivage de la lib, ça peut se faire avec un peu de courage, le vrai problème c'est le prog généré ne tournera sûrement plus sur l'émulateur du SDK D:
Du coup, pour pousser le délire jusqu'au bout, faudrait aussi bidouiller et le réécrire partiellement.
Enfin, pour l'instant y'a pas grand chose de compatible avec le SDK. L'idée, c'est d'écrire une source ASM, monobloc pour simplifier les choses, puis on assemble et le linker implémente le _InitializeSystem, et linke aussi les symboles que l'utilisateur aura rentré. Pour ce dernier point, je réfléchis encore à la syntaxe, mais je pense que ça sera un .data.l _SYM ou un truc du genre
Bref, là j'ai déjà un éditeur et assembleur, je pense poster l'alpha 0.0001 dans les projets dans la soirée
@Cakeisalie5
Wow ! Merci pour toutes ces docs
Je vais de ce pas éplucher tout ça, vraiment super intéressant !
Et ouaip, faut que je me présente
Citer : Posté le 17/07/2017 19:27 | #
CASIO n'utilise pas les nombres flottants selon la norme IEEE 754 dans son OS, il n'y a donc aucun intérêt à avoir un FPU, c'est pour ça qu'ils n'ont pas spécialement cherché à ce qu'il y en ait un sur SH4.
Ce qui est utilisé, c'est du BCD, et pour optimiser les calculs avec ceci, il y a un ALU, que les syscalls utilisent.
J'en dis pas plus, c'est écrit dans la doc' de SimLo.
Pour les sections, Simon Lothar en a un peu parlé : c'est dans le manuel de la toolchain de Renesas.
Mon blog ⋅ Mes autres projets
Citer : Posté le 17/07/2017 19:30 | #
48 ko de heap, ouais. Sur SH4, y'a 256 ko gratuits, l'adresse c'est 0x88004000, jamais utilisé par le système, tout bénef'. Je te laisse voir si ça peut te servir.
Je sais que le système de build de GCC s'appuie sur la libgcc vu qu'il n'y a pas de FPU. C'est hyper documenté, mais pour le Renesas je ne connais pas les détails (je compile tout avec GCC depuis des lustres, mon SDK pourrit tranquillement dans ma machine virtuelle). Cake en sait plus que moi en général sur le SDK, il te dira sans doute s'il le sait.
J'ai bon espoir qu'il tourne quand même, vu que cet émulateur est béton. Exemple, tu prends un add-in compilé sous Linux avec GCC, qui n'a jamais vu le SDK, qui tourne avec une alternative à fxlib, touche à tous les modules du MPU, fait n'importe quoi avec le système, et qui marche comme un charme. Je me fais pas de souci de ce côté-là, si ça tourne sur la calto ça tournera sur l'émulateur.
Mes connaissances en linkage sont assez limitées, j'ai pas encore trop eu l'occasion d'étudier ça (j'en suis encore à la compilation, les parsers, et la théorie derrière :o ), mais c'est définitivement un projet intéressant.
Pour note, y'a déjà AHelper (de Cemetech, si je ne me trompe pas) qui a tenté d'écrire un linker dynamique pour Prizm, une belle tentative. Il a fini par dérégler le MMU et bricker la calto par erreur, mais c'était quand même un travail impressionnant. Il y a peut-être des initiatives similaires sur G85.