Make the exception handlers dump more information

You'll need to the latest version of exception_dump_parser.py
This commit is contained in:
TuxSH
2016-06-07 19:25:45 +02:00
parent ca587692eb
commit e478908dca
10 changed files with 115 additions and 59 deletions

View File

@@ -33,7 +33,7 @@ void installArm9Handlers(void)
#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr)
void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset)
{
u32 *initFPU;
for(initFPU = exceptionsPage; initFPU < (exceptionsPage + 0x400) && (initFPU[0] != 0xE59F0008 || initFPU[1] != 0xE5900000); initFPU += 1);
@@ -59,6 +59,7 @@ void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr)
case 0xEBFFFFFE: *pos = MAKE_BRANCH_LINK(pos, initFPU); break;
case 0xEAFFFFFE: *pos = MAKE_BRANCH(pos, mcuReboot); break;
case 0xE12FFF1C: pos[1] = 0xFFFF0000 + 4 * (u32)(freeSpace - exceptionsPage) + pos[1] - 32; break; // bx r12 (mainHandler)
case 0xBEEFBEEF: *pos = codeSetOffset;
default: break;
}
}
@@ -117,17 +118,26 @@ void detectAndProcessExceptionDumps(void)
}
char arm11Str[] = "Processor: ARM11 (core X)";
if((dump[3] & 0xFFFF) == 11) arm11Str[28] = '0' + (char)(dump[3] >> 16);
char arm11Str[] = "Processor: ARM11 (core X)";
if((dump[3] & 0xFFFF) == 11) arm11Str[29] = '0' + (char)(dump[3] >> 16);
initScreens();
drawString("An exception occurred", 10, 10, COLOR_RED);
int posY = drawString(((dump[3] & 0xFFFF) == 11) ? arm11Str : "Processor: ARM9", 10, 30, COLOR_WHITE) + SPACING_Y;
posY = drawString("Exception type: ", 10, posY, COLOR_WHITE);
posY = drawString(handledExceptionNames[dump[4]], 10 + 16 * SPACING_X, posY, COLOR_WHITE);
int posY = drawString(((dump[3] & 0xFFFF) == 11) ? arm11Str : "Processor: ARM9", 10, 30, COLOR_WHITE) + SPACING_Y;
posY = drawString("Exception type: ", 10, posY, COLOR_WHITE);
posY = drawString(handledExceptionNames[dump[4]], 10 + 17 * SPACING_X, posY, COLOR_WHITE);
if(dump[4] == 2 && dump[7] >= 4 && (dump[10 + 16] & 0x20) == 0 && *(vu32 *)((vu8 *)dump + 40 + dump[6] + dump[7] - 4) == 0xE12FFF7F)
posY = drawString("(svcBreak)", 10 + 31 * SPACING_X, posY, COLOR_WHITE);
posY = drawString("(svcBreak)", 10 + 32 * SPACING_X, posY, COLOR_WHITE);
if((dump[3] & 0xFFFF) == 11 && dump[9] != 0)
{
posY += SPACING_Y;
char processNameStr[] = "Current process: --------";
memcpy(processNameStr + 17, (char *)(dump + ((dump[5] - dump[9]) / 4)), 8);
posY = drawString(processNameStr, 10, posY, COLOR_WHITE);
}
posY += 3 * SPACING_Y;
for(u32 i = 0; i < 17; i += 2)
@@ -139,7 +149,7 @@ void detectAndProcessExceptionDumps(void)
if(dump[3] != 9 || i != 16)
{
posY = drawString(registerNames[i + 1], 10 + 22 * SPACING_X, posY, COLOR_WHITE);
hexItoa(dump[10 + i + 1], hexstring);
hexItoa((i == 16) ? dump[10 + 20] : dump[10 + i + 1], hexstring);
posY = drawString(hexstring, 10 + 29 * SPACING_X, posY, COLOR_WHITE);
}
@@ -150,7 +160,10 @@ void detectAndProcessExceptionDumps(void)
u32 mode = dump[10 + 16] & 0xF;
if(dump[4] == 3 && (mode == 7 || mode == 11))
{
posY = drawString("Incorrect dump: failed to dump code and/or stack", 10, posY, 0x00FFFF) + 2 * SPACING_Y; //in yellow
if(dump[3] != 9) posY -= SPACING_Y;
}
posY = drawString("You can find a dump in the following file:", 10, posY, COLOR_WHITE) + SPACING_Y;
posY = drawString((dump[3] == 9) ? path9 : path11, 10, posY, COLOR_WHITE) + 2 * SPACING_Y;

View File

@@ -8,5 +8,5 @@
#include "types.h"
void installArm9Handlers(void);
void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr);
void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset);
void detectAndProcessExceptionDumps(void);

View File

@@ -326,15 +326,15 @@ static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode)
if(DEVMODE == 2) patchUnitInfoValueSet(arm9Section, section[2].size);
//Install arm11 exception handlers
u32 stackAddress;
u32 *exceptionsPage = getInfoForArm11ExceptionHandlers(arm11Section1, section[1].size, &stackAddress);
installArm11Handlers(exceptionsPage, stackAddress);
u32 stackAddress, codeSetOffset;
u32 *exceptionsPage = getInfoForArm11ExceptionHandlers(arm11Section1, section[1].size, &stackAddress, &codeSetOffset);
installArm11Handlers(exceptionsPage, stackAddress, codeSetOffset);
//Kernel9/Process9 debugging
patchExceptionHandlersInstall(arm9Section, section[2].size);
patchSvcBreak9(arm9Section, section[2].size, (u32)(section[2].address));
//Stub svcBreak11 with "bkpt 255"
//Stub svcBreak11 with "bkpt 65535"
patchSvcBreak11(arm11Section1, section[1].size);
//Make FCRAM (and VRAM as a side effect) globally executable from arm11 kernel

View File

@@ -34,14 +34,20 @@ u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
return off - 0x204 + (*(u32 *)(off - 0x64) * 0x200) + 0x200;
}
u32* getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *stackAddr)
u32* getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *stackAddr, u32 *codeSetOffset)
{
//This function has to succeed. Crash if it doesn't (we'll get an exception dump of it anyways)
const u8 callExceptionDispatcherPattern[] = {0x0F, 0x00, 0xBD, 0xE8, 0x13, 0x00, 0x02, 0xF1};
const u8 getTitleIDFromCodeSetPattern[] = {0xDC, 0x05, 0xC0, 0xE1, 0x20, 0x04, 0xA0, 0xE1};
*stackAddr = *((u32 *)memsearch(pos, callExceptionDispatcherPattern, size, 8) + 3);
u32 *loadCodeSet = (u32 *)memsearch(pos, getTitleIDFromCodeSetPattern, size, 8);
while((*loadCodeSet >> 20) != 0xE59 || ((*loadCodeSet >> 12) & 0xF) != 0) //ldr r0, [rX, #offset]
loadCodeSet--;
*codeSetOffset = *loadCodeSet & 0xFFF;
findArm11ExceptionsPageAndSvcTable(pos, size);
return arm11ExceptionsPage;
}

View File

@@ -16,7 +16,7 @@ typedef struct patchData {
} patchData;
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
u32* getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *stackAddr);
u32* getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *stackAddr, u32 *codeSetOffset);
void patchSignatureChecks(u8 *pos, u32 size);
void patchTitleInstallMinVersionCheck(u8 *pos, u32 size);
void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);