Ps2toolchain: Los últimos bytes del archivo ELF a veces están dañados

Creado en 15 ene. 2020  ·  9Comentarios  ·  Fuente: ps2dev/ps2toolchain

El siguiente fragmento de código producirá una salida no vá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;

Cuando se prueba con un número aleatorio de constantes ficticias, los resultados variarán de:
Bien:

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 error hace que size_ds34bt_irx y/o size_ds34usb_irx en OPL sean 0. Provoca un bloqueo aleatorio de OPL en el arranque (pantalla negra). Agregar una línea de código en un lugar aleatorio en OPL haría que este error apareciera y desapareciera.

Los valores no válidos parecen estar en los últimos 128 bits del archivo ELF, cuando se ven usando:
ee-objdump -D hello.elf

Los valores en el archivo elf son buenos, por lo que parece fallar en alguna parte mientras se carga el archivo elf.

Comentario más útil

Encontré el error:

crt0 borra la sección .bss, en unidades de 16 bytes/128 bits. Requiere que la sección .bss esté alineada a al menos 16 bytes/128 bits. Anteriormente, esto estaba garantizado por el archivo de enlace en ps2sdk. Sin embargo, el linkerscript predeterminado en binutils (agregué aquí: https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) no alinea la sección .bss correctamente para crt0. Como resultado, los últimos valores en .sdata también se borrarán.

He creado una corrección para el linkerscript incorporado de binutils aquí . Será parte de newlib PR.

Todos 9 comentarios

Impresionante como llegaste a esa conclusión

Si parece que los valores dentro de ELF son buenos, ¿por qué no cree que sea un problema de ps2link? ¿Qué pasa si usaste otro método para cargar tu ELF?
Creo que posiblemente se deba a que ps2link no borra la memoria. La función sceSifLoadElf() no pone a cero ninguna memoria, por lo que pueden aparecer datos erróneos si la memoria no se borra antes de cargar el ELF con esa función.

Si parece que los valores dentro de ELF son buenos, ¿por qué no cree que sea un problema de ps2link? ¿Qué pasa si usaste otro método para cargar tu ELF?

Sí, los datos en el archivo ELF parecen buenos, así que supongo que el título de este problema es un poco engañoso. Probaré con otro cargador.

Creo que posiblemente se deba a que ps2link no borra la memoria. La función sceSifLoadElf() no pone a cero ninguna memoria, por lo que pueden aparecer datos erróneos si la memoria no se borra antes de cargar el ELF con esa función.

Los const int están en la sección .sdata (datos estáticos). Creo que la sección .sdata se copia del archivo elf a la memoria en unidades de 16 bytes/128 bits en alguna parte. ¿Quizás si la sección .sdata no es un múltiplo de 128 bits, los datos restantes no se copian, dejando ceros en su lugar?
¿O tal vez la sección .sdata se copió correctamente, pero otra sección puesta a cero no está alineada correctamente junto a ella? ¿Y la puesta a cero ocurre después de que se copian los .sdata?

Hola,
Para ver si @sp193 tenía razón y el problema estaba en el ps2link , modifiqué el ejemplo y ahora usa las funciones scr_prinf para ver el resultado en la pantalla y ser ejecutado fácilmente por ULaunchELF o cargado en PCSX2

El contenido del archivo

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

Proceso de compilación

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

La salida, en este caso, usando PCSX2
Screenshot 2020-01-15 at 09 47 54

Como pueden ver el resultado es el mismo que comentó @rickgaiser .

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

Gracias

ps2link usa la función SifLoadElf para cargar el archivo 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

Eso termina llamando a una función RPC en el IOP. Parte de LOADFILE.

¿Podría ser esto un error en LOADFILE? ¿O tal vez nuestra cadena de herramientas no alinea las secciones de la forma en que LOADFILE las espera? ¿Podrían los sbv_patches solucionar este problema? Puedo ver que parchean LOADFILE, pero ¿parchan algo relacionado con esto?

El parche SBV para LOADFILE fue para habilitar la función RPC para LoadModuleBuffer(). Por alguna razón, esa función no es compatible con la versión anterior de LOADFILE. Sony también lo parchea, por lo que claramente es algo que se pasó por alto.

Encontré el error:

crt0 borra la sección .bss, en unidades de 16 bytes/128 bits. Requiere que la sección .bss esté alineada a al menos 16 bytes/128 bits. Anteriormente, esto estaba garantizado por el archivo de enlace en ps2sdk. Sin embargo, el linkerscript predeterminado en binutils (agregué aquí: https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) no alinea la sección .bss correctamente para crt0. Como resultado, los últimos valores en .sdata también se borrarán.

He creado una corrección para el linkerscript incorporado de binutils aquí . Será parte de newlib PR.

IIRC, siempre quiere asegurarse de que las secciones estén alineadas en 128 bits. Creo que tuvo algo que ver con las alineaciones DMA o algo así, pero no estoy seguro.

Este problema se resolvió con los PR de newlib que se fusionaron recientemente, específicamente este compromiso: https://github.com/ps2dev/ps2toolchain/commit/f5544b8d68fbdf611e277e9583714ae6627f3a61

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

SignalSpectre picture SignalSpectre  ·  8Comentarios

lptech1024 picture lptech1024  ·  4Comentarios

terremoth picture terremoth  ·  8Comentarios

sbellware picture sbellware  ·  12Comentarios

To1ne picture To1ne  ·  13Comentarios