Forums Casio - Autres questions

Index du Forum > Autres questions > GCC Graph35+E System ERROR
Natnat
Hors ligne
Membre
Points: 69
Défis: 0
Message
Posté le 12/06/2018 16:45

GCC Graph35+E System ERROR :

Salut,

J'ai récemment (hier) installé la toolchain GCC pour compiler depuis Linux, donc plus besoin de passer par Windows ou le compilo tout moche en C89 de Casio. Il marche pas mal, et j'arrive à compiler et executer des petits add-ins simples avec.

J'ai plusieurs problèmes du coup:
Premièrement, j'arrive pas à include la <stdlib.h>, mais j'arrive à la bypass avec les syscall pour avoir malloc(), calloc(), realloc() et free() qui fonctionnent. C'est pas bien grave, mais c'est pas super clean de faire comme ça...

Et deuxièmement, avec un programme un peu plus lourd, j'ai une grosse System ERROR dont je n'arrive pas à trouver la source. Mon programme se compile sans erreurs, il est asez lourd (44k), mais ça reste raisonnable.
Les détails sont:
Type d'erreur: ADDRESS(W), donc j'écris à une addresse inexistante ou interdire.
TARGET=081028E1
PC=003002E4
Les valeurs sont toujours les mêmes.
Et j'ai donc regardé avec objdump le symbole qui contenait ce PC, et c'est _Hmem_SetMMU. Et le target est dans la section .bss apparemment, elle finit à 081028E5, mais il me semble qu'elle est enlevée lors du passage au g1a.
Ce code qui crash s'execute avant la main(), car même en mettant seulement ça dans main.c (mais en linkant avec le reste des .o), ça crash encore:

[brown]#include [gray]"fxlib.h"[/gray][/brown]
[purple]int[/purple] main(int isAppli, unsigned short OptionNum) {
    [green]//print something to screen[/green]
    locate(1, [maroon]1[/maroon]);
    Print((unsigned char*)[gray]"Test..."[/gray]);
    [green]//wait until we die[/green]
    [purple]int[/purple] key;
    [b][blue]while[/blue][/b](1) GetKey(&key);
    [b][blue]return[/blue][/b] 1;
}

Le problême ne semble arriver que quand je met mes autres .o dans le Makefile, mais ils n'executent pas de code tout seuls si on n'appelle pas leurs fonctions d'initialisation... Et ils fonctionnent parfaitement bien sur Linux.

J'espère avoir été assez clair dans l'exposition de mon problème, merci d'avance.




Lephenixnoir
Hors ligne
Administrateur
Points: 12792
Défis: 136
Message
Citer : Posté le 12/06/2018 17:05 | #
Premièrement, j'arrive pas à include la <stdlib.h>

Aha oui on n'a pas de lib standard au fait !

Tu peux récupérer les fichiers d'include dans une install du fx9860G-SDK (CASIO\fx-9860G SDK\OS\SH\include de mémoire) et linker avec libfx.a pour obtenir un équivalent semi-propre du SDK côté gcc.

TARGET=081028E1

FYI c'est dans la zone de RAM statique où on envoie la section .data. Et cette zone ne fait que 8k... hors tu est 0x28e1 à l'intérieur soit pas loin de 12k. Tu n'as pas eu un warning de ld au moment de linker tout ça... ?

Le problême ne semble arriver que quand je met mes autres .o dans le Makefile, mais ils n'executent pas de code tout seuls si on n'appelle pas leurs fonctions d'initialisation...

Peut-être que si tu ne les linkes pas la section .data est plus petite.

Je t'invite à chercher ce qui prend de la place... on a des solutions si tu as besoin de plus de RAM, mais si on pousse un peu ça casse la compatibilité SH3. À toi de voir !
----------------------------------
Rise.
Natnat
Hors ligne
Membre
Points: 69
Défis: 0
Message
Citer : Posté le 12/06/2018 18:01 | #
Lephenixnoir a écrit :
Aha oui on n'a pas de lib standard au fait !

Franchement, c'est pas grave, on s'en sort toujours avec les syscalls ou en redéfinissant les fonctions manuellement. Et je link déjà avec libfx.a pour avoir accès à une partie des fonctions.

Lephenixnoir a écrit :

Le problême ne semble arriver que quand je met mes autres .o dans le Makefile, mais ils n'executent pas de code tout seuls si on n'appelle pas leurs fonctions d'initialisation...

