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:
TuxSH
2016-08-12 15:17:19 +02:00
parent 39b2aff627
commit f81c92e35b
10 changed files with 203 additions and 100 deletions

View File

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

View File

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

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);