1

J'ai rapidement passé en revue la partie C pour voir si la question n'a pas été posée, mais je n'ai pas trouvé.
Pourtant ça me rappelle quelque chose, peut-être que ça a plus de 3 mois et donc ça a été supprimé...

Est-il possible d'obtenir un pointeur vers le programme en cours d'execution ? (que le programme se pointe sur lui-même en fait).
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

2

Avec les conditions suivantes:
* _nostub
* programme non compressé
* le code en question est dans le fichier objet principal (par exemple: le programme n'a qu'un seul fichier source)

la méthode (très sale) suivante marchera:
extern void program_start_label asm("tigcc_compiled.") // n'oublie pas le point!
void *program_start=&program_start_label;
void *program_start_noghost=(void *)((unsigned long)program_start&0x3ffff);


program_start est l'adresse à laquelle le programme est exécuté, program_start_noghost est l'adresse réelle, nécessaire si tu veux par exemple obtenir le handle du programme.
D'ailleurs, n'oublie pas de retirer 2 si tu veux le début du handle. program_start te donne le début du code.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

3

Ouhhhhh c bien compliqué tout ça, en effet ça ne s'invente pas smile

Si je retire 2, je retombe sur les octets de taille c'est bien ça ?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

4

Kevin Kofler> Est-ce que tu peux nous expliquer précisément ce qu'il se passe, s'il te plaît ? Parce que là, je ne comprends rien.

5

Vertyos a écrit :
Ouhhhhh c bien compliqué tout ça, en effet ça ne s'invente pas smile

smile
Et attention aux conditions qui doivent être satisfaites pour que ça marche!
Si je retire 2, je retombe sur les octets de taille c'est bien ça ?

Oui.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

6

jackiechan
a écrit : Kevin Kofler> Est-ce que tu peux nous expliquer précisément ce qu'il se passe, s'il te plaît ? Parce que là, je ne comprends rien.

* Quand TIGCC compile un fichier C, il met un label appelé tigcc_compiled. au début du fichier assembleur généré.
* Le système de patchage met son code de démarrage après ce label.
* Ce label marque donc le début du fichier objet.
* Si on est en _nostub, le début du programme est le début du fichier objet principal.
* Donc, dans les conditions citées, si on obtient l'adresse de tigcc_compiled. dans le fichier objet principal, on a l'adresse du début du programme.
* Or, c'est exactement ce que mes 2 premières lignes de C font.
* Quant à la troisième ligne, elle ne fait qu'un AND avec 0x3ffff.
* Enfin, pour la condition "programme non compressé", je l'ai rajoutée pour que l'histoire des 2 octets du taille et du début du handle soit vraie.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

7

Sinon il y a une méthode qui marche avec tous les types de programmes (kernel & nostub).

On recherche dans la table des handles l'adresse immédiatement inférieure à celle de n'importe quel label du programme. On est sûr de tomber sur le handle du programme, puisqu'aucun handle ne peut se glisser en plein milieu du prog (càd entre son point d'entrée et le label) smile

Cet algo est beaucoup plus lent, mais si on ne l'exécute qu'une fois dans le prog, c'est négligeable, vu que la recherche prend dans tous les cas moins d'une seconde smile
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

8

Et on fait comment ça ? grin
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

9

eek Je viens de te donner l'algo !

Je crois qu'il y a un ROM_CALL pour obtenir l'adresse de la table des handles.
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

10

Voilà c ça qu'il fallait dire grin
Autre petite question, je viens d'essayer un truc.

Je fais un programme en C quelconque. Ensuite avec un éditeur hexa, oncalc, je rajoute 10 octets (0) à ce fichier, je déplace le TAG et je modifie les octets de taille.
Je me retrouve donc avec un fichier ASM qui fait 10 octets de plus que l'ancien et qui logiquement (enfin c ce que je pensais...) devrait se lancer et fonctionner pareil.

Au lieu de ça -> Protected Memory Violation.

Y a-t-il une raison ou une explication, ou bien est-ce que théoriquement ça devrait marcher, auquel cas j'aurais merdé quelque part ?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

11

Tu as bien redimensionné le handle par un ROM_CALL, pour que son header soit mis à jour ?

