Ps2toolchain: Os últimos bytes do arquivo ELF às vezes são corrompidos

Criado em 15 jan. 2020  ·  9Comentários  ·  Fonte: ps2dev/ps2toolchain

O seguinte trecho de código produzirá uma saída inválida:

#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;

Quando tentado com um número aleatório de constantes fictícias, os resultados variam de:
Boa:

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

Para mal:

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

Este bug faz com que size_ds34bt_irx e/ou size_ds34usb_irx no OPL seja 0. Causando uma falha aleatória do OPL na inicialização (tela preta). Adicionar uma linha de código em um local aleatório no OPL faria com que esse bug aparecesse e desaparecesse.

Os valores inválidos parecem estar nos últimos 128 bits do arquivo ELF, quando visualizados usando:
ee-objdump -D hello.elf

Os valores no arquivo elf são bons, então parece dar errado em algum lugar ao carregar o elf.

Comentários muito úteis

Encontrei o erro:

crt0 limpa a seção .bss, em unidades de 16 bytes/128 bits. Requer que a seção .bss esteja alinhada a pelo menos 16 bytes/128 bits. Anteriormente, isso era garantido pelo linkerfile no ps2sdk. No entanto, o script de vinculação padrão no binutils (adicionei aqui: https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) não alinha a seção .bss corretamente para crt0. Resultando nos últimos valores em .sdata a serem limpos também.

Eu criei uma correção para o script de linker binutils embutido aqui . Será parte do PR newlib.

Todos 9 comentários

Incrível como você chegou a essa conclusão

Se parece que os valores dentro do ELF são bons, por que você não acha que é um problema do ps2link? E se você usasse outro método para carregar seu ELF?
Eu acho que é possivelmente causado por ps2link não limpar a memória. A função sceSifLoadElf() não zera nenhuma memória, portanto, dados incorretos podem aparecer se a memória não for apagada antes que o ELF seja carregado com essa função.

Se parece que os valores dentro do ELF são bons, por que você não acha que é um problema do ps2link? E se você usasse outro método para carregar seu ELF?

Sim, os dados no arquivo ELF parecem bons, então acho que o título desta edição é um pouco enganoso. Vou tentar outro carregador.

Eu acho que é possivelmente causado por ps2link não limpar a memória. A função sceSifLoadElf() não zera nenhuma memória, portanto, dados incorretos podem aparecer se a memória não for apagada antes que o ELF seja carregado com essa função.

Os const int's estão na seção .sdata (dados estáticos). Acho que a seção .sdata é copiada do arquivo elf para a memória em unidades de 16 bytes/128 bits em algum lugar. Talvez se a seção .sdata não for um múltiplo de 128 bits, os dados restantes não serão copiados, deixando zeros em seu lugar?
Ou talvez a seção .sdata tenha sido copiada corretamente, mas outra seção zerada não esteja alinhada corretamente ao lado dela? E o zeramento acontece depois que o .sdata é copiado?

Olá,
Para ver se @sp193 estava certo e o problema estava no ps2link eu modifiquei o exemplo e agora ele usa as funções scr_prinf para ver a saída na tela e ser facilmente executada por ULaunchELF ou carregado em PCSX2

O conteúdo do arquivo

#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;

Processo de compilação

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

A saída, neste caso, usando PCSX2
Screenshot 2020-01-15 at 09 47 54

Como você pode ver o resultado é o mesmo que o @rickgaiser comentou.

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

Obrigado

ps2link usa a função SifLoadElf para carregar o arquivo elf:
https://github.com/ps2dev/ps2link/blob/1ec566c54bb8b567ee0a702982b392f37807b5e2/ee/cmdHandler.c#L138

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

Isso acaba chamando uma função RPC no IOP. Parte de LOADFILE.

Isso pode ser um bug no LOADFILE? Ou talvez nossa cadeia de ferramentas não alinha as seções da maneira que o LOADFILE as espera? O sbv_patches poderia corrigir esse problema? Eu posso ver que eles corrigem LOADFILE, mas eles corrigem algo relacionado a isso?

O patch SBV para LOADFILE era habilitar a função RPC para LoadModuleBuffer(). Por alguma razão, essa função não é suportada pela versão inicial do LOADFILE. A Sony também o corrige, então é claramente algo que foi esquecido.

Encontrei o erro:

crt0 limpa a seção .bss, em unidades de 16 bytes/128 bits. Requer que a seção .bss esteja alinhada a pelo menos 16 bytes/128 bits. Anteriormente, isso era garantido pelo linkerfile no ps2sdk. No entanto, o script de vinculação padrão no binutils (adicionei aqui: https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) não alinha a seção .bss corretamente para crt0. Resultando nos últimos valores em .sdata a serem limpos também.

Eu criei uma correção para o script de linker binutils embutido aqui . Será parte do PR newlib.

IIRC, você sempre quer ter certeza de que as seções estão alinhadas em 128 bits. Acredito que tenha algo a ver com alinhamentos DMA ou algo assim, mas não tenho certeza.

Este problema foi resolvido com os PR's newlib que foram recentemente mesclados, especificamente este commit: https://github.com/ps2dev/ps2toolchain/commit/f5544b8d68fbdf611e277e9583714ae6627f3a61

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

lptech1024 picture lptech1024  ·  4Comentários

SignalSpectre picture SignalSpectre  ·  8Comentários

terremoth picture terremoth  ·  8Comentários

keithamus picture keithamus  ·  32Comentários

jhartikainen picture jhartikainen  ·  6Comentários