Edito

Ne me cherchez pas, même ici, je suis ailleurs !

img

"Si tu veux etre underground, tu fais du kernel" 17-02-2004, ©PpHd

Dimanche 07 Mars 2010
Pffffffffffft (<- jet de vapeur)
Bon, puisque je suis toujours sur mon assembleur et que je ne release jamais, autant voir les choses en grand. Et comme c'est la 7ème ou 8ème fois que je recommence, j'en ai marre de faire certaines choses. Donc n'hésitons pas à être ambitieux, voire prétentieux ou même carrément arrogant.

Déjà, les nouveautés par rapport à la "version" précédente :
- assembleur et linker stand-alone, vraiment séparés. L'assembleur fait des objets, le linker des exécutables. A l'ouest, rien de nouveau.
- ca permet d'assembler les fichiers au fur et à mesure qu'ils sont rencontrés dans la ligne de commande. Gros progrès, ça évite de gérer un gros bordel de tables, et ça permet également de gagner en RAM ! Seul truc, ça nécessite des stack frames récursifs à cause des 'include'. C'est donc jouissif.

Donc pour m'aider dans tout ça, j'ai écrit une lib : butillib, pour binutils lib. Oui, j'avais prévenu que l'humilité ne m'étouffait pas.
Le but est de faciliter un certain nombre de tâches qu'on retrouvera systématiquement dans un soft en ligne de commande sous PedroM. Les fonctions (pour le moment, j'en rajoute au besoin) :

Gestion de la ligne de commande
- InitCmdLine
Utilisé pour initialiser une structure CMDLINE fournie par le programme (8 octets). Un pointeur sur cette structure est fourni à la lib pour les autres fonctions
- IsNextArg
Retourne vrai s'il reste des arguments à parser
- GetCurrentArgPtr
Renvoie un pointeur sur l'argument courant
- GetNextArgPtr
Skippe l'argument courant et renvoie un pointeur sur le suivant
- IsArgSwitch
Renvoie vrai si un argument est un switch (ie s'il commence par '+' ou '-')
- ExecSwitchRoutine
Là, c'est puissant. Ca exécute la routine prévue par le programme pour le switch courant. Le programme fournit deux tables de saut pc-relatives sur un word contenant les offsets des routines, et la routine qui va bien est exécutée, en tenant compte du fait que le switch puisse commencer par '+' ou '-'. Plus rien à faire dans le programme, ça c'est le pied.

Gestion des fichiers
- GetFileHandle
Renvoie tout simplement le handle d'un fichier. Plus besoin de créer la SYM_STR en fonction du fichier, l'existence du fichier et la validité du nom sont vérifiées. C'est bien commode.
- GetFilePtr
Ce n'est jamais que HeapDeref(GetFileHandle(const char *Filename)), mais c'est bien commode aussi. Je l'ai exportée parce que CheckFileType l'utilise.

- CheckFileType
Pareil, super commode, vérifie l'existence, la validité et le type d'un fichier. Le type peut-être OTH_TAG, auquel cas une signature custom peut-être vérifiée aussi si elle est fournie. Ca simplifie la vie.

Gestion des chaines
- CompareStrings
Routine postée précédemment. Super commode, plus de recherche à faire à la main. Sert à parser une ligne de commande, une fichier source, un fichier de conf, bref, n'importe quoi qui contient des strings C. Encore une grosse simplification.

Le design de la lib fait qu'elle est appelable en C. Le tout sans smc ni relogements comme d'habitude, ce qui permet d'avoir une lib read-only et ré-entrante, supportant donc un multi-tâche même préemptif sur le même binaire.


Autre fonction prévue, étant donné que tout ça ne tournerait que sous PedroM : SetPedroMAPI. La fonction peut-être appelable par un programme qui ne détecte pas PedroM au boot : plutôt que de terminer avec une erreur, il met en place une API similaire à celle de PedroM pour certaines fonctions, et le programme tourne comme si de rien n'était. Ca comporte :
- implémentation d'un trap #3 pour le déréférencement
- implémentation d'un handler de RAM_THROW sur le handler de f-line
- simulation d'une ligne de commande permettant l'exécution d'un programme de type void main(int argc, const char **argv).

Rappelons que PedroM dispose d'une lib système au format standard des dll (kernel v4), ce qui suppose alors l'implémentation d'une lib nommée "pedrom" contenant les différentes fonctions de PedroM utilisées par la toolchain pour utiliser un programme "PedroM-only" sous AMS. Certaines sont implémentées dans TIGCCLIB, ce qui facilite grandement l'implémentation d'une telle dll.

Voilà voilà, je vaporise à fond là-dedans en ce moment. :)
Posté à
12:14
 par Folco -
