The user-mode context is now dumped (instead of the supervisor-mode context) on a svcBreak call.
Kernel panics are now handled by the exception handlers as well.
This commit is contained in:
@@ -162,10 +162,25 @@ void detectAndProcessExceptionDumps(void)
|
||||
|
||||
posY = drawString("Exception type: ", 10, posY, COLOR_WHITE);
|
||||
posY = drawString(handledExceptionNames[dumpHeader->type], 10 + 17 * SPACING_X, posY, COLOR_WHITE);
|
||||
if(dumpHeader->type == 2 && dumpHeader->registerDumpSize >= 4 && (regs[16] & 0x20) == 0
|
||||
&& *(vu32 *)((vu8 *)dumpHeader + sizeof(ExceptionDumpHeader) + dumpHeader->registerDumpSize + dumpHeader->codeDumpSize - 4) == 0xE12FFF7F)
|
||||
posY = drawString("(svcBreak)", 10 + 32 * SPACING_X, posY, COLOR_WHITE);
|
||||
|
||||
if(dumpHeader->type == 2)
|
||||
{
|
||||
if((regs[16] & 0x20) == 0 && dumpHeader->codeDumpSize >= 4)
|
||||
{
|
||||
u32 instr = *(vu32 *)((vu8 *)dumpHeader + sizeof(ExceptionDumpHeader) + dumpHeader->registerDumpSize + dumpHeader->codeDumpSize - 4);
|
||||
if(instr == 0xE12FFF7E)
|
||||
posY = drawString("(kernel panic)", 10 + 32 * SPACING_X, posY, COLOR_WHITE);
|
||||
else if(instr == 0xEF00003C)
|
||||
posY = drawString("(svcBreak)", 10 + 32 * SPACING_X, posY, COLOR_WHITE);
|
||||
}
|
||||
else if((regs[16] & 0x20) == 0 && dumpHeader->codeDumpSize >= 2)
|
||||
{
|
||||
u16 instr = *(vu16 *)((vu8 *)dumpHeader + sizeof(ExceptionDumpHeader) + dumpHeader->registerDumpSize + dumpHeader->codeDumpSize - 2);
|
||||
if(instr == 0xDF3C)
|
||||
posY = drawString("(svcBreak)", 10 + 32 * SPACING_X, posY, COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
if(dumpHeader->processor == 11 && dumpHeader->additionalDataSize != 0)
|
||||
{
|
||||
posY += SPACING_Y;
|
||||
|
||||
@@ -358,9 +358,12 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
|
||||
//Kernel9/Process9 debugging
|
||||
patchExceptionHandlersInstall(arm9Section, section[2].size);
|
||||
patchSvcBreak9(arm9Section, section[2].size, (u32)(section[2].address));
|
||||
patchKernel9Panic(arm9Section, section[2].size);
|
||||
|
||||
//Stub svcBreak11 with "bkpt 65535"
|
||||
patchSvcBreak11(arm11Section1, section[1].size);
|
||||
//Stub kernel11panic with "bkpt 65534"
|
||||
patchKernel11Panic(arm11Section1, section[1].size);
|
||||
|
||||
//Make FCRAM (and VRAM as a side effect) globally executable from arm11 kernel
|
||||
patchKernelFCRAMAndVRAMMappingPermissions(arm11Section1, section[1].size);
|
||||
@@ -390,6 +393,7 @@ static inline void patchLegacyFirm(FirmwareType firmType)
|
||||
//Kernel9/Process9 debugging
|
||||
patchExceptionHandlersInstall(arm9Section, section[3].size);
|
||||
patchSvcBreak9(arm9Section, section[3].size, (u32)(section[3].address));
|
||||
patchKernel9Panic(arm9Section, section[3].size);
|
||||
}
|
||||
|
||||
applyLegacyFirmPatches((u8 *)firm, firmType);
|
||||
@@ -414,10 +418,11 @@ static inline void patchSafeFirm(void)
|
||||
//Kernel9/Process9 debugging
|
||||
patchExceptionHandlersInstall(arm9Section, section[2].size);
|
||||
patchSvcBreak9(arm9Section, section[2].size, (u32)(section[2].address));
|
||||
patchKernel9Panic(arm9Section, section[2].size);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void copySection0AndInjectSystemModules(void)
|
||||
static inline void copySection0AndInjectSystemModules(FirmwareType firmType)
|
||||
{
|
||||
u8 *arm11Section0 = (u8 *)firm + section[0].offset;
|
||||
char fileName[] = "/luma/sysmodules/--------.cxi";
|
||||
@@ -430,40 +435,45 @@ static inline void copySection0AndInjectSystemModules(void)
|
||||
const u8 *addr;
|
||||
} modules[5] = {{0}};
|
||||
|
||||
u8 *pos = arm11Section0;
|
||||
u8 *pos = arm11Section0, *end = pos + section[0].size;
|
||||
u32 n = 0;
|
||||
|
||||
u32 loaderIndex = 0;
|
||||
for(u32 i = 0; i < 5; i++)
|
||||
|
||||
while(pos < end)
|
||||
{
|
||||
modules[i].addr = pos;
|
||||
modules[i].size = *(u32 *)(pos + 0x104) * 0x200;
|
||||
modules[n].addr = pos;
|
||||
modules[n].size = *(u32 *)(pos + 0x104) * 0x200;
|
||||
|
||||
memcpy(modules[i].name, pos + 0x200, 8);
|
||||
pos += modules[i].size;
|
||||
memcpy(modules[n].name, pos + 0x200, 8);
|
||||
pos += modules[n].size;
|
||||
|
||||
//Read modules from files if they exist
|
||||
u32 nameOff;
|
||||
for(nameOff = 0; nameOff < 8 && modules[i].name[nameOff] != 0; nameOff++);
|
||||
memcpy(fileName + 17, modules[i].name, nameOff);
|
||||
for(nameOff = 0; nameOff < 8 && modules[n].name[nameOff] != 0; nameOff++);
|
||||
memcpy(fileName + 17, modules[n].name, nameOff);
|
||||
memcpy(fileName + 17 + nameOff, ext, 5);
|
||||
|
||||
u32 fileSize = getFileSize(fileName);
|
||||
if(fileSize != 0)
|
||||
{
|
||||
modules[i].addr = NULL;
|
||||
modules[i].size = fileSize;
|
||||
modules[n].addr = NULL;
|
||||
modules[n].size = fileSize;
|
||||
}
|
||||
|
||||
if(memcmp(modules[i].name, "loader", 7) == 0) loaderIndex = i;
|
||||
if(firmType == NATIVE_FIRM && memcmp(modules[n].name, "loader", 7) == 0) loaderIndex = n;
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
if(modules[loaderIndex].addr != NULL)
|
||||
if(firmType == NATIVE_FIRM && modules[loaderIndex].addr != NULL)
|
||||
{
|
||||
modules[loaderIndex].size = injector_size;
|
||||
modules[loaderIndex].addr = injector;
|
||||
}
|
||||
|
||||
pos = section[0].address;
|
||||
for(u32 i = 0; i < 5; i++)
|
||||
for(u32 i = 0; i < n; i++)
|
||||
{
|
||||
if(modules[i].addr != NULL)
|
||||
memcpy(pos, modules[i].addr, modules[i].size);
|
||||
@@ -487,7 +497,7 @@ static inline void launchFirm(FirmwareType firmType, bool isFirmlaunch)
|
||||
u32 sectionNum;
|
||||
if(firmType != SAFE_FIRM)
|
||||
{
|
||||
copySection0AndInjectSystemModules();
|
||||
copySection0AndInjectSystemModules(firmType);
|
||||
sectionNum = 1;
|
||||
}
|
||||
else sectionNum = 0;
|
||||
|
||||
@@ -58,5 +58,5 @@ static inline u32 loadFirm(FirmwareType firmType);
|
||||
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh);
|
||||
static inline void patchLegacyFirm(FirmwareType firmType);
|
||||
static inline void patchSafeFirm(void);
|
||||
static inline void copySection0AndInjectSystemModules(void);
|
||||
static inline void copySection0AndInjectSystemModules(FirmwareType firmType);
|
||||
static inline void launchFirm(FirmwareType firmType, bool isFirmlaunch);
|
||||
@@ -177,7 +177,8 @@ void patchSvcBreak9(u8 *pos, u32 size, u32 k9addr)
|
||||
|
||||
u32 *arm9SvcTable = (u32 *)memsearch(pos, svcHandlerPattern, size, 4);
|
||||
while(*arm9SvcTable) arm9SvcTable++; //Look for SVC0 (NULL)
|
||||
*(u32 *)(pos + arm9SvcTable[0x3C] - k9addr) = 0xE12FFF7F;
|
||||
u32 *addr = (u32 *)(pos + arm9SvcTable[0x3C] - k9addr);
|
||||
*addr = 0xE12FFF7F;
|
||||
}
|
||||
|
||||
void patchSvcBreak11(u8 *pos, u32 size)
|
||||
@@ -185,7 +186,24 @@ void patchSvcBreak11(u8 *pos, u32 size)
|
||||
//Same as above, for NFIRM arm11
|
||||
|
||||
findArm11ExceptionsPageAndSvcHandlerAndTable(pos, size);
|
||||
*(u32 *)(pos + arm11SvcTable[0x3C] - 0xFFF00000) = 0xE12FFF7F;
|
||||
u32 *addr = (u32 *)(pos + arm11SvcTable[0x3C] - 0xFFF00000);
|
||||
*addr = 0xE12FFF7F;
|
||||
}
|
||||
|
||||
void patchKernel9Panic(u8 *pos, u32 size)
|
||||
{
|
||||
const u8 pattern[] = {0x00, 0x20, 0xA0, 0xE3, 0x02, 0x30, 0xA0, 0xE1, 0x02, 0x10, 0xA0, 0xE1, 0x05, 0x00, 0xA0, 0xE3};
|
||||
|
||||
u32 *off = (u32 *)memsearch(pos, pattern, size, 16);
|
||||
*off = 0xE12FFF7E;
|
||||
}
|
||||
|
||||
void patchKernel11Panic(u8 *pos, u32 size)
|
||||
{
|
||||
const u8 pattern[] = {0x02, 0x0B, 0x44, 0xE2, 0x00, 0x10, 0x90, 0xE5};
|
||||
|
||||
u32 *off = (u32 *)memsearch(pos, pattern, size, 8);
|
||||
*off = 0xE12FFF7E;
|
||||
}
|
||||
|
||||
void patchArm11SvcAccessChecks(u8 *pos, u32 size)
|
||||
|
||||
@@ -45,6 +45,8 @@ void patchFirmWriteSafe(u8 *pos, u32 size);
|
||||
void patchExceptionHandlersInstall(u8 *pos, u32 size);
|
||||
void patchSvcBreak9(u8 *pos, u32 size, u32 k9addr);
|
||||
void patchSvcBreak11(u8 *pos, u32 size);
|
||||
void patchKernel9Panic(u8 *pos, u32 size);
|
||||
void patchKernel11Panic(u8 *pos, u32 size);
|
||||
void patchArm11SvcAccessChecks(u8 *pos, u32 size);
|
||||
void patchK11ModuleChecks(u8 *pos, u32 size);
|
||||
void patchP9AccessChecks(u8 *pos, u32 size);
|
||||
|
||||
Reference in New Issue
Block a user