Et puis surtout, il faut déplacer la table des relogements. Tu n'as pas dû le faire wink
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

12

En fait j'ai essayé 2 choses :

- Faire un HeapRealloc sur la variable, pour "l'aggrandir", puis modifier les octets de taille et déplacer le tag.
- Créer une nouvelle variable d'une taille supperieure à l'originale de 10 octets, puis faire un memcpy, et enfin mettre à jour les octets de taille et déplacer le tag à la fin.

Dans un cas comme dans l'autre => erreur sad
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

13

Il faut déplacer la table des relogements
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

14

Arf je sais même pas ce que c'est grin
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

15

Ça consiste en quoi "déplacer la table de relogement" ?
Pas trouvé dans la doc de tigcc sad
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

16

C'est la table qui indique au relogeur du lanceur où sont les adresses absolues à corriger.

Car le compilateur ne peut pas deviner où sera exécuté le programme, donc les variables accédées par leur adresse absolue sont traitées d'une manière spéciale. Le compilo stocke à la fin du programme les offsets des adresses à compléter : c'est la table des relogements.
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

17

if( Il faut les déplacer de la même manière que le tag ? )
 {
 if( Leur taille est fixe ou pas ? )
  {
  C'est combien ?
  }
 else
  {
  Comment peut-on reconnaitre cette table du reste du programme ?
  }
 }
else
 {
 Oula ça devient compliqué comme histoire...
 }


grin
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

18

nan mais il était serieux mon post sad
Il faut les déplacer de la même manière que le tag ?
Leur taille est fixe ou pas ? Comment peut-on reconnaitre cette table du reste du programme ?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

19