Peut-être que si tu ne les linkes pas la section .data est plus petite.

Oui, effectivement, elle est plus petite...

Lephenixnoir a écrit :
Et cette zone ne fait que 8k... hors tu est 0x28e1 à l'intérieur soit pas loin de 12k. Tu n'as pas eu un warning de ld au moment de linker tout ça... ?

Ba, la raison pour laquelle je ne m'en suis pas douté, c'est justement parceque ld m'a pas parlé de ça dans les warnings, mais seulement des choses en rapport avec addin.ld (et j'ai -Wall pourtant...).

/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.1.0/../../../../sh3eb-elf/bin/ld:bin/addin.ld:5: warning: redeclaration of memory region `rom'
/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.1.0/../../../../sh3eb-elf/bin/ld:bin/addin.ld:6: warning: redeclaration of memory region `ram'
/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.1.0/../../../../sh3eb-elf/bin/ld: warning: section `.bss' type changed to PROGBITS


La section .data, c'est bien les données statiques définies directement dans les .c? Donc si je malloc tout ce qui prend de la place dedans, ça peut résoudre le problème ou il va vraiment falloir que je trouve comment réduire encore la place que je prend?
Sinon, si je passe sous Gint (enfin, si j'arrive à l'installer correctement, ld me dit que "the input file 'build/version.o' has no sections"), ça peut s'agrandir ou je suis encore à 8k?
Lephenixnoir
Hors ligne
Administrateur
Points: 12792
Défis: 136
Message
Citer : Posté le 12/06/2018 18:20 | #
La section .data, c'est bien les données statiques définies directement dans les .c? Donc si je malloc tout ce qui prend de la place dedans, ça peut résoudre le problème ou il va vraiment falloir que je trouve comment réduire encore la place que je prend?

C'est principalement les variables statiques et globales. Donc en effet si tu fais du malloc() tu vas libérer de la place : c'est la première solution que j'allais te proposer.

Sache que le tas fait 48k en principe donc tu as déjà une marge de manœuvre beaucoup plus large !

Sinon, si je passe sous Gint (enfin, si j'arrive à l'installer correctement, ld me dit que "the input file 'build/version.o' has no sections"), ça peut s'agrandir ou je suis encore à 8k?

En principe c'est toujours 8k ; on a cependant les choses suivantes :
- Sous SH4, c'est 64k (gint ou pas)
- La SH4 dispose de 256k de RAM inutilisés à 0x88010000 (gint ou pas)
- gint vole une partie de la RAM de 12k pour s'installer sans perturber l'application ; un utilisateur confirmé peut récupérer de la place dans cette zone

Et ld a raison, le fichier build/version.o ne contient en effet pas de sections, juste un symbole qui permet de connaître la version de gint à l'exécution. Mais en principe de n'est pas un problème. Tu peux poster les détails de ta compilation sur le topic de gint pour que j'essaie de comprendre pourquoi ld le refuse ?
----------------------------------
Rise.
Natnat
Hors ligne
Membre
Points: 69
Défis: 0
Message
Citer : Posté le 12/06/2018 19:43 | #
Lephenixnoir a écrit :
La section .data, c'est bien les données statiques définies directement dans les .c? Donc si je malloc tout ce qui prend de la place dedans, ça peut résoudre le problème ou il va vraiment falloir que je trouve comment réduire encore la place que je prend?

C'est principalement les variables statiques et globales. Donc en effet si tu fais du malloc() tu vas libérer de la place : c'est la première solution que j'allais te proposer.

Sache que le tas fait 48k en principe donc tu as déjà une marge de manœuvre beaucoup plus large !


Hmm, j'ai réessayé en malloc(), et cette fois TARGET vaut 081000BD, ce qui fait normalement 189 octets... Et pourtant, ça crash encore... (peut-être parce que c'est pas aligné?)
Et j'appelle même pas mes malloc au point où ça crash, c'est toujours avant le main().
Et là, franchement je pense pas pouvoir réduire plus, j'ai déjà malloc tous mes gros tableaux...
Lephenixnoir
Hors ligne
Administrateur
Points: 12792
Défis: 136
Message
Citer : Posté le 12/06/2018 20:31 | #
Hmm, j'ai réessayé en malloc(), et cette fois TARGET vaut 081000BD, ce qui fait normalement 189 octets... Et pourtant, ça crash encore... (peut-être parce que c'est pas aligné?)

Ça c'est très probable. C'est probablement pas malloc() qui renvoie une adresse aussi moche. Maintenant que j'y pense, le x86 peut faire des accès non alignés n'est-ce-pas ? Si tu t'en sers dans ton programme original, alors il va falloir le retoucher pour qu'il évite.

Ce n'est plus un problème de zone de mémoire, j'en suis à peu près certain. C'est le même endroit du code (le syscall Hmem_setMMU() qui plante ?

Note : quand tu linkes, tu peux définir le flag -M pour avoir une map complète du résultat du linker, très pratique pour debugger. (Du coup c'est probablement -Wl,-M si tu linkes avec gcc.)
----------------------------------
Rise.
Natnat
Hors ligne
Membre
Points: 69
Défis: 0
Message
Citer : Posté le 12/06/2018 21:48 | #
C'est définitivement pas malloc qui me donne des addresses pas alignées comme ça... (enfin calloc dans mon cas).
Et oui, c'est toujours dans cette routine, donc évidemment le mov.l aime pas cette adresse :/
Par contre, c'est toujours avant mon main, donc avant que j'alloue quoi que ce soit, ce qui veut dire que j'ai probablement une section qui est pas alignée... Et même sur la version PC, j'ai pas le moindre pointeur non aligné que je crée moi (enfin, les char* sont pas alignés mais c'est tout), ça sort tout directement de malloc, calloc ou realloc, avec au pire un offset dans u de struct que je pack pas pour laisser GCC aligner ce qu'il veut.
À chaque fois que j'essaie de compiler avec un '-M', je me prend une erreur de compilation disant que les objets sont absents...
Je regarderai demain si je trouve plus d'infos avec objdump et le '-M'.

Mais merci beaucoup de m'avoir aidé
Lephenixnoir
Hors ligne
Administrateur
Points: 12792
Défis: 136
Message
Citer : Posté le 12/06/2018 21:55 | #
Et oui, c'est toujours dans cette routine, donc évidemment le mov.l aime pas cette adresse :/

Tu m'inquiètes là. Hmem_SetMMU() ça n'a pas de raison de planter (du tout). L'output de -M m'intéresse beaucoup du coup.

enfin, les char* sont pas alignés mais c'est tout

Un char * c'est toujours aligné enfin !

Tu ne dois pas compiler avec -M, tu dois linker avec -Wl,-M, c'est très différent...
----------------------------------
Rise.
Natnat
Hors ligne
Membre
Points: 69
Défis: 0
Message
Citer : Posté le 13/06/2018 14:04 | # | Fichier joint
Lephenixnoir a écrit :
Tu ne dois pas compiler avec -M, tu dois linker avec -Wl,-M, c'est très différent

Oui, effectivement...
Hmm, j'ai recompilé (enfin linké, du coup) avec -Wl,-M, le résultat tient pas en entier dans le scrollback de ma console, je le met donc en fichier joint (make > make.txt, donc il y a pas les warnings mais il y a tout le -Wl,-M).

Le System ERROR m'indique toujours ADDRESS(W) avec TARGET=081000BD (qui tombe dans mon string.o, en face de '_ebss = .') et PC=003002E4 qui tombe dans bin/crt0.o dans la section .pretext dans le symbole 'initialize', pile poil sur le symbole _Hmem_SetMMU():

$ objdump -x asm.elf |grep 003002e4                                                                                                  
003002e4 l       .text  00000000 _Hmem_SetMMU

$ objdump -x asm.elf |grep 081000bd
081000bd g       .bss   00000000 _bssdatasize
081000bd g       .bss   00000000 _bbss


Le contenu de mon string.c, si ça peut aider, c'est des fonctions qui me servent vu que j'ai pas accès à la lib standard, elles ne reposent pas sur des trucs trop chelous, donc je vois pas trop comment ça peut poser problème:

#include "string.h"

char RETVAL[33];

void strcpyl(char* src, char* dest, int max) {
    for(int i=0; i<max&&*src; i++) *(dest++)=*(src++);
}
int strcmpl(char* src, char* cmp, int max) {
    for(int i=0; i<max&&*src; i++) {
        if(*(cmp++)!=*(src++)) return 0;
    }
    return 1;
}
int strsuml(char* str, int max) {
    int hash=7;
    for(int i=0; i<max&&str[i]; i++) {
        hash*=31;
        hash+=str[i];
    }
    return hash;
}
int strlenl(char* str, int max) {
    int i=0;
    while(*str&&i<max) {
        str++;
        i++;
    }
    return i;
}

void strcpyd(char* src, char* dest) {
    while(*src) *(dest++)=*(src++);
}
int strcmpd(char* src, char* cmp) {
    while(*src||*cmp) {
        if(*(cmp++)!=*(src++)) return 0;
    }
    return 1;
}
int strsumd(char* str) {
    int hash=7;
    for(int i=0; str[i]; i++) {
        hash*=31;
        hash+=str[i];
    }
    return hash;
}
int strlend(char* str) {
    int i=0;
    while(*str) {
        str++;
        i++;
    }
    return i;
}

void strcpyt(char* src, char* dest, char end) {
    while(*src!=end) *(dest++)=*(src++);
}
int strcmpt(char* src, char* cmp, char end) {
    while(*src!=end||*cmp!=end) {
        if(*(cmp++)!=*(src++)) return 0;
    }
    return 1;
}
int strsumt(char* str, char end) {
    int hash=7;
    for(int i=0; str[i]!=end; i++) {
        hash*=31;
        hash+=str[i];
    }
    return hash;
}
int strlent(char* str, char end) {
    int i=0;
    while(*str!=end) {
        str++;
        i++;
    }
    return i;
}

#define hexdigit(val) ((val)>9?((val)+'a'-10):((val)+'0'))
#define decdigit(val) ((val)+'0')
char* itohex(int val, int digits) {
    for(int i=0; i<digits; i++) {
        int part=val>>4*i;
        RETVAL[digits-i-1]=hexdigit(part&0xf);
    }
    RETVAL[digits]='\0';
    return RETVAL;
}
char* itobin(int val, int digits) {
    for(int i=0; i<digits; i++) {
        int part=val>>i;
        RETVAL[digits-i-1]=decdigit(part&0x1);
    }
    RETVAL[digits]='\0';
    return RETVAL;
}
char* itodec(int val) {
    int pos=31;
    int neg=0;
    RETVAL[32]='\0';
    if(val==0) {
        RETVAL[31]='0';
        return RETVAL+31;
    } else if(val<0) {
        neg=1;
        val=-val;
    }
    while(val) {
        RETVAL[pos--]=decdigit(val%10);
        val/=10;
    }
    if(neg) {
        RETVAL[pos--]='-';
    }
    return RETVAL+pos+1;
}

#define digitval(digit) (((digit)>='a')?((digit)-'a'+10):((digit)>='A')?((digit)-'A'+10):(digit)-'0')
#define isDec(c) (((c)>='0'&&(c)<='9'))
#define isHex(c) (((c)>='A'&&(c)<='F')||((c)>='a'&&(c)<='f')||isDec((c)))
#define isBin(c) ((c)=='0'||(c)=='1')
int hextoi(char* str) {
    int val=0;
    while(isHex(*str)) {
        val<<=4;
        val|=digitval(*str);
        str++;
    }
    return val;
}
int dectoi(char* str) {
    int val=0;
    int sgn=*str=='-'?-1:1;
    if(*str=='-'||*str=='+') str++;
    while(isDec(*str)) {
        val*=10;
        val|=digitval(*str);
        str++;
    }
    return val*sgn;
}
int bintoi(char* str) {
    int val=0;
    while(isBin(*str)) {
        val<<=1;
        val|=digitval(*str);
        str++;
    }
    return val;
}
Lephenixnoir
Hors ligne
Administrateur
Points: 12792
Défis: 136
Message
Citer : Posté le 13/06/2018 14:22 | #
Wow, tes noms de fichiers sources vendent du rêve

pile poil sur le symbole _Hmem_SetMMU():

Tu peux désassembler à cette adresse, ainsi que 15-20 octets juste avant, qu'on puisse y voir clair ?
----------------------------------
Rise.
Natnat
Hors ligne
Membre
Points: 69
Défis: 0
Message
Citer : Posté le 13/06/2018 14:42 | #
Lephenixnoir a écrit :
Wow, tes noms de fichiers sources vendent du rêve

Hmm, je sais pas trop comment prendre ça...

Lephenixnoir a écrit :
pile poil sur le symbole _Hmem_SetMMU():

Tu peux désassembler à cette adresse, ainsi que 15-20 octets juste avant, qu'on puisse y voir clair ?

Euh, ça provient du crt0.s normalement, qui provient de Ce topic...

objdump -d asm.elf me donne ça (j'ai pris les quelques routines autour, au cas où):

00300286 <L_close_finds>:
  300286:    4c 0b           jsr    @r12
  300288:    64 d3           mov    r13,r4
  30028a:    7d 01           add    #1,r13
  30028c:    3d e3           cmp/ge    r14,r13
  30028e:    8b fa           bf    300286 <L_close_finds>
  300290:    4f 26           lds.l    @r15+,pr
  300292:    6c f6           mov.l    @r15+,r12
  300294:    6d f6           mov.l    @r15+,r13
  300296:    d2 0a           mov.l    3002c0 <Bkey_Set_RepeatTime_Default>,r2    ! 300308 <_Bkey_Set_RepeatTime_Default>
  300298:    42 2b           jmp    @r2
  30029a:    6e f6           mov.l    @r15+,r14
  30029c:    00 00           .word 0x0000
    ...

003002a0 <address_two>:
  3002a0:    88 01           cmp/eq    #1,r0
  3002a2:    e0 00           mov    #0,r0

003002a4 <address_one>:
  3002a4:    08 10           .word 0x0810
  3002a6:    20 00           mov.b    r0,@r0

003002a8 <Hmem_SetMMU>:
  3002a8:    00 30           .word 0x0030
  3002aa:    02 e4           mov.b    r14,@(r0,r2)

003002ac <GLibAddinAplExecutionCheck>:
  3002ac:    00 30           .word 0x0030
  3002ae:    03 2c           mov.b    @(r0,r2),r3

003002b0 <CallbackAtQuitMainFunction>:
  3002b0:    00 30           .word 0x0030
  3002b2:    03 14           mov.b    r1,@(r0,r3)

Tous les accès mémoire sont des mov.b, donc il devrait même pas y avoir de problème d'alignement :/
Lephenixnoir
Hors ligne
Administrateur
Points: 12792
Défis: 136
Message
Citer : Posté le 13/06/2018 14:53 | #
Hmm, je sais pas trop comment prendre ça...

Un compliment : un projet qui contient linker.c, mmu.c ou stack.c est forcément intéressant (de mon point de vue)

Oui, je me doute que ça vient de crt0.s, mais si c'est un problème de linker ça ne se verra pas dans les sources... À vrai dire je n'ai pas d'idée derrière la tête de ce que pourrait être la cause du problème.

On dirait que tu n'as pas désassemblé la fonction elle-même (3002e4). Si ça ne te dérange pas, tu peux uploader le fichier ELF et ça ira plus vite pour moi pour chercher.
----------------------------------
Rise.
Natnat
Hors ligne
Membre
Points: 69
Défis: 0
Message
Citer : Posté le 13/06/2018 14:59 | # | Fichier joint
Lephenixnoir a écrit :
On dirait que tu n'as pas désassemblé la fonction elle-même (3002e4). Si ça ne te dérange pas, tu peux uploader le fichier ELF et ça ira plus vite pour moi pour chercher.

Woops, mauvais symbole

003002dc <exit_handler>:
  3002dc:    00 30           .word 0x0030
  3002de:    02 54           mov.b    r5,@(r0,r2)

003002e0 <main>:
  3002e0:    00 30           .word 0x0030
  3002e2:    7d 70           add    #112,r13

003002e4 <_Hmem_SetMMU>:
  3002e4:    d2 13           mov.l    300334 <sc_addr>,r2    ! 80010070 <__JumpTableTOP>
  3002e6:    d0 01           mov.l    3002ec <_Hmem_SetMMU+0x8>,r0    ! 3fa
  3002e8:    42 2b           jmp    @r2
  3002ea:    00 09           nop    
  3002ec:    00 00           .word 0x0000
  3002ee:    03 fa           .word 0x03fa

003002f0 <_Bdel_cychdr>:
  3002f0:    d2 10           mov.l    300334 <sc_addr>,r2    ! 80010070 <__JumpTableTOP>
  3002f2:    d0 01           mov.l    3002f8 <_Bdel_cychdr+0x8>,r0    ! 119
  3002f4:    42 2b           jmp    @r2
  3002f6:    00 09           nop    
  3002f8:    00 00           .word 0x0000
  3002fa:    01 19           .word 0x0119

003002fc <_BfileFLS_CloseFile>:
  3002fc:    d2 0d           mov.l    300334 <sc_addr>,r2    ! 80010070 <__JumpTableTOP>
  3002fe:    d0 01           mov.l    300304 <_BfileFLS_CloseFile+0x8>,r0    ! 1e7
  300300:    42 2b           jmp    @r2
  300302:    00 09           nop    
  300304:    00 00           .word 0x0000
  300306:    01 e7           mul.l    r14,r1

Celui-là devrait être mieux... Effectivement, là on a bien un mov.l
Je met le .elf en fichier joint quand même, mais je le renomme en .txt, il accepte pas les .elf :/
Lephenixnoir
Hors ligne
Administrateur
Points: 12792
Défis: 136
Message
Citer : Posté le 13/06/2018 18:05 | # | Fichier joint
Oui mais voilà : cette instruction ne fait pas d'accès mémoire en écriture.

Donc, c'est pas là. Genre pas du tout.

char RETVAL[33];

Je pense que c'était évident en fait... Mets 36.

La section est pas alignée, voilà tout. 0x081000bd c'est congru à 1 modulo 4, crt0.s faisant évidemment la copie 4 octets parce que c'est 4 fois plus rapide, ça plante parce que c'est pas aligné. Et c'est peut-être une écriture parce qu'il calcule bssdatasize et écrit la valeur en mémoire avant de wiper la section.

Bon évidemment 36 ce n'est pas un vrai fix. Éventuellement tu peux récupérer les linkers scripts de gint qui sont sensiblement plus rodés contre ce genre de problèmes puisque j'en ai mangé pendant des semaines. x) Je te joins celui pour la Graph 85, qui devrait marcher out-of-the-box, si jamais ça t'intéresse.

Edit : oupsie, euh, non, ça va pas marcher tout seul, my bad. On peut essayer de corriger le tien, c'est l'affaire de quelques BLOCK(4) par-ci-par-là.
----------------------------------
Rise.
Natnat
Hors ligne
Membre
Points: 69
Défis: 0
Message
Citer : Posté le 13/06/2018 18:39 | #
Lephenixnoir a écrit :
Oui mais voilà : cette instruction ne fait pas d'accès mémoire en écriture.

Donc, c'est pas là. Genre pas du tout.

char RETVAL[33];

Je pense que c'était évident en fait... Mets 36.

Oui, effectivement, ça marche maintenant

Lephenixnoir a écrit :
Bon évidemment 36 ce n'est pas un vrai fix.

Vrai fix ou pas, au pire ça m'obligera à aligner mas variables statiques, ce qui est toujours une bonne chose à faire...

Lephenixnoir a écrit :
Edit : oupsie, euh, non, ça va pas marcher tout seul, my bad. On peut essayer de corriger le tien, c'est l'affaire de quelques BLOCK(4) par-ci-par-là.

Franchement, c'est pas vraiment nécessaire, je vais essayer de comprendre comment il fonctionne, mais si j'y arrive pas, c'est pas grave, tant que ça marche.

Merci beaucoup
Lephenixnoir
Hors ligne
Administrateur
Points: 12792
Défis: 136
Message
Citer : Posté le 13/06/2018 19:18 | #
Vrai fix ou pas, au pire ça m'obligera à aligner mas variables statiques, ce qui est toujours une bonne chose à faire...

C'est le boulot du compilateur et linker pour être honnête, pas le tien.

Il y a deux choses que tu dois ajouter à la section .bss et à la section .data :

        .bss : {
                _bbss = . ;
                _bssdatasize = . ;
                LONG(0);        /* bssdatasize */
                *(.bss) *(COMMON);
                _ebss = . ;
        } > ram


        .bss ALIGN(4) : ALIGN(4) {
                _bbss = . ;
                _bssdatasize = . ;
                LONG(0);        /* bssdatasize */
                *(.bss) *(COMMON);
                . = ALIGN(4);
                _ebss = . ;
        } > ram

Les deux premiers ALIGN(4) forcent l'alignement de début de la section : un est pour l'adresse en ROM où les données d'origine résident (utile uniquement pour .data), le second est l'endroit de la RAM où on les envoie.

Le troisième ALIGN(4) indique au linker de rajouter jusqu'à 3 octets à la fin pour que la taille soit aussi multiple de 4.
----------------------------------
Rise.
Natnat
Hors ligne
Membre
Points: 69
Défis: 0
Message
Citer : Posté le 13/06/2018 20:10 | #

/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.1.0/../../../../sh3eb-elf/bin/ld:bin/addin.ld:5: warning: redeclaration of memory region `rom'
/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.1.0/../../../../sh3eb-elf/bin/ld:bin/addin.ld:6: warning: redeclaration of memory region `ram'
/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.1.0/../../../../sh3eb-elf/bin/ld: address 0x30a5d0 of asm.elf section `.bss' is not within region `ram'
/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.1.0/../../../../sh3eb-elf/bin/ld: asm.elf section `B' will not fit in region `ram'
/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.1.0/../../../../sh3eb-elf/bin/ld: address 0x30a5d0 of asm.elf section `.bss' is not within region `ram'
/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.1.0/../../../../sh3eb-elf/bin/ld: section .data LMA [000000000030a4fc,000000000030a503] overlaps section .bss LMA [000000000030a4fc,000000000030a5cf]
/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.1.0/../../../../sh3eb-elf/bin/ld: region `ram' overflowed by 18446744073577408464 bytes
/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.1.0/../../../../sh3eb-elf/bin/ld: warning: section `.bss' type changed to PROGBITS
collect2: error: ld returned 1 exit status

Hmm, les ALIGN(4) me laissent pas linker, dès lors que le les met sur la section .bss, et j'ai la même erreur si je les met sur .data aussi... Mais sans, ça fonctionne si j'aligne à la main les variables, donc je crois que je vais faire sans.
N'empêche, un dépassement de 18Go, c'est pas mal

Tant pis pour le linker script.
Lephenixnoir
Hors ligne
Administrateur
Points: 12792
Défis: 136
Message
Citer : Posté le 13/06/2018 20:20 | #
Aah, c'est ma faute, j'ai sauté des détails. Je te dois une explication rapide.

} > ram

Ceci signifie que ld assigne à ces données des adresses virtuelles qui sont dans la RAM. Mais là on fait quelque chose d'un peu spécial : les données existent à deux endroits différents au cours du programme (d'abord dans la ROM, puis après l'initialisation du programme, dans la RAM) et donc les données ont aussi des adresses dans la ROM (d'où on les copie). Cette adresse est donnée dans le AT(). La section .bss n'en a pas puisqu'elle ne contient que des 0 et on ne la charge donc pas dans la ROM.

Et donc, grosso modo, les ALIGN(4) en haut ont dit (et je l'ai oublié) à ld de placer les adresses virtuelles à l'adresse ALIGN(4), ce qui correspond à quelques octets près à la « position actuelle de ld ». Et en l'occurrence ld est en train de compter dans la ROM. Donc, je me suis contredit :
- D'une part j'ai dit que les données allaient in fine être dans la RAM
- D'autre part j'ai aligné à une adresse dans la ROM

Et donc il n'est pas content et me dit que je n'ai pas rempli ma part du contrat :

address 0x30a5d0 of asm.elf section `.bss' is not within region `ram'

Dans mes linker scripts plus récents, j'utilise un mécanisme plus souple qui prend cette forme-là, et qui me paraît assez clair :

} > ram AT> rom

Et en gros ça se passe mieux.

Les problèmes de linker sont toujours assez compliqués et tu risques d'en re-croiser. La procédure que je suis en général est la suivante :

1. Linker avec -Wl,-M
2. Vérifier que les bons fichiers sont inclus par le linker et que les symboles qui m'intéressent y sont
3. Vérifier que les sections ont des tailles qui n'explosent pas
4. Vérifier que toutes les adresses importantes sont alignées à 4 octets (ou, dans le cas de gint, 16 octets)
5. Autres détails dépendant de ce que je suis en train de faire dans le contexte.

Enfin voilà, bon courage pour ta suite, et si jamais, tu disposes de l'attribut gcc __attribute__((aligned(n))) qui te permet d'aligner à l'adresse que tu veux (n étant une puissance de 2).
----------------------------------
Rise.


Index du Forum > Autres questions > GCC Graph35+E System ERROR

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2018 | Il y a 28 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire indépendant, géré bénévolement et n'est donc pas affilié à Casio | Toute reproduction de Planète Casio, même partielle, est interdite
Les fichiers, programmes et autres publications présents sur Planète Casio restent la propriété de leurs auteurs respectifs et peuvent être soumis à des licences ou des copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd