Ps2toolchain: Les derniers octets du fichier ELF sont parfois corrompus

Créé le 15 janv. 2020  ·  9Commentaires  ·  Source: ps2dev/ps2toolchain

Le morceau de code suivant produira une sortie non valide :

#include <stdio.h>

extern const int i1, i2, i3, i4;

int main()
{
        printf("i1=%d\n", i1);
        printf("i2=%d\n", i2);
        printf("i3=%d\n", i3);
        printf("i4=%d\n", i4);

        return 0;
}

const int dum1=1;
const int dum2=2;
const int dum3=3;
//const int dum4=4;
//const int dum5=5;
//const int dum6=6;
const int i1=1111;
const int i2=2222;
const int i3=3333;
const int i4=4444;

Lorsqu'ils sont essayés avec un nombre aléatoire de constantes fictives, les résultats varient de :
Bon:

i1=1111
i2=2222
i3=3333
i4=4444

Au pire :

i1=1111
i2=2222
i3=3333
i4=0
i1=1111
i2=2222
i3=0
i4=0



md5-a7a998816ff6355b19ebaf6bb16f20b1



i1=1111
i2=0
i3=0
i4=0



md5-50fa41c3352404f2cadd42c17104c34f



ee-gcc -o hello.elf hello.c
ps2client -h 192.168.1.10 execee host:hello.elf

Ce bogue fait que size_ds34bt_irx et/ou size_ds34usb_irx dans OPL sont 0. Provoquant un plantage aléatoire d'OPL au démarrage (écran noir). L'ajout d'une ligne de code à un endroit aléatoire dans OPL entraînerait l'apparition et la disparition de ce bogue.

Les valeurs non valides semblent se trouver dans les 128 derniers bits du fichier ELF, lorsqu'elles sont visualisées avec :
ee-objdump -D hello.elf

Les valeurs dans le fichier elf sont bonnes, il semble donc qu'il y ait un problème quelque part lors du chargement de l'elf.

Commentaire le plus utile

J'ai trouvé le bogue :

