ARM => Arm
This commit is contained in:
parent
4a655384e2
commit
58f3edda12
6
.github/ISSUE_TEMPLATE/bug-report.md
vendored
6
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@ -70,11 +70,11 @@ Show NAND or user string in System Settings: ( )
|
|||||||
|
|
||||||
Show GBA boot screen in patched AGB_FIRM: ( )
|
Show GBA boot screen in patched AGB_FIRM: ( )
|
||||||
|
|
||||||
Patch ARM9 access: ( )
|
Patch Arm9 access: ( )
|
||||||
|
|
||||||
Set developer UNITINFO: ( )
|
Set developer UNITINFO: ( )
|
||||||
|
|
||||||
Disable ARM11 exception handlers: ( )
|
Disable Arm11 exception handlers: ( )
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
@ -94,6 +94,6 @@ Disable ARM11 exception handlers: ( )
|
|||||||
|
|
||||||
|
|
||||||
**Dump file:**
|
**Dump file:**
|
||||||
<!--If the issue leads to a crash you must uncheck the "Disable ARM11 exception handlers" option.
|
<!--If the issue leads to a crash you must uncheck the "Disable Arm11 exception handlers" option.
|
||||||
-- The error message will tell you where the dump is.
|
-- The error message will tell you where the dump is.
|
||||||
-- Zip the dmp file and drag & drop it below.-->
|
-- Zip the dmp file and drag & drop it below.-->
|
||||||
|
@ -71,7 +71,7 @@ start:
|
|||||||
.global prepareForFirmlaunch
|
.global prepareForFirmlaunch
|
||||||
.type prepareForFirmlaunch, %function
|
.type prepareForFirmlaunch, %function
|
||||||
prepareForFirmlaunch:
|
prepareForFirmlaunch:
|
||||||
str r0, [r1] @ tell ARM9 we're done
|
str r0, [r1] @ tell Arm9 we're done
|
||||||
mov r0, #0x20000000
|
mov r0, #0x20000000
|
||||||
|
|
||||||
_wait_for_core0_entrypoint_loop:
|
_wait_for_core0_entrypoint_loop:
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
The data cache and/or the instruction cache MUST be flushed before doing one of the following:
|
The data cache and/or the instruction cache MUST be flushed before doing one of the following:
|
||||||
- rebooting
|
- rebooting
|
||||||
- powering down
|
- powering down
|
||||||
- setting the ARM11 entrypoint to execute a function
|
- setting the Arm11 entrypoint to execute a function
|
||||||
- jumping to a payload
|
- jumping to a payload
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
flushEntireDCache:
|
flushEntireDCache:
|
||||||
@ Adapted from http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0155a/ch03s03s05.html,
|
@ Adapted from http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0155a/ch03s03s05.html,
|
||||||
@ and https://github.com/gemarcano/libctr9_io/blob/master/src/ctr_system_ARM.c#L39 as well
|
@ and https://github.com/gemarcano/libctr9_io/blob/master/src/ctr_system_ARM.c#L39 as well
|
||||||
@ Note: ARM's example is actually for a 8KB DCache (which is what the 3DS has)
|
@ Note: Arm's example is actually for a 8KB DCache (which is what the 3DS has)
|
||||||
|
|
||||||
@ Implemented in bootROM at address 0xffff0830
|
@ Implemented in bootROM at address 0xffff0830
|
||||||
mov r1, #0 @ segment counter
|
mov r1, #0 @ segment counter
|
||||||
|
@ -94,7 +94,7 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
|
|||||||
"( ) Show NAND or user string in System Settings",
|
"( ) Show NAND or user string in System Settings",
|
||||||
"( ) Show GBA boot screen in patched AGB_FIRM",
|
"( ) Show GBA boot screen in patched AGB_FIRM",
|
||||||
"( ) Set developer UNITINFO",
|
"( ) Set developer UNITINFO",
|
||||||
"( ) Disable ARM11 exception handlers",
|
"( ) Disable Arm11 exception handlers",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *optionsDescription[] = { "Select the default EmuNAND.\n\n"
|
static const char *optionsDescription[] = { "Select the default EmuNAND.\n\n"
|
||||||
@ -189,7 +189,7 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
|
|||||||
"are doing!",
|
"are doing!",
|
||||||
|
|
||||||
"Disables the fatal error exception\n"
|
"Disables the fatal error exception\n"
|
||||||
"handlers for the ARM11 CPU.\n\n"
|
"handlers for the Arm11 CPU.\n\n"
|
||||||
"Note: Disabling the exception handlers\n"
|
"Note: Disabling the exception handlers\n"
|
||||||
"will disqualify you from submitting\n"
|
"will disqualify you from submitting\n"
|
||||||
"issues or bug reports to the Luma3DS\n"
|
"issues or bug reports to the Luma3DS\n"
|
||||||
|
@ -599,11 +599,11 @@ void kernel9Loader(Arm9Bin *arm9Section)
|
|||||||
__attribute__((aligned(4))) u8 arm9BinCtr[AES_BLOCK_SIZE];
|
__attribute__((aligned(4))) u8 arm9BinCtr[AES_BLOCK_SIZE];
|
||||||
memcpy(arm9BinCtr, arm9Section->ctr, sizeof(arm9BinCtr));
|
memcpy(arm9BinCtr, arm9Section->ctr, sizeof(arm9BinCtr));
|
||||||
|
|
||||||
//Decrypt ARM9 binary
|
//Decrypt Arm9 binary
|
||||||
aes_use_keyslot(arm9BinSlot);
|
aes_use_keyslot(arm9BinSlot);
|
||||||
aes(startOfArm9Bin, startOfArm9Bin, arm9SectionSize / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
aes(startOfArm9Bin, startOfArm9Bin, arm9SectionSize / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
|
|
||||||
if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Failed to decrypt the ARM9 binary.");
|
if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Failed to decrypt the Arm9 binary.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void computePinHash(u8 *outbuf, const u8 *inbuf)
|
void computePinHash(u8 *outbuf, const u8 *inbuf)
|
||||||
@ -612,7 +612,7 @@ void computePinHash(u8 *outbuf, const u8 *inbuf)
|
|||||||
cipherText[AES_BLOCK_SIZE];
|
cipherText[AES_BLOCK_SIZE];
|
||||||
|
|
||||||
sdmmc_get_cid(1, (u32 *)cid);
|
sdmmc_get_cid(1, (u32 *)cid);
|
||||||
aes_use_keyslot(0x04); //Console-unique keyslot whose keys are set by the ARM9 bootROM
|
aes_use_keyslot(0x04); //Console-unique keyslot whose keys are set by the Arm9 bootROM
|
||||||
aes(cipherText, inbuf, 1, cid, AES_CBC_ENCRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
aes(cipherText, inbuf, 1, cid, AES_CBC_ENCRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
sha(outbuf, cipherText, sizeof(cipherText), SHA_256_MODE);
|
sha(outbuf, cipherText, sizeof(cipherText), SHA_256_MODE);
|
||||||
}
|
}
|
||||||
|
@ -85,8 +85,8 @@ void detectAndProcessExceptionDumps(void)
|
|||||||
|
|
||||||
drawString(true, 10, 10, COLOR_RED, "An exception occurred");
|
drawString(true, 10, 10, COLOR_RED, "An exception occurred");
|
||||||
u32 posY;
|
u32 posY;
|
||||||
if(dumpHeader->processor == 11) posY = drawFormattedString(true, 10, 30, COLOR_WHITE, "Processor: ARM11 (core %u)", dumpHeader->core);
|
if(dumpHeader->processor == 11) posY = drawFormattedString(true, 10, 30, COLOR_WHITE, "Processor: Arm11 (core %u)", dumpHeader->core);
|
||||||
else posY = drawString(true, 10, 30, COLOR_WHITE, "Processor: ARM9");
|
else posY = drawString(true, 10, 30, COLOR_WHITE, "Processor: Arm9");
|
||||||
|
|
||||||
if(dumpHeader->type == 2)
|
if(dumpHeader->type == 2)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,7 @@ static __attribute__((noinline)) bool inRange(u32 as, u32 ae, u32 bs, u32 be)
|
|||||||
|
|
||||||
static bool checkFirm(u32 firmSize)
|
static bool checkFirm(u32 firmSize)
|
||||||
{
|
{
|
||||||
if(memcmp(firm->magic, "FIRM", 4) != 0 || firm->arm9Entry == NULL) //Allow for the ARM11 entrypoint to be zero in which case nothing is done on the ARM11 side
|
if(memcmp(firm->magic, "FIRM", 4) != 0 || firm->arm9Entry == NULL) //Allow for the Arm11 entrypoint to be zero in which case nothing is done on the Arm11 side
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool arm9EpFound = false,
|
bool arm9EpFound = false,
|
||||||
@ -184,7 +184,7 @@ u32 loadNintendoFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadF
|
|||||||
else if(ctrNandError) error("Unable to mount CTRNAND or load the CTRNAND FIRM.\nPlease use an external one.");
|
else if(ctrNandError) error("Unable to mount CTRNAND or load the CTRNAND FIRM.\nPlease use an external one.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check that the FIRM is right for the console from the ARM9 section address
|
//Check that the FIRM is right for the console from the Arm9 section address
|
||||||
if((firm->section[3].offset != 0 ? firm->section[3].address : firm->section[2].address) != (ISN3DS ? (u8 *)0x8006000 : (u8 *)0x8006800))
|
if((firm->section[3].offset != 0 ? firm->section[3].address : firm->section[2].address) != (ISN3DS ? (u8 *)0x8006000 : (u8 *)0x8006800))
|
||||||
error("The %s FIRM is not for this console.", loadedFromStorage ? "external" : "CTRNAND");
|
error("The %s FIRM is not for this console.", loadedFromStorage ? "external" : "CTRNAND");
|
||||||
|
|
||||||
@ -350,7 +350,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStora
|
|||||||
|
|
||||||
if(ISN3DS)
|
if(ISN3DS)
|
||||||
{
|
{
|
||||||
//Decrypt ARM9Bin and patch ARM9 entrypoint to skip kernel9loader
|
//Decrypt Arm9Bin and patch Arm9 entrypoint to skip kernel9loader
|
||||||
kernel9Loader((Arm9Bin *)arm9Section);
|
kernel9Loader((Arm9Bin *)arm9Section);
|
||||||
firm->arm9Entry = (u8 *)0x801B01C;
|
firm->arm9Entry = (u8 *)0x801B01C;
|
||||||
}
|
}
|
||||||
@ -409,7 +409,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStora
|
|||||||
if(!ISDEVUNIT) ret += patchCheckForDevCommonKey(process9Offset, process9Size);
|
if(!ISDEVUNIT) ret += patchCheckForDevCommonKey(process9Offset, process9Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//ARM9 exception handlers
|
//Arm9 exception handlers
|
||||||
ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size);
|
ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size);
|
||||||
ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address);
|
ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address);
|
||||||
ret += patchKernel9Panic(arm9Section, kernel9Size);
|
ret += patchKernel9Panic(arm9Section, kernel9Size);
|
||||||
@ -426,7 +426,7 @@ u32 patchTwlFirm(u32 firmVersion, bool loadFromStorage, bool doUnitinfoPatch)
|
|||||||
{
|
{
|
||||||
u8 *arm9Section = (u8 *)firm + firm->section[3].offset;
|
u8 *arm9Section = (u8 *)firm + firm->section[3].offset;
|
||||||
|
|
||||||
//On N3DS, decrypt ARM9Bin and patch ARM9 entrypoint to skip kernel9loader
|
//On N3DS, decrypt Arm9Bin and patch Arm9 entrypoint to skip kernel9loader
|
||||||
if(ISN3DS)
|
if(ISN3DS)
|
||||||
{
|
{
|
||||||
kernel9Loader((Arm9Bin *)arm9Section);
|
kernel9Loader((Arm9Bin *)arm9Section);
|
||||||
@ -465,7 +465,7 @@ u32 patchAgbFirm(bool loadFromStorage, bool doUnitinfoPatch)
|
|||||||
{
|
{
|
||||||
u8 *arm9Section = (u8 *)firm + firm->section[3].offset;
|
u8 *arm9Section = (u8 *)firm + firm->section[3].offset;
|
||||||
|
|
||||||
//On N3DS, decrypt ARM9Bin and patch ARM9 entrypoint to skip kernel9loader
|
//On N3DS, decrypt Arm9Bin and patch Arm9 entrypoint to skip kernel9loader
|
||||||
if(ISN3DS)
|
if(ISN3DS)
|
||||||
{
|
{
|
||||||
kernel9Loader((Arm9Bin *)arm9Section);
|
kernel9Loader((Arm9Bin *)arm9Section);
|
||||||
@ -501,7 +501,7 @@ u32 patch1x2xNativeAndSafeFirm(void)
|
|||||||
|
|
||||||
if(ISN3DS)
|
if(ISN3DS)
|
||||||
{
|
{
|
||||||
//Decrypt ARM9Bin and patch ARM9 entrypoint to skip kernel9loader
|
//Decrypt Arm9Bin and patch Arm9 entrypoint to skip kernel9loader
|
||||||
kernel9Loader((Arm9Bin *)arm9Section);
|
kernel9Loader((Arm9Bin *)arm9Section);
|
||||||
firm->arm9Entry = (u8 *)0x801B01C;
|
firm->arm9Entry = (u8 *)0x801B01C;
|
||||||
}
|
}
|
||||||
@ -518,7 +518,7 @@ u32 patch1x2xNativeAndSafeFirm(void)
|
|||||||
|
|
||||||
ret += ISN3DS ? patchSignatureChecks(process9Offset, process9Size) : patchOldSignatureChecks(process9Offset, process9Size);
|
ret += ISN3DS ? patchSignatureChecks(process9Offset, process9Size) : patchOldSignatureChecks(process9Offset, process9Size);
|
||||||
|
|
||||||
//ARM9 exception handlers
|
//Arm9 exception handlers
|
||||||
ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size);
|
ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size);
|
||||||
ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address);
|
ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address);
|
||||||
|
|
||||||
|
@ -79,8 +79,8 @@ u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 *
|
|||||||
return arm11SvcTable;
|
return arm11SvcTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For ARM prologs in the form of: push {regs} ... sub sp, #off (this obviously doesn't intend to cover all cases)
|
// For Arm prologs in the form of: push {regs} ... sub sp, #off (this obviously doesn't intend to cover all cases)
|
||||||
static inline u32 computeARMFrameSize(const u32 *prolog)
|
static inline u32 computeArmFrameSize(const u32 *prolog)
|
||||||
{
|
{
|
||||||
const u32 *off;
|
const u32 *off;
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ u32 patchKernel11(u8 *pos, u32 size, u32 baseK11VA, u32 *arm11SvcTable, u32 *arm
|
|||||||
*/
|
*/
|
||||||
for(off = (u32 *)ControlMemoryPos; (off[0] & 0xFFF0FFFF) != 0xE3500001 || (off[1] & 0xFFFF0FFF) != 0x13A00000; off++);
|
for(off = (u32 *)ControlMemoryPos; (off[0] & 0xFFF0FFFF) != 0xE3500001 || (off[1] & 0xFFFF0FFF) != 0x13A00000; off++);
|
||||||
off -= 2;
|
off -= 2;
|
||||||
*off = 0xE59D0000 | (*off & 0x0000F000) | (8 + computeARMFrameSize((u32 *)ControlMemoryPos)); // ldr r0, [sp, #(frameSize + 8)]
|
*off = 0xE59D0000 | (*off & 0x0000F000) | (8 + computeArmFrameSize((u32 *)ControlMemoryPos)); // ldr r0, [sp, #(frameSize + 8)]
|
||||||
|
|
||||||
//Patch DebugActiveProcess
|
//Patch DebugActiveProcess
|
||||||
for(off = (u32 *)(pos + (arm11SvcTable[0x60] - baseK11VA)); *off != 0xE3110001; off++);
|
for(off = (u32 *)(pos + (arm11SvcTable[0x60] - baseK11VA)); *off != 0xE3110001; off++);
|
||||||
@ -312,7 +312,7 @@ u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr)
|
|||||||
|
|
||||||
off -= 0x13;
|
off -= 0x13;
|
||||||
|
|
||||||
//Firmlaunch function offset - offset in BLX opcode (A4-16 - ARM DDI 0100E) + 1
|
//Firmlaunch function offset - offset in BLX opcode (A4-16 - Arm DDI 0100E) + 1
|
||||||
u32 fOpenOffset = (u32)(off + 9 - (-((*(u32 *)off & 0x00FFFFFF) << 2) & (0xFFFFFF << 2)) - pos + process9MemAddr);
|
u32 fOpenOffset = (u32)(off + 9 - (-((*(u32 *)off & 0x00FFFFFF) << 2) & (0xFFFFFF << 2)) - pos + process9MemAddr);
|
||||||
|
|
||||||
//Put the fOpen offset in the right location
|
//Put the fOpen offset in the right location
|
||||||
|
@ -77,7 +77,7 @@ _start:
|
|||||||
ldr r1, =0xFFF0001B @ fff00000 16k | dtcm
|
ldr r1, =0xFFF0001B @ fff00000 16k | dtcm
|
||||||
ldr r2, =0x01FF801D @ 01ff8000 32k | itcm
|
ldr r2, =0x01FF801D @ 01ff8000 32k | itcm
|
||||||
ldr r3, =0x08000027 @ 08000000 1M | arm9 mem
|
ldr r3, =0x08000027 @ 08000000 1M | arm9 mem
|
||||||
ldr r4, =0x10000029 @ 10000000 2M | io mem (ARM9 / first 2MB)
|
ldr r4, =0x10000029 @ 10000000 2M | io mem (Arm9 / first 2MB)
|
||||||
ldr r5, =0x20000035 @ 20000000 128M | fcram
|
ldr r5, =0x20000035 @ 20000000 128M | fcram
|
||||||
ldr r6, =0x1FF00027 @ 1FF00000 1M | dsp / axi wram
|
ldr r6, =0x1FF00027 @ 1FF00000 1M | dsp / axi wram
|
||||||
ldr r7, =0x1800002D @ 18000000 8M | vram (+ 2MB)
|
ldr r7, =0x1800002D @ 18000000 8M | vram (+ 2MB)
|
||||||
@ -153,11 +153,11 @@ disableMpuAndJumpToEntrypoints:
|
|||||||
bic r0, #(1<<0) @ - MPU disable
|
bic r0, #(1<<0) @ - MPU disable
|
||||||
mcr p15, 0, r0, c1, c0, 0 @ write control register
|
mcr p15, 0, r0, c1, c0, 0 @ write control register
|
||||||
|
|
||||||
@ Set the ARM11 entrypoint
|
@ Set the Arm11 entrypoint
|
||||||
mov r0, #0x20000000
|
mov r0, #0x20000000
|
||||||
str r7, [r0, #-4]
|
str r7, [r0, #-4]
|
||||||
|
|
||||||
@ Jump to the ARM9 entrypoint
|
@ Jump to the Arm9 entrypoint
|
||||||
mov r0, r4
|
mov r0, r4
|
||||||
mov r1, r5
|
mov r1, r5
|
||||||
ldr r2, =0x3BEEF
|
ldr r2, =0x3BEEF
|
||||||
|
@ -121,8 +121,8 @@ def main(args=None):
|
|||||||
addtionalDataOffset = stackOffset + stackDumpSize
|
addtionalDataOffset = stackOffset + stackDumpSize
|
||||||
additionalData = data[addtionalDataOffset : addtionalDataOffset + additionalDataSize]
|
additionalData = data[addtionalDataOffset : addtionalDataOffset + additionalDataSize]
|
||||||
|
|
||||||
if processor == 9: print("Processor: ARM9")
|
if processor == 9: print("Processor: Arm9")
|
||||||
else: print("Processor: ARM11 (core {0})".format(processor >> 16))
|
else: print("Processor: Arm11 (core {0})".format(processor >> 16))
|
||||||
|
|
||||||
typeDetailsStr = ""
|
typeDetailsStr = ""
|
||||||
if exceptionType == 2:
|
if exceptionType == 2:
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#define PA_PTR(addr) (void *)((u32)(addr) | 1u << 31)
|
#define PA_PTR(addr) (void *)((u32)(addr) | 1u << 31)
|
||||||
#define PA_FROM_VA_PTR(addr) PA_PTR(convertVAToPA(addr, false))
|
#define PA_FROM_VA_PTR(addr) PA_PTR(convertVAToPA(addr, false))
|
||||||
|
|
||||||
static inline u32 makeARMBranch(const void *src, const void *dst, bool link) // the macros for those are ugly and buggy
|
static inline u32 makeArmBranch(const void *src, const void *dst, bool link) // the macros for those are ugly and buggy
|
||||||
{
|
{
|
||||||
u32 instrBase = link ? 0xEB000000 : 0xEA000000;
|
u32 instrBase = link ? 0xEB000000 : 0xEA000000;
|
||||||
u32 off = (u32)((const u8 *)dst - ((const u8 *)src + 8)); // the PC is always two instructions ahead of the one being executed
|
u32 off = (u32)((const u8 *)dst - ((const u8 *)src + 8)); // the PC is always two instructions ahead of the one being executed
|
||||||
@ -41,7 +41,7 @@ static inline u32 makeARMBranch(const void *src, const void *dst, bool link) //
|
|||||||
return instrBase | ((off >> 2) & 0xFFFFFF);
|
return instrBase | ((off >> 2) & 0xFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *decodeARMBranch(const void *src)
|
static inline void *decodeArmBranch(const void *src)
|
||||||
{
|
{
|
||||||
u32 instr = *(const u32 *)src;
|
u32 instr = *(const u32 *)src;
|
||||||
s32 off = (instr & 0xFFFFFF) << 2;
|
s32 off = (instr & 0xFFFFFF) << 2;
|
||||||
@ -50,8 +50,8 @@ static inline void *decodeARMBranch(const void *src)
|
|||||||
return (void *)((const u8 *)src + 8 + off);
|
return (void *)((const u8 *)src + 8 + off);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For ARM prologs in the form of: push {regs} ... sub sp, #off (this obviously doesn't intend to cover all cases)
|
// For Arm prologs in the form of: push {regs} ... sub sp, #off (this obviously doesn't intend to cover all cases)
|
||||||
static inline u32 computeARMFrameSize(const u32 *prolog)
|
static inline u32 computeArmFrameSize(const u32 *prolog)
|
||||||
{
|
{
|
||||||
const u32 *off;
|
const u32 *off;
|
||||||
|
|
||||||
|
@ -108,67 +108,67 @@ static void findUsefulSymbols(void)
|
|||||||
|
|
||||||
for(; *off != 0xE3A0A0C2; off++);
|
for(; *off != 0xE3A0A0C2; off++);
|
||||||
mcuReboot = (void (*) (void))--off;
|
mcuReboot = (void (*) (void))--off;
|
||||||
coreBarrier = (void (*) (void))decodeARMBranch(off - 4);
|
coreBarrier = (void (*) (void))decodeArmBranch(off - 4);
|
||||||
|
|
||||||
for(off = (u32 *)originalHandlers[2]; *off != 0xE1A00009; off++);
|
for(off = (u32 *)originalHandlers[2]; *off != 0xE1A00009; off++);
|
||||||
svcFallbackHandler = (void (*)(u8))decodeARMBranch(off + 1);
|
svcFallbackHandler = (void (*)(u8))decodeArmBranch(off + 1);
|
||||||
for(; *off != 0xE92D000F; off++);
|
for(; *off != 0xE92D000F; off++);
|
||||||
officialPostProcessSvc = (void (*)(void))decodeARMBranch(off + 1);
|
officialPostProcessSvc = (void (*)(void))decodeArmBranch(off + 1);
|
||||||
|
|
||||||
KProcessHandleTable__ToKProcess = (KProcess * (*)(KProcessHandleTable *, Handle))decodeARMBranch(5 + (u32 *)officialSVCs[0x76]);
|
KProcessHandleTable__ToKProcess = (KProcess * (*)(KProcessHandleTable *, Handle))decodeArmBranch(5 + (u32 *)officialSVCs[0x76]);
|
||||||
|
|
||||||
for(off = (u32 *)KProcessHandleTable__ToKProcess; *off != 0xE1A00004; off++);
|
for(off = (u32 *)KProcessHandleTable__ToKProcess; *off != 0xE1A00004; off++);
|
||||||
KAutoObject__AddReference = (void (*)(KAutoObject *))decodeARMBranch(off + 1);
|
KAutoObject__AddReference = (void (*)(KAutoObject *))decodeArmBranch(off + 1);
|
||||||
|
|
||||||
for(; *off != 0xE320F000; off++);
|
for(; *off != 0xE320F000; off++);
|
||||||
KProcessHandleTable__ToKAutoObject = (KAutoObject * (*)(KProcessHandleTable *, Handle))decodeARMBranch(off + 1);
|
KProcessHandleTable__ToKAutoObject = (KAutoObject * (*)(KProcessHandleTable *, Handle))decodeArmBranch(off + 1);
|
||||||
|
|
||||||
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[9]); /* KThread::Terminate */ *off != 0xE5D42034; off++);
|
for(off = (u32 *)decodeArmBranch(3 + (u32 *)officialSVCs[9]); /* KThread::Terminate */ *off != 0xE5D42034; off++);
|
||||||
off -= 2;
|
off -= 2;
|
||||||
criticalSectionLock = (KRecursiveLock *)off[2 + (off[0] & 0xFF) / 4];
|
criticalSectionLock = (KRecursiveLock *)off[2 + (off[0] & 0xFF) / 4];
|
||||||
KRecursiveLock__Lock = (void (*)(KRecursiveLock *))decodeARMBranch(off + 1);
|
KRecursiveLock__Lock = (void (*)(KRecursiveLock *))decodeArmBranch(off + 1);
|
||||||
off += 4;
|
off += 4;
|
||||||
|
|
||||||
for(; (*off >> 16) != 0xE59F; off++);
|
for(; (*off >> 16) != 0xE59F; off++);
|
||||||
KRecursiveLock__Unlock = (void (*)(KRecursiveLock *))decodeARMBranch(off + 1);
|
KRecursiveLock__Unlock = (void (*)(KRecursiveLock *))decodeArmBranch(off + 1);
|
||||||
|
|
||||||
for(; *off != 0xE5C4007D; off++);
|
for(; *off != 0xE5C4007D; off++);
|
||||||
KSynchronizationObject__Signal = (void (*)(KSynchronizationObject *, bool))decodeARMBranch(off + 3);
|
KSynchronizationObject__Signal = (void (*)(KSynchronizationObject *, bool))decodeArmBranch(off + 3);
|
||||||
|
|
||||||
for(off = (u32 *)officialSVCs[0x19]; *off != 0xE1A04005; off++);
|
for(off = (u32 *)officialSVCs[0x19]; *off != 0xE1A04005; off++);
|
||||||
KEvent__Clear = (Result (*)(KEvent *))decodeARMBranch(off + 1);
|
KEvent__Clear = (Result (*)(KEvent *))decodeArmBranch(off + 1);
|
||||||
for(off = (u32 *)KEvent__Clear; *off != 0xE8BD8070; off++);
|
for(off = (u32 *)KEvent__Clear; *off != 0xE8BD8070; off++);
|
||||||
synchronizationMutex = *(KObjectMutex **)(off + 1);
|
synchronizationMutex = *(KObjectMutex **)(off + 1);
|
||||||
|
|
||||||
for(off = (u32 *)officialSVCs[0x24]; *off != 0xE59F004C; off++);
|
for(off = (u32 *)officialSVCs[0x24]; *off != 0xE59F004C; off++);
|
||||||
WaitSynchronization1 = (Result (*)(void *, KThread *, KSynchronizationObject *, s64))decodeARMBranch(off + 6);
|
WaitSynchronization1 = (Result (*)(void *, KThread *, KSynchronizationObject *, s64))decodeArmBranch(off + 6);
|
||||||
|
|
||||||
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x33]) /* OpenProcess */ ; *off != 0xE1A05000; off++);
|
for(off = (u32 *)decodeArmBranch(3 + (u32 *)officialSVCs[0x33]) /* OpenProcess */ ; *off != 0xE1A05000; off++);
|
||||||
KProcessHandleTable__CreateHandle = (Result (*)(KProcessHandleTable *, Handle *, KAutoObject *, u8))decodeARMBranch(off - 1);
|
KProcessHandleTable__CreateHandle = (Result (*)(KProcessHandleTable *, Handle *, KAutoObject *, u8))decodeArmBranch(off - 1);
|
||||||
|
|
||||||
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x34]) /* OpenThread */; *off != 0xD9001BF7; off++);
|
for(off = (u32 *)decodeArmBranch(3 + (u32 *)officialSVCs[0x34]) /* OpenThread */; *off != 0xD9001BF7; off++);
|
||||||
threadList = *(KObjectList **)(off + 1);
|
threadList = *(KObjectList **)(off + 1);
|
||||||
|
|
||||||
off = (u32 *)decodeARMBranch((u32 *)officialSVCs[0x37] + 3) + 5; /* GetThreadId */
|
off = (u32 *)decodeArmBranch((u32 *)officialSVCs[0x37] + 3) + 5; /* GetThreadId */
|
||||||
KProcessHandleTable__ToKThread = (KThread * (*)(KProcessHandleTable *, Handle))decodeARMBranch((*off >> 16) == 0xEB00 ? off : off + 2);
|
KProcessHandleTable__ToKThread = (KThread * (*)(KProcessHandleTable *, Handle))decodeArmBranch((*off >> 16) == 0xEB00 ? off : off + 2);
|
||||||
|
|
||||||
for(off = (u32 *)officialSVCs[0x50]; off[0] != 0xE1A05000 || off[1] != 0xE2100102 || off[2] != 0x5A00000B; off++);
|
for(off = (u32 *)officialSVCs[0x50]; off[0] != 0xE1A05000 || off[1] != 0xE2100102 || off[2] != 0x5A00000B; off++);
|
||||||
InterruptManager__MapInterrupt = (Result (*)(InterruptManager *, KBaseInterruptEvent *, u32, u32, u32, bool, bool))decodeARMBranch(--off);
|
InterruptManager__MapInterrupt = (Result (*)(InterruptManager *, KBaseInterruptEvent *, u32, u32, u32, bool, bool))decodeArmBranch(--off);
|
||||||
interruptManager = *(InterruptManager **)(off - 4 + (off[-6] & 0xFFF) / 4);
|
interruptManager = *(InterruptManager **)(off - 4 + (off[-6] & 0xFFF) / 4);
|
||||||
for(off = (u32 *)officialSVCs[0x54]; *off != 0xE8BD8008; off++);
|
for(off = (u32 *)officialSVCs[0x54]; *off != 0xE8BD8008; off++);
|
||||||
flushDataCacheRange = (void (*)(void *, u32))(*(u32 **)(off[1]) + 3);
|
flushDataCacheRange = (void (*)(void *, u32))(*(u32 **)(off[1]) + 3);
|
||||||
|
|
||||||
for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++);
|
for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++);
|
||||||
KProcessHwInfo__MapProcessMemory = (Result (*)(KProcessHwInfo *, KProcessHwInfo *, void *, void *, u32))decodeARMBranch(off - 1);
|
KProcessHwInfo__MapProcessMemory = (Result (*)(KProcessHwInfo *, KProcessHwInfo *, void *, void *, u32))decodeArmBranch(off - 1);
|
||||||
|
|
||||||
// From 4.x to 6.x the pattern will match but the result will be wrong
|
// From 4.x to 6.x the pattern will match but the result will be wrong
|
||||||
for(off = (u32 *)officialSVCs[0x72]; *off != 0xE2041102; off++);
|
for(off = (u32 *)officialSVCs[0x72]; *off != 0xE2041102; off++);
|
||||||
KProcessHwInfo__UnmapProcessMemory = (Result (*)(KProcessHwInfo *, void *, u32))decodeARMBranch(off - 1);
|
KProcessHwInfo__UnmapProcessMemory = (Result (*)(KProcessHwInfo *, void *, u32))decodeArmBranch(off - 1);
|
||||||
|
|
||||||
for(off = (u32 *)officialSVCs[0x7C]; *off != 0x03530000; off++);
|
for(off = (u32 *)officialSVCs[0x7C]; *off != 0x03530000; off++);
|
||||||
KObjectMutex__WaitAndAcquire = (void (*)(KObjectMutex *))decodeARMBranch(++off);
|
KObjectMutex__WaitAndAcquire = (void (*)(KObjectMutex *))decodeArmBranch(++off);
|
||||||
for(; *off != 0xE320F000; off++);
|
for(; *off != 0xE320F000; off++);
|
||||||
KObjectMutex__ErrorOccured = (void (*)(void))decodeARMBranch(off + 1);
|
KObjectMutex__ErrorOccured = (void (*)(void))decodeArmBranch(off + 1);
|
||||||
|
|
||||||
for(off = (u32 *)originalHandlers[4]; *off != (u32)exceptionStackTop; off++);
|
for(off = (u32 *)originalHandlers[4]; *off != (u32)exceptionStackTop; off++);
|
||||||
kernelUsrCopyFuncsStart = (void *)off[1];
|
kernelUsrCopyFuncsStart = (void *)off[1];
|
||||||
@ -208,26 +208,26 @@ static void findUsefulSymbols(void)
|
|||||||
|
|
||||||
// The official prototype of ControlMemory doesn't have that extra param'
|
// The official prototype of ControlMemory doesn't have that extra param'
|
||||||
ControlMemory = (Result (*)(u32 *, u32, u32, u32, MemOp, MemPerm, bool))
|
ControlMemory = (Result (*)(u32 *, u32, u32, u32, MemOp, MemPerm, bool))
|
||||||
decodeARMBranch((u32 *)officialSVCs[0x01] + 5);
|
decodeArmBranch((u32 *)officialSVCs[0x01] + 5);
|
||||||
SleepThread = (void (*)(s64))officialSVCs[0x0A];
|
SleepThread = (void (*)(s64))officialSVCs[0x0A];
|
||||||
CloseHandle = (Result (*)(Handle))officialSVCs[0x23];
|
CloseHandle = (Result (*)(Handle))officialSVCs[0x23];
|
||||||
GetHandleInfo = (Result (*)(s64 *, Handle, u32))decodeARMBranch((u32 *)officialSVCs[0x29] + 3);
|
GetHandleInfo = (Result (*)(s64 *, Handle, u32))decodeArmBranch((u32 *)officialSVCs[0x29] + 3);
|
||||||
GetSystemInfo = (Result (*)(s64 *, s32, s32))decodeARMBranch((u32 *)officialSVCs[0x2A] + 3);
|
GetSystemInfo = (Result (*)(s64 *, s32, s32))decodeArmBranch((u32 *)officialSVCs[0x2A] + 3);
|
||||||
GetProcessInfo = (Result (*)(s64 *, Handle, u32))decodeARMBranch((u32 *)officialSVCs[0x2B] + 3);
|
GetProcessInfo = (Result (*)(s64 *, Handle, u32))decodeArmBranch((u32 *)officialSVCs[0x2B] + 3);
|
||||||
GetThreadInfo = (Result (*)(s64 *, Handle, u32))decodeARMBranch((u32 *)officialSVCs[0x2C] + 3);
|
GetThreadInfo = (Result (*)(s64 *, Handle, u32))decodeArmBranch((u32 *)officialSVCs[0x2C] + 3);
|
||||||
ConnectToPort = (Result (*)(Handle *, const char*))decodeARMBranch((u32 *)officialSVCs[0x2D] + 3);
|
ConnectToPort = (Result (*)(Handle *, const char*))decodeArmBranch((u32 *)officialSVCs[0x2D] + 3);
|
||||||
SendSyncRequest = (Result (*)(Handle))officialSVCs[0x32];
|
SendSyncRequest = (Result (*)(Handle))officialSVCs[0x32];
|
||||||
OpenProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x33] + 3);
|
OpenProcess = (Result (*)(Handle *, u32))decodeArmBranch((u32 *)officialSVCs[0x33] + 3);
|
||||||
GetProcessId = (Result (*)(u32 *, Handle))decodeARMBranch((u32 *)officialSVCs[0x35] + 3);
|
GetProcessId = (Result (*)(u32 *, Handle))decodeArmBranch((u32 *)officialSVCs[0x35] + 3);
|
||||||
DebugActiveProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x60] + 3);
|
DebugActiveProcess = (Result (*)(Handle *, u32))decodeArmBranch((u32 *)officialSVCs[0x60] + 3);
|
||||||
UnmapProcessMemory = (Result (*)(Handle, void *, u32))officialSVCs[0x72];
|
UnmapProcessMemory = (Result (*)(Handle, void *, u32))officialSVCs[0x72];
|
||||||
KernelSetState = (Result (*)(u32, u32, u32, u32))((u32 *)officialSVCs[0x7C] + 1);
|
KernelSetState = (Result (*)(u32, u32, u32, u32))((u32 *)officialSVCs[0x7C] + 1);
|
||||||
|
|
||||||
for(off = (u32 *)svcFallbackHandler; *off != 0xE8BD4010; off++);
|
for(off = (u32 *)svcFallbackHandler; *off != 0xE8BD4010; off++);
|
||||||
kernelpanic = (void (*)(void))decodeARMBranch(off + 1);
|
kernelpanic = (void (*)(void))decodeArmBranch(off + 1);
|
||||||
|
|
||||||
for(off = (u32 *)0xFFFF0000; off[0] != 0xE3A01002 || off[1] != 0xE3A00004; off++);
|
for(off = (u32 *)0xFFFF0000; off[0] != 0xE3A01002 || off[1] != 0xE3A00004; off++);
|
||||||
SignalDebugEvent = (Result (*)(DebugEventType type, u32 info, ...))decodeARMBranch(off + 2);
|
SignalDebugEvent = (Result (*)(DebugEventType type, u32 info, ...))decodeArmBranch(off + 2);
|
||||||
|
|
||||||
for(; *off != 0x96007F9; off++);
|
for(; *off != 0x96007F9; off++);
|
||||||
isDevUnit = *(bool **)(off - 1);
|
isDevUnit = *(bool **)(off - 1);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# 3ds_pm
|
# 3ds_pm
|
||||||
Open source replacement of the ARM11 PM system module.
|
Open source replacement of the Arm11 PM system module.
|
||||||
This is licensed under the MIT license.
|
This is licensed under the MIT license.
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# 3ds_pxi
|
# 3ds_pxi
|
||||||
Open source replacement of the ARM11 PXI system module.
|
Open source replacement of the Arm11 PXI system module.
|
||||||
This is licensed under the MIT license.
|
This is licensed under the MIT license.
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
#define REG32(addr) (*(vu32 *)(PA_PTR(addr)))
|
#define REG32(addr) (*(vu32 *)(PA_PTR(addr)))
|
||||||
|
|
||||||
static inline u32 makeARMBranch(const void *src, const void *dst, bool link) // the macros for those are ugly and buggy
|
static inline u32 makeArmBranch(const void *src, const void *dst, bool link) // the macros for those are ugly and buggy
|
||||||
{
|
{
|
||||||
u32 instrBase = link ? 0xEB000000 : 0xEA000000;
|
u32 instrBase = link ? 0xEB000000 : 0xEA000000;
|
||||||
u32 off = (u32)((const u8 *)dst - ((const u8 *)src + 8)); // the PC is always two instructions ahead of the one being executed
|
u32 off = (u32)((const u8 *)dst - ((const u8 *)src + 8)); // the PC is always two instructions ahead of the one being executed
|
||||||
@ -47,7 +47,7 @@ static inline u32 makeARMBranch(const void *src, const void *dst, bool link) //
|
|||||||
return instrBase | ((off >> 2) & 0xFFFFFF);
|
return instrBase | ((off >> 2) & 0xFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *decodeARMBranch(const void *src)
|
static inline void *decodeArmBranch(const void *src)
|
||||||
{
|
{
|
||||||
u32 instr = *(const u32 *)src;
|
u32 instr = *(const u32 *)src;
|
||||||
s32 off = (instr & 0xFFFFFF) << 2;
|
s32 off = (instr & 0xFFFFFF) << 2;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
There are only 2 Watchpoint Register Pairs on MPCORE ARM11 CPUs,
|
There are only 2 Watchpoint Register Pairs on MPCORE Arm11 CPUs,
|
||||||
and only 2 Breakpoint Register Pairs with context ID capabilities (BRP4-5) as well.
|
and only 2 Breakpoint Register Pairs with context ID capabilities (BRP4-5) as well.
|
||||||
|
|
||||||
We'll reserve and use all 4 of them
|
We'll reserve and use all 4 of them
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include "utils.h" // for makeARMBranch
|
#include "utils.h" // for makeArmBranch
|
||||||
#include "minisoc.h"
|
#include "minisoc.h"
|
||||||
#include "input_redirection.h"
|
#include "input_redirection.h"
|
||||||
#include "menus.h"
|
#include "menus.h"
|
||||||
@ -315,7 +315,7 @@ Result InputRedirection_DoOrUndoPatches(void)
|
|||||||
return -6;
|
return -6;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(void **)(irCodePhys + 8) = decodeARMBranch(off + 4);
|
*(void **)(irCodePhys + 8) = decodeArmBranch(off + 4);
|
||||||
*(void **)(irCodePhys + 12) = (void*)irDataPhys;
|
*(void **)(irCodePhys + 12) = (void*)irDataPhys;
|
||||||
|
|
||||||
irHookLoc = off;
|
irHookLoc = off;
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "hbloader.h"
|
#include "hbloader.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "utils.h" // for makeARMBranch
|
#include "utils.h" // for makeArmBranch
|
||||||
#include "minisoc.h"
|
#include "minisoc.h"
|
||||||
#include "ifile.h"
|
#include "ifile.h"
|
||||||
#include "pmdbgext.h"
|
#include "pmdbgext.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# 3ds_sm
|
# 3ds_sm
|
||||||
Open source replacement of the ARM11 SM system module.
|
Open source replacement of the Arm11 SM system module.
|
||||||
This is licensed under the MIT license.
|
This is licensed under the MIT license.
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
Reference in New Issue
Block a user