Jeudi 04 Mars 2010
Smack
Je trouve ça beau. Point barre, ça ne se discute pas.
;========================================================== ; CompareStrings ; ; Check if the string RefString terminated by a char of SeparatorTable is contained ; in the string table StringTable ; Return #item in the table, or -1 if the string isn't in the table. First item is #0 ; Put in NextChar a ptr to the next char after RefString if NextChar != NULL ; ; input a0 StringTable ; a1 SeparatorTable ; a2 RefString ; a3 **char (NextChar) ; output d0.w #item, else <0 ; (a3) updated if a3 != 0 ; destroy d0-d2/a0 ;========================================================== butillib##antispam##0006: movem.l a1/a4,-(sp) ; Save RefString moveq.l #-1,d0 ; #item \ItemLoop: addq.w #1,d0 ; Update #item lea (a2),a1 ; RefString \Loop: move.b (a0)+,d1 ; End of string in StringTable ? beq.s \CheckSeparator ; Yes, so check the separator at -1(a0) cmp.b (a1)+,d1 ; Compare strings beq.s \Loop ; Until mismatch \NextString: tst.b (a0)+ ; Else skip current string bne.s \NextString \CheckEOT: tst.b (a0) ; End of StringTable ? bne.s \ItemLoop ; No, continue moveq.l #-1,d0 ; Else return error code bra.s \NoSaveNextChar \CheckSeparator: move.b (a1),d1 ; Current char of RefString beq.s \Quit ; #0 ? So quit, EOF is always a valid separator movea.l (sp),a4 ; SeparatorTable \LoopSeparator: move.b (a4)+,d2 ; End of SeparatorTable ? beq.s \CheckEOT ; Yes, try with the next string cmp.b d1,d2 ; Equal ? bne.s \LoopSeparator ; No, test with next char \Quit: move.l a3,d1 ; Must save *NextChar ? beq.s \NoSaveNextChar ; No move.l a1,(a3) ; Else save it \NoSaveNextChar: movem.l (sp)+,a1/a4 rts
Posté à
15:31
 par Folco -
Dimanche 28 Février 2010
GCC sux ?!?
Je sais pas quoi penser de ce compilo... Autant j'aime le C, autant la manière dont GCC le transcrit en 68k me laisse parfois perplexe... Hier, c'est une bêtise qu'il m'a pondu : http://www.yaronet.com/posts.php?sl=&h=369&s=126586&p=13#369

