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.
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
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
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
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.