C'est un peu compliqué, mais ça devient simple si on a compris. Voilà l'algorithme:
1. À partir du mot (short) devant le tag, tant que le mot actuel n'est pas 0:
1.1. Rajouter 10 (le nombre d'octets que tu as rajouté au début).
1.2. Passer au mot immédiatement précédent.
Attention, je te conseille de lire et d'écrire tes shorts octet par octet, parce que théoriquement la table de relogements pourrait aussi être à une adresse impaire.

Et puis il faut remplir les 10 octets de 0x4e71 (nop), pas de 0x0000.

Au fait: c'est pour quoi faire?
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

20

Ouille ouille ouille...

On a donc un pointeur sur le tag... On remonte de 2.
On vérifie si il est égal à zéro, si oui on arrête tout.
Sinon, on lui ajoute 10, et on prend le mot d'avant...

Et ceci avant d'agrandir la variable ou après ?

C'est pour quoi faire -> cf mini message smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

21

Attention, je pense que j'ai dit une bêtise (désolé). Ça, c'était pour rajouter 10 octets au début. Toi, tu veux les rajouter à la fin, donc, après avoir redimensionné le fichier, tu déplaces tout entre le mot qui précède l'ancien emplacement du tag et le premier mot nul le précédant de 10 octets vers la fin. Donc:
char *p=oldtagptr-1; // ancien emplacement du tag - 1
while(*(p--) || *p) p--; // cherche le mot nul (pas while(*--p || *--p) à cause de l'évaluation paresseuse)
memmove(p+10,p,oldtagptr-p); // déplace la table de relogements
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

22

ok je vais essayer ça, merci smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

23

Hum... J'ai commencé mais y'a un truc curieux là :

char *p=oldtagptr-1; // ancien emplacement du tag - 1
while(*(p--) || *p) p--; // cherche le mot nul (pas while(*--p || *--p) à cause de l'évaluation paresseuse)
memmove(p+10,p,oldtagptr-p); // déplace la table de relogements


Avec le while tu ne fais que tester un seul octet ? Je croyais qu'on devait trouver un mot nul ?
Et puis char *p=oldtagptr-1; : Le premier mot à tester est {p-1,p} ou bien {p,p+1} ? Puisque dans le second cas on retombe sur le tag...


Edit #1 : Je comprends pas comment ça marche, mais ça marche grin
Quelques explications sur ce que j'ai dit au dessus seraient néanmoins les bienvenues smile

Edit #2 : Arf en fait ça marche à moitié... J'ai un prog qui "allonge" un ASM de 10 octets à chaque lancement, mais ça ne marche que quelques fois, ensuite l'asm est corrompu...
Voilà le code :

// Stoque le SYM_ENTRY de la variable dans "sym" et un pointeur vers son handle dans "handle"
handle=vat_heap(sym=(vat_open("asmprog")));

// Pointe "old" sur le tag avant redimention
char *old=(handle+*(unsigned short*)handle+1);

// Pointe "p" sur l'octet precedant le tag
char *p=old-1;

// Ajoute 10 octets à la variable
short add=10,size=*(unsigned short*)handle;
*(unsigned short*)HeapDeref(sym->handle=HeapRealloc(sym->handle,size+add+2))=size+add;

// Met à jour le handle après la redimention (je ne sais pas si c'est reellement utile)
handle=vat_heap(sym);

// cherche le mot nul (pas while(*--p || *--p) à cause de l'évaluation paresseuse)
while(*(p--) || *p) p--;

// déplace la table de relogements
memmove(p+10,p,old-p);

// Réécrit le tag
*(unsigned char*)(handle+*(unsigned short*)handle+1)=243;
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

24

Vertyos
a écrit : Avec le while tu ne fais que tester un seul octet ? Je croyais qu'on devait trouver un mot nul ?

Non, je teste un mot entier, mais octet par octet parce que l'adresse pourrait être impaire:
while(*(p--) || *p) p--; // cherche le mot nul (pas while(*--p || *--p) à cause de l'évaluation paresseuse)
Le code en rouge teste le deuxième octet du mot et décale le pointeur.
Si le deuxième octet était nul, le code en vert teste le premier octet pour voir s'il est également nul.
Si au moins un des octets est non-nul (donc si le mot est non nul), le code en bleu redécale le pointeur pour tomber sur le deuxième octet du mot d'avant.
Si les 2 octets étaient nuls, on se retrouve sur le premier octet du mot nul.
Et puis char *p=oldtagptr-1; : Le premier mot à tester est {p-1,p} ou bien {p,p+1} ?

Le premier mot à tester est {oldtagptr-2,oldtagptr-1}, c'est-à-dire {p-1,p}.
Edit #1
: Je comprends pas comment ça marche, mais ça marche grin
Quelques explications sur ce que j'ai dit au dessus seraient néanmoins les bienvenues smile

C'est fait.
Edit #2
: Arf en fait ça marche à moitié... J'ai un prog qui "allonge" un ASM de 10 octets à chaque lancement, mais ça ne marche que quelques fois, ensuite l'asm est corrompu...

Ton code est faux:
// Pointe "old" sur le tag avant redimention char *old=(handle+*(unsigned short*)handle+1);

Ici, tu crées un pointeur vers le bloc.
// Pointe "p" sur l'octet precedant le tag char *p=old-1;

Ici, tu en déduis un autre pointeur vers le bloc.
// Ajoute 10 octets à la variable
short add=10,size=*(unsigned short*)handle; *(unsigned short*)HeapDeref(sym->handle=HeapRealloc(sym->handle,size+add+2))=size+add;

Ici, tu agrandis le bloc, donc il peut être déplacé! Donc tous les pointeurs vers ton bloc ne sont plus valables à ce moment et doivent être recalculés!
// cherche le mot nul (pas while(*--p || *--p) à cause de l'évaluation paresseuse)
while(*(p--) || *p) p--;

// déplace la table de relogements memmove(p+10,p,old-p);

Ici, tu utilise le pointeur désormais invalidé.

Essaye:
// Stoque le SYM_ENTRY de la variable dans "sym" et un pointeur vers son handle dans "handle"
handle=vat_heap(sym=(vat_open("asmprog")));

// Ajoute 10 octets à la variable (partie 1)
short add=10,size=*(unsigned short*)handle;

// Met à jour le pointeur handle
handle=HeapDeref(sym->handle=HeapRealloc(sym->handle,size+add+2));

// Pointe "old" sur le tag avant redimensionnement
char *old=(handle+*(unsigned short*)handle+1);

// Ajoute 10 octets à la variable (partie 2)
*(unsigned short*)handle=size+add;

// Pointe "p" sur l'octet precedant le tag
char *p=old-1;

// cherche le mot nul (pas while(*--p || *--p) à cause de l'évaluation paresseuse)
while(*(p--) || *p) p--;

// déplace la table de relogements
memmove(p+add,p,old-p);

// Réécrit le tag
*(unsigned char*)(handle+*(unsigned short*)handle+1)=243;
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

25

Merci bien j'essaye tout de suite smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

26

Oops... Toujours pas tsss

Cette fois-ci, le programme qui redimentionne ne plante plus (alors qu'il 'gelait' occasionnellement avant). Mais au bout d'un certain nombre de redimentions, le programme ASM provoque une "Line 1111 Emulator".
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

27

Ah oui, je vois ce qui se passe! Autre problème: Le pointeur sym est également invalidé par HeapRealloc parce que HeapRealloc réorganise parfois la RAM entière, et donc l'assignement à sym->handle cause des ennuis.

Solution:
// Stoque le SYM_ENTRY de la variable dans "sym" et un pointeur vers son handle dans "handle"
handle=vat_heap(sym=(vat_open("asmprog")));

// Ajoute 10 octets à la variable (partie 1)
short add=10,size=*(unsigned short*)handle;

// Met à jour le pointeur handle [b](pas d'assignement à sym->handle)[/b]
handle=HeapDeref(HeapRealloc(sym->handle,size+add+2));

// Pointe "old" sur le tag avant redimensionnement
char *old=(handle+*(unsigned short*)handle+1);

// Ajoute 10 octets à la variable (partie 2)
*(unsigned short*)handle=size+add;

// Pointe "p" sur l'octet precedant le tag
char *p=old-1;

// cherche le mot nul (pas while(*--p || *--p) à cause de l'évaluation paresseuse)
while(*(p--) || *p) p--;

// déplace la table de relogements
memmove(p+add,p,old-p);

// Réécrit le tag
*(unsigned char*)(handle+*(unsigned short*)handle+1)=243;



D'ailleurs, il faut toujours vérifier si HeapRealloc n'a pas échoué! Donc:
// Stoque le SYM_ENTRY de la variable dans "sym" et un pointeur vers son handle dans "handle"
handle=vat_heap(sym=(vat_open("asmprog")));

// Ajoute 10 octets à la variable (partie 1)
short add=10,size=*(unsigned short*)handle;
HANDLE h=HeapRealloc(sym->handle,size+add+2);

// Si le redimensionnement a réussi (en le cas échéant, on ne peut rien faire)
if (h) {
 // Met à jour le pointeur handle
 handle=HeapDeref(h);

 // Pointe "old" sur le tag avant redimensionnement
 char *old=(handle+*(unsigned short*)handle+1);

 // Ajoute 10 octets à la variable (partie 2)
 *(unsigned short*)handle=size+add;

 // Pointe "p" sur l'octet precedant le tag
 char *p=old-1;

 // cherche le mot nul (pas while(*--p || *--p) à cause de l'évaluation paresseuse)
 while(*(p--) || *p) p--;

 // déplace la table de relogements
 memmove(p+add,p,old-p);

 // Réécrit le tag
 *(unsigned char*)(handle+*(unsigned short*)handle+1)=243;
}
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

28

Toujours pas sad
Apparement c'est une operation un peu délicate, et étant donné que c'était pour apprendre et non pour distribuer, je vais peut-être laisser tomber sad

A moins que tu ne veuille la source complete pour tester par toi-même ?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

29

C'est peut-être la meilleure idée. Mais je ne te garantis pas que j'aurai le temps d'aller voir suffisamment en détail.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

30

Thibaut: > Je crois qu'il y a un ROM_CALL pour obtenir l'adresse de la table des handles.
Vrai sous AMS 2.xx ("HeapTable", ROM_CALL 441), mais ça n'existe pas sous AMS 1.xx.
tthdex contient le source d'une méthode marchant sur toutes les versions d'AMS:
//-------------------------------------------------------------------------
// get the handle table (thanks to Zeljko Juric for this trick !)
//-------------------------------------------------------------------------
handle_table = *(unsigned long**)(unsigned long)(*((HANDLE*)HeapDeref+4+AMS_2xx));
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.