Ps2toolchain: Die letzten Bytes der ELF-Datei sind manchmal beschädigt

Erstellt am 15. Jan. 2020  ·  9Kommentare  ·  Quelle: ps2dev/ps2toolchain

Der folgende Codeabschnitt erzeugt eine ungültige Ausgabe:

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

Beim Versuch mit einer zufälligen Anzahl von Dummy-Konstanten variieren die Ergebnisse von:
Gut:

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

Zu schlecht:

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

Dieser Fehler führt dazu, dass size_ds34bt_irx und/oder size_ds34usb_irx in OPL 0 sind. Verursacht einen zufälligen Absturz von OPL beim Booten (schwarzer Bildschirm). Das Hinzufügen einer Codezeile an einer zufälligen Stelle in OPL würde dazu führen, dass dieser Fehler auftaucht und verschwindet.

Die ungültigen Werte scheinen sich in den letzten 128 Bit der ELF-Datei zu befinden, wenn sie angezeigt werden mit:
ee-objdump -D hello.elf

Die Werte in der Elf-Datei sind gut, also scheint es beim Laden des Elfs irgendwo schief zu gehen.

Hilfreichster Kommentar

Ich habe den Fehler gefunden:

crt0 löscht den .bss-Abschnitt in Einheiten von 16 Byte/128 Bit. Es erfordert, dass der .bss-Abschnitt auf mindestens 16 Byte/128 Bit ausgerichtet ist. Bisher wurde dies durch das Linkerfile in ps2sdk gewährleistet. Allerdings richtet das standardmäßige Linkerscript in binutils (ich habe es hier hinzugefügt: https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) den .bss-Abschnitt nicht richtig für crt0 aus. Dadurch werden auch die letzten paar Werte in .sdata gelöscht.

Ich habe hier einen Fix für das eingebaute Binutils- Linkerscript erstellt. Es wird Teil der newlib PR sein.

Alle 9 Kommentare

Erstaunlich, wie Sie zu diesem Schluss gekommen sind

Wenn es so aussieht, als ob die Werte innerhalb der ELF gut sind, warum glauben Sie nicht, dass es sich um ein ps2link-Problem handelt? Was wäre, wenn Sie Ihre ELF mit einer anderen Methode geladen hätten?
Ich denke, es liegt möglicherweise daran, dass ps2link den Speicher nicht löscht. Die Funktion sceSifLoadElf() nullt keinen Speicher, daher können fehlerhafte Daten erscheinen, wenn der Speicher nicht gelöscht wird, bevor die ELF mit dieser Funktion geladen wird.

Wenn es so aussieht, als ob die Werte innerhalb der ELF gut sind, warum glauben Sie nicht, dass es sich um ein ps2link-Problem handelt? Was wäre, wenn Sie Ihre ELF mit einer anderen Methode geladen hätten?

Ja, die Daten in der ELF-Datei scheinen gut zu sein, daher denke ich, dass der Titel dieser Ausgabe etwas irreführend ist. Ich werde es mit einem anderen Lader versuchen.

Ich denke, es liegt möglicherweise daran, dass ps2link den Speicher nicht löscht. Die Funktion sceSifLoadElf() nullt keinen Speicher, daher können fehlerhafte Daten erscheinen, wenn der Speicher nicht gelöscht wird, bevor die ELF mit dieser Funktion geladen wird.

Die const int's in befinden sich im Abschnitt .sdata (statische Daten). Ich denke, der Abschnitt .sdata wird irgendwo in Einheiten von 16 Bytes / 128 Bits aus der Elf-Datei in den Speicher kopiert. Wenn der .sdata-Abschnitt kein Vielfaches von 128 Bit ist, werden die verbleibenden Daten möglicherweise nicht kopiert und hinterlassen Nullen an ihrer Stelle?
Oder vielleicht wird der .sdata-Abschnitt korrekt kopiert, aber ein anderer auf Null gesetzter Abschnitt ist daneben nicht richtig ausgerichtet? Und das Nullsetzen erfolgt, nachdem die .sdata kopiert wurde?

Hallo,
Um zu sehen, ob @sp193 richtig war und das Problem in ps2link lag, habe ich das Beispiel geändert und es verwendet jetzt die Funktionen scr_prinf , um die Ausgabe auf dem Bildschirm zu sehen und einfach ausgeführt zu werden ULaunchELF oder in PCSX2 geladen

Der Inhalt der Datei

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

Zusammenstellungsprozess

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

Die Ausgabe erfolgt in diesem Fall über PCSX2
Screenshot 2020-01-15 at 09 47 54

Wie Sie sehen können, ist das Ergebnis das gleiche, das @rickgaiser kommentiert hat.

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

Danke

ps2link verwendet die Funktion SifLoadElf, um die elf-Datei zu laden:
https://github.com/ps2dev/ps2link/blob/1ec566c54bb8b567ee0a702982b392f37807b5e2/ee/cmdHandler.c#L138

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

Das endet mit dem Aufruf einer RPC-Funktion auf dem IOP. Teil von LOADFILE.

Könnte dies ein Fehler in LOADFILE sein? Oder richtet unsere Toolchain die Abschnitte vielleicht nicht so aus, wie LOADFILE es erwartet? Könnten die sbv_patches dieses Problem beheben? Ich kann sehen, dass sie LOADFILE patchen, aber patchen sie etwas, das damit zusammenhängt?

Der SBV-Patch für LOADFILE sollte die RPC-Funktion für LoadModuleBuffer() aktivieren. Aus irgendeinem Grund wird diese Funktion von der frühen Version von LOADFILE nicht unterstützt. Sony patcht es auch, also wurde es eindeutig übersehen.

Ich habe den Fehler gefunden:

crt0 löscht den .bss-Abschnitt in Einheiten von 16 Byte/128 Bit. Es erfordert, dass der .bss-Abschnitt auf mindestens 16 Byte/128 Bit ausgerichtet ist. Bisher wurde dies durch das Linkerfile in ps2sdk gewährleistet. Allerdings richtet das standardmäßige Linkerscript in binutils (ich habe es hier hinzugefügt: https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) den .bss-Abschnitt nicht richtig für crt0 aus. Dadurch werden auch die letzten paar Werte in .sdata gelöscht.

Ich habe hier einen Fix für das eingebaute Binutils- Linkerscript erstellt. Es wird Teil der newlib PR sein.

IIRC, Sie möchten immer sicherstellen, dass Abschnitte 128-Bit ausgerichtet sind. Ich glaube, es hatte etwas mit DMA-Ausrichtungen oder ähnlichem zu tun, bin mir aber nicht sicher.

Dieses Problem wurde mit den kürzlich zusammengeführten Newlib-PRs gelöst, insbesondere mit diesem Commit: https://github.com/ps2dev/ps2toolchain/commit/f5544b8d68fbdf611e277e9583714ae6627f3a61

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen