Следующий фрагмент кода выдаст неверный вывод:
#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;
При попытке со случайным числом фиктивных констант результаты будут отличаться от:
Хорошо:
i1=1111
i2=2222
i3=3333
i4=4444
К плохому:
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
Из-за этой ошибки size_ds34bt_irx и/или size_ds34usb_irx в OPL равны 0. Вызывает случайный сбой OPL при загрузке (черный экран). Добавление строки кода в случайном месте в OPL может вызвать появление и исчезновение этой ошибки.
Недопустимые значения, по-видимому, находятся в последних 128 битах файла ELF при просмотре с использованием:
ee-objdump -D hello.elf
Значения в файле elf хорошие, поэтому кажется, что что-то пошло не так при загрузке elf.
Удивительно, как вы пришли к такому выводу
Если кажется, что значения в ELF хороши, почему вы не думаете, что это проблема ps2link? Что делать, если вы использовали другой метод для загрузки вашего ELF?
Я думаю, что это может быть вызвано тем, что ps2link не очищает память. Функция sceSifLoadElf() не обнуляет память, поэтому могут появиться неверные данные, если память не будет стерта до загрузки ELF с помощью этой функции.
Если кажется, что значения в ELF хороши, почему вы не думаете, что это проблема ps2link? Что делать, если вы использовали другой метод для загрузки вашего ELF?
Да, данные в файле ELF кажутся хорошими, поэтому я думаю, что название этого выпуска немного вводит в заблуждение. Попробую другой загрузчик.
Я думаю, что это может быть вызвано тем, что ps2link не очищает память. Функция sceSifLoadElf() не обнуляет память, поэтому могут появиться неверные данные, если память не будет стерта до загрузки ELF с помощью этой функции.
Константы int находятся в разделе .sdata (статические данные). Я думаю, что раздел .sdata копируется из файла elf в память где-то по 16 байт/128 бит. Возможно, если раздел .sdata не кратен 128 битам, остальные данные не копируются, а на их месте остаются нули?
Или, возможно, раздел .sdata скопирован правильно, но рядом с ним неправильно выровнен другой обнуленный раздел? А обнуление происходит после копирования .sdata?
Привет,
Чтобы убедиться, что @sp193 был прав и проблема заключалась в ps2link
, я изменил пример, и теперь он использует функции scr_prinf
для просмотра вывода на экране и легкого выполнения с помощью ULaunchELF
или загружается в PCSX2
Содержимое файла
#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;
Процесс компиляции
ee-gcc -o hello.elf hello.c -L$PS2SDK/ee/lib -ldebug
Вывод в данном случае с использованием PCSX2
Как видите, результат тот же, что прокомментировал @rickgaiser .
i1=1111
i2=2222
i3=3333
i4=0
Спасибо
ps2link использует функцию SifLoadElf для загрузки файла elf:
https://github.com/ps2dev/ps2link/blob/1ec566c54bb8b567ee0a702982b392f37807b5e2/ee/cmdHandler.c#L138
Это заканчивается вызовом функции RPC в IOP. Часть LOADFILE.
Может ли это быть ошибкой в LOADFILE? Или, возможно, наш набор инструментов не выровнял разделы так, как их ожидает LOADFILE? Могут ли sbv_patches решить эту проблему? Я вижу, что они исправляют LOADFILE, но исправляют ли они что-либо, связанное с этим?
Патч SBV для LOADFILE должен был включить функцию RPC для LoadModuleBuffer(). По какой-то причине эта функция не поддерживается ранней версией LOADFILE. Sony тоже исправляет это, так что это явно что-то, что было упущено из виду.
Я нашел ошибку:
crt0 очищает раздел .bss в единицах 16 байт/128 бит. Требуется, чтобы раздел .bss был выровнен как минимум до 16 байт/128 бит. Раньше это гарантировалось компоновщиком в ps2sdk. Тем не менее, компоновщик по умолчанию в binutils (я добавил здесь: https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) не выравнивает раздел .bss должным образом для crt0. В результате последние несколько значений в .sdata также будут очищены.
Я создал исправление для встроенного компоновщика binutils здесь . Это будет частью PR newlib.
IIRC, вы всегда хотите убедиться, что разделы выровнены по 128 битам. Я полагаю, что это как-то связано с выравниванием DMA или чем-то подобным, но не уверен.
Эта проблема была решена с помощью недавно объединенных PR newlib, в частности этого коммита: https://github.com/ps2dev/ps2toolchain/commit/f5544b8d68fbdf611e277e9583714ae6627f3a61 .
Самый полезный комментарий
Я нашел ошибку:
crt0 очищает раздел .bss в единицах 16 байт/128 бит. Требуется, чтобы раздел .bss был выровнен как минимум до 16 байт/128 бит. Раньше это гарантировалось компоновщиком в ps2sdk. Тем не менее, компоновщик по умолчанию в binutils (я добавил здесь: https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) не выравнивает раздел .bss должным образом для crt0. В результате последние несколько значений в .sdata также будут очищены.
Я создал исправление для встроенного компоновщика binutils здесь . Это будет частью PR newlib.