Pas un bug, une bêtise. Par habitude, je lisais le code assembleur pour déboguer le C (je maitrise pas bien encore le débogueur C %) ), quand je suis tombé sur cette énormité : cmp.w #0,%a3. Incroyable ! Et ce juste avant de sortir de la fonction incriminée, donc avec d0, d1 et d2 de disponibles, assis sur le banc de touche et attendant patiamment un emploi.
Ben non, niet, on préfère utiliser une valeur immédiate et bouffer deux octets en plus. Tout va bien, c'est normal...
Si je dis bêtise, c'est parce qu'il ne s'agit pas ici d'une optimisation, mais d'une évidence ! Même sans optimisation activée, je ne comprends pas qu'un compilo puisse choisir ce comportement. Et je compilais en -02 (-03 n'aurait eu aucun effet à ce niveau).

D'ailleurs, ce genre de choix m'épate souvent. Comme le fait que GCC ne semble pas connaitre les instruction bset/bclr du 68000. Ils ont dû les oublier dans la table. Tant pis, on utilisera des masques entiers. #top#
Comme il y a quelques semaines, quand je codais 4 instructions assez similaires à la suite. Les trois premières utilisaient un pea <Label>(%pc) pour pousser une adresse. La quatrième faisait un magistral move.l #<Label>,-(%sp). Pourquoi ? Mystère. Justification technique ? Aucune. Gain en place ? Négatif. Alors quoi ? Rien, juste une lubie de GCC. Dieu merci, on est à la version 4 de ce compilo, je n'ai pas connu les versions inférieures, qu'est-ce que ça devait être !

Et d'une manière générale, GCC m'a très rarement épaté. Deux choses :
- ou je suis vraiment très bon en asm, ce qui n'est pas le cas. Je m'en sors honorablement, mais ça va pas beaucoup plus loin.
- ou GCC a beaucoup de progrès à faire encore. Voilà, ça doit être tout simplement ça.

On m'a souvent dit que le code compilé était illisible. Pas de bol, la majorité du temps il se lit et se comprend à la volée, rien de sorcier. Et quasi-systématiquement, je tombe sur des aberrations... Quel dommage... #tsss#

ps -> le fait que GCC ne sache pas produire du code asm valide qui n'utilise pas de fallback à l'assemblage m'énerve particulièrement... cmpa, addi etc..., c'est pas pour les chiens :/
Posté à
09:05
 par Folco -
Vendredi 26 Février 2010
Choix cornélien
Je suis en train de faire un truc... mais en quoi ?

Asm ou C ? Entre les deux mon coeur balance... je raffole des deux. Et depuis quelques temps, tout ce que j'écris en l'un, je le reproduis avec l'autre. C'est sympa, mais ça fait pas avancer. Rah mais pourquoi j'ai appris autre chose que l'assembleur ?!? On me disait que ça me ferait gagner du temps, aujourd'hui c'est l'inverse... En plus ça me fait perdre mon skill asm, j'ai parfois besion de réfléchir à deux fois avant de faire un déréférencement alakhôn, alors qu'avant j'en faisais même en dormant...


Raaah !!! C'est dur la vie ! #ouin#

Alors quoi ? Quel langage ? Je rêve de faire ce que j'ai à faire dans les deux... rah quelle galère :/
Posté à
11:44
 par Folco -
Vendredi 25 Septembre 2009
Swap
Suite aux excellentes nouvelles de PpHd sur l'effacement de variables en flash, je peux implémenter une sorte de swap pour asTI68k. Je dis bien une sorte, parce que je ne me contenterai de swapper que ce qui appartient au programme. J'aurais pu me payer le culot de swapper tous les fichiers en RAM, mais je sais pas trop si c'est safe, à cause de ce fichu changement de handle à l'archivage (PpHd, change ça stp !). Bref, on se penchera dessus quand j'aurai encore plus de temps à perdre qu'à coder un assembleur inutile qui ne servira jamais sur une machine que plus personne utilise, et encore moins sous PedroM. Mais ça reste en tête.

Tiens, on va poster le code. En fait, les fonctions de (ré)allocation sont réécrites, pour être traitées si elles échouent. Tout ça n'est pas testé (même pas encore relu ! je suis pourtant du genre à relire 10 fois mon code avant le moindre run), je vois pas comment je pourrais faire vu que rien se s'assemble aujourd'hui. :D

On aura au passage noté mon retour à A68k (objectif bootstrap oblige), ainsi que l'adoption du PpHd comment's style, pour ceux qui sont habitués à le lire. :D

Rah je me rends compte à l'instant... J'ai fini d'implémenter tout ça, le boot du programme est fini, j'attaque donc... l'assemblage !!!
#peur#
Posté à
14:22
 par Folco -
Mardi 22 Septembre 2009
Texas Instruments a une politique de merde
C'est quand même incroyable que TI, qui ne sort plus d'OS pour 68k, qui ne corrige pas les bugs dont sont infectés ses OS, qui ne signe plus les FlashApps qu'on lui envoie, se permette de mettre des bâtons dans les roues à qui veut divulger les moyens d'avoir des OS à jour et sur lesquels on puisse bosser (sans le faire perdre le moindre centime, précisons, et on peut même penser bougrement le contraire).

Qui plus est, TI attaque de manière déloyale, comme peut se le permettre un "ayant-droit" friqué face à des jeunes passionnés dépourvus de moyen. Les infos techniques qu'ils donnent sur les tenants et aboutissants des clés qu'on leur a cassées sont tout simplement fausses (cryptage de l'OS etc...).
Ou ils sont encore plus incompétents qu'on le pensait, à ne plus savoir ce qu'ils ont écrit comme softs, ou encore ils nous prennent pour des ignards. Dans les deux cas, ils sont à la ramasse.

Mais bon, que pourront-ils face au net ? Perdront-ils des mois à envoyer des DMCA un peu partout dans le monde ? On verra bien. En attendant, la diffusion assurant leur perte, allons-y :
RabbitSign, de Benjamin Moody, et Resign68k de Brandon Wilson vous permettront de signer ce que vous voulez.

Merci à eux et à tous les participants de ce projet !

PS : Lien vers le site de l'EFF qui invalide les actions de Texas.
Posté à
10:39
 par Folco -
Lundi 21 Septembre 2009
Mon avanceur assemble. Ou l'inverse.
Puisque je programme pour ne surtout pas finir mes programmes, encore moins pour releaser et surtout pas pour faire quelque chose d'utile, je vois les choses en très grand pour mon assembleur qui prend enfin un véritable goût d'arlésienne.
Puis tant qu'à faire dans le v4p0r, autant faire un magnifique nuage, pas un petit étron qui passera inaperçu. Il serait en effet dommage de ne pas être à l'honneur en 2042 quand même. :o

Alors on y va, asTI68k ce ne sera pas ça :
- assembleur multi-sources + linker
- compatibilité avec la plupart des directives de A68k
- compatibilité avec la syntaxe A68k et GNU as (au run-time, fichier par fichier)
- sortie : exécutables, binaires (pour incbin), archives (pour la gloire, vu que c'est déjà pas très utile, alors sur calc on en parle pas), hexa (pour trouver une raison existentielle à EExec).
- utilisation de la flash comme swap au cas où la RAM commence à fumer
- kerstub et nonel
- relogements divers et variés, mais pas compressés. BSS et toute cette mouise
- maquereaux
- exécution en flache comme d'habitude

Voilà. J'ai codé 3 kilos de ce futur non-monstre. Evidemment, j'ai commencé par le plus inutile, c'est à dire surtout pas par le moteur d'assemblage : j'ai parlé du parsing de la ligne de commande et de l'ouverture des sources.

J'utilise un header nommé config.h pour... la configuration des options qui détermineront le comportement par défaut du programme (switches d'assemblage, de linking, d'utilisation de la mémoire et autres imports de symboles).
Là c'est simple, il suffit de remplir les lignes de 0 et de 1 pour configurer ce qu'on veut. Facile.

Là où ça commence à être drôle, c'est que asTI68k se reconfigure au boot avec un fichier de configuration. Par défaut, il lira sa config dans system\asti68k (un fichier texte supportant tous les switches, suivis d'un petit 1 ou 0 suivant l'état qu'on veut leur donner). A noter que ce fichier accepte les commentaires sur toute la ligne ou en fin de ligne. Inutile donc indispensable, comme d'habitude. De même que le support des tabulations et d'autant d'espaces qu'on veut où on veut. Il fallait donc bien que je le fasse.

Comme ça suffit pas, on peut modifier dans config.h la manière dont ce fichier de conf est déterminé au run-time ! Ca peut être un fichier dans le répertoire courant, si on a défini un chemin nul (ce qui permet d'avoir un fichier de conf par projet), ou un fichier donné dans un répertoite donné si on a défini les deux. Complètement ridicule, mais asTI68k en est capable.

Pour être sûr qu'on puisse configurer le soft au cas où ces deux moyens ne suffiraient pas, on peut passer, entre le nom de l'assembleur et le premier source, des options globales qui seront alors appliquées à l'ensemble des fichiers. C'est pas beau ça ? Ca permet de rétablir ce qu'on avait configuré dans config.h, mais détruit à coup de fichier de conf, des fois que le remord nous envahisse.

Enfin, après chaque source, les options qui suivront avant le source suivant seront appliquées au dit-source. Ben oui, des fois que pris de regret, on se dise que finalement, la ligne de configuration écrite dans le fichier de conf pour overrider config.h était trop bien pour être écrasée dans les options globales ! Ca peut être important ça, non ? Non ? Et bien tant pis, c'est fait. Na.

Donc voilà, ça c'est fait comme dirait l'aut', l'ouverture des fichiers aussi, il y a tout ce qu'il faut pour pondre tout un babillage ennuyeux sur stdout et stderr, des éléments du parseur ont été écrits (et voilà, j'ai trouvé une utilité au fichier de conf !), j'ai même une chouette fonction qui trouve et détermine la position d'un mot dans une table en fonction des séparateurs pouvant suivre ce mot dans un source ! Ca c'est épatant, le parsing me faisant hautement braire, ça fait une bonne chose de faite.

Voilà voilà, le temps pas passé sur Steam me permet, en plus que d'avancer 27.32 fois plus vite que d'habitude (première estimation à la louche, à préciser par la suite), de poster un billet. C'est pas chouette ça ? Aller, j'y retourne. :)
Posté à
15:41
 par Folco -
Dimanche 30 Aout 2009
A tout hasard
719958345686847736367204386511604722971278844
802065351568433078413780508897143327301197055
213896058379936821537358230859192898504505926
1105298431035818727
=
223112452563762944318196304529739487547051016
7130210300957267082210173784611
*
322688553424014741501824839741010128636276112
8614350056368675111071170873486957

Juste comme ça, parce que j'aime les maths.
Posté à
18:34
 par Folco -
Lundi 03 Aout 2009
Extended Exec
Voici donc la version finale de Extended Exec.

Ce programme permet donc d'éxécuter un binaire représenté par une chaine hexadécimale. Le binaire peut être ajouté à la VAT avant exécution, archivé, et même effacé si besoin est. Eexec supporte aussi le "dry-run", qui consiste à simuler l'appel sans exécuter le binaire argument.
La source hexadécimale peut être passée manuellement en ligne de commande, ou peut être contenu dans un fichier texte ou string.

Contrairement aux versions précédentes, le programme est un simple programme kernel, sans loader, sans self-modifying code, ce qui lui permet d'être exécuté archivé sans consommer un octet de mémoire. Il est également réentrant. Merci à PpHd pour l'extension RAM_THROW sur le handler de f-line, sans ça ça n'aurait pas été possible.

Il n'y a pas de page de man de fournie dans ce pack, on verra ça quand le-dit programme sera codé. En attendant, c'est sous GPL, donc il y a les sources de fournies, un script pour compiler sous Linux et un pour Windows, et le tout est à télécharger ici !
Posté à
22:43
 par Folco_ -
Samedi 09 Mai 2009
Ça bosse !
img

Ya pas à dire, parser une ligne de commande est toujours un régal !
Après avoir fait plusieurs types de parsings pour d'autres programmes, je trouve que celui-ci est très réussi, et du premier coup. C'est rare que je soit content d'un premier jet. Le code est clair, léger, évidemment rapide (asm oblige), et très maintenable. Ca serait facile de rajouter une option ou d'en virer une.

La validité de tout ce qui est entré est vérifié, les switches nécessitant un argument comme un fichier ou une valeur sont vérifiés dans la foulée, la cohérence entre les switches (ceux qui s'excluent ou ceux qui en nécessitent un autre) également.

Le corps du programme maintenant. =)
Posté à
22:35
 par Folco_ -
Mercredi 07 Janvier 2009
Ça avance !
|================================================================== | IV. Assembly !!! |================================================================== clr.w %d3 |# file to assemble : #0 MakeObject: bsr Src2Obj DontMakeObject: addq.w #1,%d3 |update # file to assemble movea.l SOURCE_TABLE_PTR(%fp),%a0 |&table cmp.w (%a0)+,%d3 |read number of files bhi.s EndOfObject |ok, go to link move.w %d3,%d0 |# current file mulu.w #SOURCE.ENTRY_SIZE,%d0 |offset of data of the file to assemble in the table adda.l %d0,%a0 |&file to assemble move.l SOURCE.Flags(%a0),%d0 |read flag btst.l #OBJECT_DONE,%d0 |file already assembled ? beq.s MakeObject |no, do it bra.s DontMakeObject |else loop, but not ass


On passe à la phase d'assemblage ! Après cinq refontes, il était temps d'y arriver. Mais je suis perfectionniste, et quand j'ai une meilleure idée sur un truc déjà écrit, j'ai la manie de recomencer. Là, j'ai mis en place la structure des fichiers object et archive, la gestion des inclusions de headers et de sources (finalement c'est la même chose), des macros et des équivalences. C'est ambitieux, mais j'aime faire en grand (peut-être aussi pour ça que ça prend tant de temps). :D Mais autant faire en grand, c'est plus marrant.
Posté à
18:35
 par Folco_ -

 RSS  - ©yNBlogs 2004 - 38ms

Login : - Mot de passe :