Ps2toolchain: أحيانًا تكون وحدات البايت الأخيرة من ملف ELF تالفة

تم إنشاؤها على ١٥ يناير ٢٠٢٠  ·  9تعليقات  ·  مصدر: ps2dev/ps2toolchain

الجزء التالي من الكود سينتج مخرجات غير صالحة:

#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 جيدة ، لذا يبدو أنها تسوء في مكان ما أثناء تحميل العفريت.

التعليق الأكثر فائدة

لقد وجدت الخطأ:

يمسح crt0 قسم .bss بوحدات 16 بايت / 128 بت. يتطلب أن يتم محاذاة قسم .bss مع 16 بايت / 128 بت على الأقل. في السابق كان هذا مضمونًا بواسطة linkerfile في ps2sdk. ومع ذلك ، فإن الرابط الافتراضي في binutils (أضفته هنا: https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) لا يحاذي قسم .bss بشكل صحيح لـ crt0. مما يؤدي إلى مسح القيم القليلة الأخيرة في .sdata أيضًا.

لقد قمت بإنشاء إصلاح للرابط binutils المدمج هنا . سيكون جزءًا من newlib العلاقات العامة.

ال 9 كومينتر

من المدهش كيف وصلت إلى هذا الاستنتاج

إذا بدا أن القيم داخل ELF جيدة ، فلماذا لا تعتقد أنها مشكلة ps2link؟ ماذا لو استخدمت طريقة أخرى لتحميل ELF الخاص بك؟
أعتقد أنه من المحتمل أن يكون السبب هو عدم مسح ps2link للذاكرة. لا تؤدي وظيفة sceSifLoadElf () إلى الصفر إلى أي ذاكرة ، وبالتالي قد تظهر البيانات السيئة إذا لم يتم مسح الذاكرة قبل تحميل ELF بهذه الوظيفة.

إذا بدا أن القيم داخل ELF جيدة ، فلماذا لا تعتقد أنها مشكلة ps2link؟ ماذا لو استخدمت طريقة أخرى لتحميل ELF الخاص بك؟

نعم ، تبدو البيانات الموجودة في ملف ELF جيدة ، لذا أعتقد أن عنوان هذه المشكلة مضلل بعض الشيء. سأحاول محمل آخر.

أعتقد أنه من المحتمل أن يكون السبب هو عدم مسح ps2link للذاكرة. لا تؤدي وظيفة sceSifLoadElf () إلى الصفر إلى أي ذاكرة ، وبالتالي قد تظهر البيانات السيئة إذا لم يتم مسح الذاكرة قبل تحميل ELF بهذه الوظيفة.

توجد قيمة const int في قسم .sdata (بيانات ثابتة). أعتقد أن قسم .sdata يتم نسخه من ملف elf إلى الذاكرة بوحدات 16 بايت / 128 بت في مكان ما. ربما إذا لم يكن قسم .sdata من مضاعفات 128 بت ، فلن يتم نسخ البيانات المتبقية ، وترك الأصفار في مكانها؟
أو ربما تم نسخ قسم البيانات. ويحدث التصفير بعد نسخ البيانات؟

مرحبا،
لمعرفة ما إذا كان @ 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
Screenshot 2020-01-15 at 09 47 54

كما ترى فإن النتيجة هي نفسها التي علق بهاrickgaiser .

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

شكرا

يستخدم ps2link الوظيفة SifLoadElf لتحميل ملف elf:
https://github.com/ps2dev/ps2link/blob/1ec566c54bb8b567ee0a702982b392f37807b5e2/ee/cmdHandler.c#L138

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

ينتهي الأمر باستدعاء وظيفة RPC على IOP. جزء من LOADFILE.

هل يمكن أن يكون هذا خطأ في LOADFILE؟ أو ربما لا تقوم سلسلة أدواتنا بمحاذاة الأقسام بالطريقة التي يتوقعها LOADFILE؟ هل يمكن لـ sbv_patches إصلاح هذه المشكلة؟ أستطيع أن أرى أنهم قاموا بتصحيح LOADFILE ، لكن هل يقومون بتصحيح أي شيء متعلق بهذا؟

كان تصحيح SBV لـ LOADFILE هو تمكين وظيفة RPC لـ LoadModuleBuffer (). لسبب ما ، هذه الوظيفة غير مدعومة من قبل الإصدار القديم من LOADFILE. قامت Sony بتصحيحه أيضًا ، لذلك من الواضح أنه تم التغاضي عنه.

لقد وجدت الخطأ:

يمسح crt0 قسم .bss بوحدات 16 بايت / 128 بت. يتطلب أن يتم محاذاة قسم .bss مع 16 بايت / 128 بت على الأقل. في السابق كان هذا مضمونًا بواسطة linkerfile في ps2sdk. ومع ذلك ، فإن الرابط الافتراضي في binutils (أضفته هنا: https://github.com/ps2dev/ps2toolchain/commit/7c494f217d379639aaca23d3c588e48986177a51) لا يحاذي قسم .bss بشكل صحيح لـ crt0. مما يؤدي إلى مسح القيم القليلة الأخيرة في .sdata أيضًا.

لقد قمت بإنشاء إصلاح للرابط binutils المدمج هنا . سيكون جزءًا من newlib العلاقات العامة.

IIRC ، تريد دائمًا التأكد من محاذاة الأقسام بمقدار 128 بت ، وأعتقد أن الأمر يتعلق بمحاذاة DMA أو بعضها ولكن غير متأكد.

تم حل هذه المشكلة مع العلاقات العامة newlib التي تم دمجها مؤخرًا ، وتحديداً هذا الالتزام: https://github.com/ps2dev/ps2toolchain/commit/f5544b8d68fbdf611e277e9583714ae6627f3a61

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات