@ -25,21 +25,34 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
Module : : Interface : : ~ Interface ( ) = default ;
struct FatalInfo {
std : : array < u64_le , 31 > registers { } ; // TODO(ogniK): See if this actually is registers or
// not(find a game which has non zero valeus)
u64_le unk0 { } ;
u64_le unk1 { } ;
u64_le unk2 { } ;
u64_le unk3 { } ;
u64_le unk4 { } ;
u64_le unk5 { } ;
u64_le unk6 { } ;
enum class Architecture : s32 {
AArch64 ,
AArch32 ,
} ;
const char * ArchAsString ( ) const {
return arch = = Architecture : : AArch64 ? " AArch64 " : " AArch32 " ;
}
std : : array < u64_le , 31 > registers { } ;
u64_le sp { } ;
u64_le pc { } ;
u64_le pstate { } ;
u64_le afsr0 { } ;
u64_le afsr1 { } ;
u64_le esr { } ;
u64_le far { } ;
std : : array < u64_le , 32 > backtrace { } ;
u64_le unk7 { } ;
u64_le unk8 { } ;
u64_le program_entry_point { } ;
// Bit flags that indicate which registers have been set with values
// for this context. The service itself uses these to determine which
// registers to specifically print out.
u64_le set_flags { } ;
u32_le backtrace_size { } ;
u32_le unk9 { } ;
Architecture arch { } ;
u32_le unk10 { } ; // TODO(ogniK): Is this even used or is it just padding?
} ;
static_assert ( sizeof ( FatalInfo ) = = 0x250 , " FatalInfo is an invalid size " ) ;
@ -52,36 +65,36 @@ enum class FatalType : u32 {
static void GenerateErrorReport ( ResultCode error_code , const FatalInfo & info ) {
const auto title_id = Core : : CurrentProcess ( ) - > GetTitleID ( ) ;
std : : string crash_report =
fmt : : format ( " Yuzu {}-{} crash report \n "
" Title ID: {:016x} \n "
" Result: 0x{:X} ({:04}-{:04d}) \n "
" \n " ,
Common : : g_scm_branch , Common : : g_scm_desc , title_id , error_code . raw ,
2000 + static_cast < u32 > ( error_code . module . Value ( ) ) ,
static_cast < u32 > ( error_code . description . Value ( ) ) , info . unk8 , info . unk7 ) ;
std : : string crash_report = fmt : : format (
" Yuzu {}-{} crash report \n "
" Title ID: {:016x} \n "
" Result: 0x{:X} ({:04}-{:04d}) \n "
" Set flags: 0x{:16X} \n "
" Program entry point: 0x{:16X} \n "
" \n " ,
Common : : g_scm_branch , Common : : g_scm_desc , title_id , error_code . raw ,
2000 + static_cast < u32 > ( error_code . module . Value ( ) ) ,
static_cast < u32 > ( error_code . description . Value ( ) ) , info . set_flags , info . program_entry_point ) ;
if ( info . backtrace_size ! = 0x0 ) {
crash_report + = " Registers: \n " ;
// TODO(ogniK): This is just a guess, find a game which actually has non zero values
for ( size_t i = 0 ; i < info . registers . size ( ) ; i + + ) {
crash_report + =
fmt : : format ( " X[{:02d}]: {:016x} \n " , i , info . registers [ i ] ) ;
}
crash_report + = fmt : : format ( " Unknown 0: {:016x} \n " , info . unk0 ) ;
crash_report + = fmt : : format ( " Unknown 1: {:016x} \n " , info . unk1 ) ;
crash_report + = fmt : : format ( " Unknown 2: {:016x} \n " , info . unk2 ) ;
crash_report + = fmt : : format ( " Unknown 3: {:016x} \n " , info . unk3 ) ;
crash_report + = fmt : : format ( " Unknown 4: {:016x} \n " , info . unk4 ) ;
crash_report + = fmt : : format ( " Unknown 5: {:016x} \n " , info . unk5 ) ;
crash_report + = fmt : : format ( " Unknown 6: {:016x} \n " , info . unk6 ) ;
crash_report + = fmt : : format ( " SP: {:016x} \n " , info . sp ) ;
crash_report + = fmt : : format ( " PC: {:016x} \n " , info . pc ) ;
crash_report + = fmt : : format ( " PSTATE: {:016x} \n " , info . pstate ) ;
crash_report + = fmt : : format ( " AFSR0: {:016x} \n " , info . afsr0 ) ;
crash_report + = fmt : : format ( " AFSR1: {:016x} \n " , info . afsr1 ) ;
crash_report + = fmt : : format ( " ESR: {:016x} \n " , info . esr ) ;
crash_report + = fmt : : format ( " FAR: {:016x} \n " , info . far ) ;
crash_report + = " \n Backtrace: \n " ;
for ( size_t i = 0 ; i < info . backtrace_size ; i + + ) {
crash_report + =
fmt : : format ( " Backtrace[{:02d}]: {:016x} \n " , i , info . backtrace [ i ] ) ;
}
crash_report + = fmt : : format ( " \n Unknown 7: 0x{:016x} \n " , info . unk7 ) ;
crash_report + = fmt : : format ( " Unknown 8: 0x{:016x} \n " , info . unk8 ) ;
crash_report + = fmt : : format ( " Unknown 9: 0x{:016x} \n " , info . unk9 ) ;
crash_report + = fmt : : format ( " Architecture: {} \n " , info . ArchAsString ( ) ) ;
crash_report + = fmt : : format ( " Unknown 10: 0x{:016x} \n " , info . unk10 ) ;
}