crt0 efface la section .bss, en unités de 16 octets/128 bits. Il nécessite que la section .bss soit alignée sur au moins 16 octets/128 bits. Auparavant, cela était garanti par le fichier de liens dans ps2sdk. Cependant, le linkerscript par défaut dans binutils (j'ai ajouté ici : https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) n'aligne pas correctement la section .bss pour crt0. Les dernières valeurs de .sdata doivent également être effacées.

J'ai créé un correctif pour le script de liaison binutils intégré ici . Il fera partie du PR newlib.

Tous les 9 commentaires

Incroyable comment vous êtes arrivé à cette conclusion

S'il semble que les valeurs dans l'ELF sont bonnes, pourquoi ne pensez-vous pas qu'il s'agit d'un problème de ps2link ? Et si vous utilisiez une autre méthode pour charger votre ELF ?
Je pense que c'est peut-être dû au fait que ps2link n'efface pas la mémoire. La fonction sceSifLoadElf() ne met aucune mémoire à zéro, donc des données incorrectes peuvent apparaître si la mémoire n'est pas effacée avant que l'ELF ne soit chargé avec cette fonction.

S'il semble que les valeurs dans l'ELF sont bonnes, pourquoi ne pensez-vous pas qu'il s'agit d'un problème de ps2link ? Et si vous utilisiez une autre méthode pour charger votre ELF ?

Oui, les données du fichier ELF semblent bonnes, donc je suppose que le titre de ce numéro est un peu trompeur. Je vais essayer un autre chargeur.

Je pense que c'est peut-être dû au fait que ps2link n'efface pas la mémoire. La fonction sceSifLoadElf() ne met aucune mémoire à zéro, donc des données incorrectes peuvent apparaître si la mémoire n'est pas effacée avant que l'ELF ne soit chargé avec cette fonction.

Les const int sont dans la section .sdata (données statiques). Je pense que la section .sdata est copiée du fichier elf dans la mémoire en unités de 16 octets/128 bits quelque part. Peut-être que si la section .sdata n'est pas un multiple de 128 bits, les données restantes ne sont pas copiées, laissant des zéros à sa place ?
Ou peut-être que la section .sdata est copiée correctement, mais qu'une autre section mise à zéro n'est pas correctement alignée à côté ? Et la mise à zéro se produit après la copie du .sdata ?

Bonjour,
Afin de voir si @ sp193 avait raison et que le problème était dans le ps2link , j'ai modifié l'exemple et maintenant il utilise les fonctions scr_prinf pour voir la sortie à l'écran et être facilement exécuté par ULaunchELF ou chargé dans PCSX2

Le contenu du dossier

#include <stdio.h>

void init_scr(void);
void scr_printf(const char *, ...) __attribute__((format(printf,1,2)));

extern const int i1, i2, i3, i4;

int main()
{
   init_scr();
   scr_printf("i1=%d\n", i1);
   scr_printf("i2=%d\n", i2);
   scr_printf("i3=%d\n", i3);
   scr_printf("i4=%d\n", i4);

   while(1) {}

   return 0;
}

const int dum1=1;
const int dum2=2;
const int dum3=3;
const int dum4=4;
const int dum5=5;
const int i1=1111;
const int i2=2222;
const int i3=3333;
const int i4=4444;

Processus de compilation

ee-gcc -o hello.elf hello.c -L$PS2SDK/ee/lib -ldebug

La sortie, dans ce cas, en utilisant PCSX2
Screenshot 2020-01-15 at 09 47 54

Comme vous pouvez le voir, le résultat est le même que celui commenté par @rickgaiser .

i1=1111
i2=2222
i3=3333
i4=0

Merci

ps2link utilise la fonction SifLoadElf pour charger le fichier elf :
https://github.com/ps2dev/ps2link/blob/1ec566c54bb8b567ee0a702982b392f37807b5e2/ee/cmdHandler.c#L138

de ps2sdk :
https://github.com/ps2dev/ps2sdk/blob/5385a6ccd9db8c9fa54ecfd8af45322a5908bf6d/ee/kernel/src/loadfile.c#L129

Cela finit par appeler une fonction RPC sur l'IOP. Fait partie de LOADFILE.

Serait-ce un bogue dans LOADFILE ? Ou peut-être que notre chaîne d'outils n'aligne pas les sections comme LOADFILE les attend ? Les sbv_patches pourraient-ils résoudre ce problème ? Je peux voir qu'ils corrigent LOADFILE, mais corrigent-ils quelque chose en rapport avec cela ?

Le correctif SBV pour LOADFILE consistait à activer la fonction RPC pour LoadModuleBuffer(). Pour une raison quelconque, cette fonction n'est pas prise en charge par la première version de LOADFILE. Sony le corrige aussi, donc c'est clairement quelque chose qui a été négligé.

J'ai trouvé le bogue :

crt0 efface la section .bss, en unités de 16 octets/128 bits. Il nécessite que la section .bss soit alignée sur au moins 16 octets/128 bits. Auparavant, cela était garanti par le fichier de liens dans ps2sdk. Cependant, le linkerscript par défaut dans binutils (j'ai ajouté ici : https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) n'aligne pas correctement la section .bss pour crt0. Les dernières valeurs de .sdata doivent également être effacées.

J'ai créé un correctif pour le script de liaison binutils intégré ici . Il fera partie du PR newlib.

IIRC, vous voulez toujours vous assurer que les sections sont alignées sur 128 bits. Je pense que cela a quelque chose à voir avec les alignements DMA ou quelque chose du genre, mais pas sûr.

Ce problème a été résolu avec les PR newlib qui ont été récemment fusionnés, en particulier ce commit : https://github.com/ps2dev/ps2toolchain/commit/f5544b8d68fbdf611e277e9583714ae6627f3a61

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

terremoth picture terremoth  ·  8Commentaires

SignalSpectre picture SignalSpectre  ·  8Commentaires

lptech1024 picture lptech1024  ·  4Commentaires

meleyal picture meleyal  ·  85Commentaires

ashmoran picture ashmoran  ·  24Commentaires