From e17ff097138b950deef3b9c05e94c3f265303197 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sat, 23 Apr 2022 13:03:30 +0200 Subject: [PATCH 1/5] rosalina: Add define to print process creation time --- sysmodules/rosalina/source/menus/process_list.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/sysmodules/rosalina/source/menus/process_list.c b/sysmodules/rosalina/source/menus/process_list.c index 950bcdf..b556b5b 100644 --- a/sysmodules/rosalina/source/menus/process_list.c +++ b/sysmodules/rosalina/source/menus/process_list.c @@ -42,6 +42,7 @@ typedef struct ProcessInfo { u32 pid; + u32 creationTimeMs; u64 titleId; char name[8]; bool isZombie; @@ -87,6 +88,13 @@ static inline int ProcessListMenu_FormatInfoLine(char *out, const ProcessInfo *i } } + else + { +#ifdef ROSALINA_PRINT_PROCESS_CREATION_TIME + sprintf(commentBuf, "%lums\n", info->creationTimeMs); +#endif + } + if (gdbServer.super.running) GDB_UnlockAllContexts(&gdbServer); return sprintf(out, "%s%-4lu %-8.8s %s", checkbox, info->pid, info->name, commentBuf); // Theoritically PIDs are 32-bit ints, but we'll only justify 4 digits @@ -422,7 +430,7 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info) const u32 infoY = instructionsY + SPACING_Y; viewerY += SPACING_Y; if(codeAvailable && heapAvailable) - { + { Draw_DrawString(10, infoY, COLOR_WHITE, "Press L or R to switch between heap and code."); if((u32)menus[MENU_MODE_NORMAL].buf == heapDestAddress) Draw_DrawString(10 + SPACING_X * 31, infoY, COLOR_GREEN, "heap"); @@ -463,7 +471,7 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info) color = COLOR_WHITE; u8 val = menus[menuMode].buf[address]; - + if(ascii) Draw_DrawFormattedString(x, y, color, "%c ", u8ToChar(val)); else @@ -661,7 +669,8 @@ s32 ProcessListMenu_FetchInfo(void) for(s32 i = 0; i < processAmount; i++) { - Handle processHandle; + Handle processHandle = 0; + s64 creationTimeTicks = 0; Result res = svcOpenProcess(&processHandle, pidList[i]); if(R_FAILED(res)) continue; @@ -670,6 +679,8 @@ s32 ProcessListMenu_FetchInfo(void) svcGetProcessInfo((s64 *)&infos[i].name, processHandle, 0x10000); svcGetProcessInfo((s64 *)&infos[i].titleId, processHandle, 0x10001); infos[i].isZombie = svcWaitSynchronization(processHandle, 0) == 0; + svcGetHandleInfo(&creationTimeTicks, processHandle, 0); + infos[i].creationTimeMs = (u32)(1000 * creationTimeTicks / SYSCLOCK_ARM11); svcCloseHandle(processHandle); } From 65825020ab4d5c3cb030d6d27cb6c10016264248 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sat, 23 Apr 2022 23:55:48 +0200 Subject: [PATCH 2/5] bootdiag: add process list dumping --- sysmodules/rosalina/source/bootdiag.c | 39 ++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/sysmodules/rosalina/source/bootdiag.c b/sysmodules/rosalina/source/bootdiag.c index 09c971e..b6fe02d 100644 --- a/sysmodules/rosalina/source/bootdiag.c +++ b/sysmodules/rosalina/source/bootdiag.c @@ -29,15 +29,40 @@ #include "ifile.h" #include "fmt.h" +//#define BOOTDIAG_ENABLED #ifdef BOOTDIAG_ENABLED static MyThread bootdiagThread; static u8 ALIGN(0x1000) bootdiagThreadStack[0x1000]; -#define BOOTDIAG_WAIT_TIME (2000 * 1000 * 1000u) // 2 seconds -#define BOOTDIAG_PID 2u // PM +#define BOOTDIAG_WAIT_TIME (3500 * 1000 * 1000u) // 2 seconds +#define BOOTDIAG_DUMP_PLIST 1 +#define BOOTDIAG_PID 1u #define BOOTDIAG_DUMP_TO_FILE 0 +static int bootdiagDumpProcessList(char *buf) +{ + int n = 0; + u32 pids[40]; + s32 numProcesses = 0; + if (R_FAILED(svcGetProcessList(&numProcesses, pids, 0x40))) __builtin_trap(); + + for (s32 i = 0; i < numProcesses; i++) + { + s64 tmp = 0; + char name[9] = {0}; + Handle h; + svcOpenProcess(&h, pids[i]); + svcGetProcessInfo(&tmp, h, 0x10000); + memcpy(name, &tmp, 8); + svcGetHandleInfo(&tmp, h, 0); + u32 creationTimeMs = (u32)(1000 * tmp / SYSCLOCK_ARM11); + svcCloseHandle(h); + n += sprintf(buf + n, "#%4lu - %8s %lums\n", pids[i], name, creationTimeMs); + } + + return n; +} static int bootdiagDumpThread(char *buf, Handle debug, u32 tid) { ThreadContext ctx; @@ -78,10 +103,16 @@ static int bootdiagDumpProcess(char *buf, u32 pid) static void bootdiagThreadMain(void) { - char buf[512]; + char buf[1024]; svcSleepThread(BOOTDIAG_WAIT_TIME); - int n = bootdiagDumpProcess(buf, BOOTDIAG_PID); + int n = 0; +#if BOOTDIAG_DUMP_PLIST == 1 + n += bootdiagDumpProcessList(buf + n); +#else + (void)bootdiagDumpProcessList; +#endif + n += bootdiagDumpProcess(buf + n, BOOTDIAG_PID); #if BOOTDIAG_DUMP_TO_FILE IFile file; From 6573fc4247edc898124fa6e85b4b0efaa3bbbc3b Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Mon, 2 May 2022 15:57:08 +0100 Subject: [PATCH 3/5] k11ext: fix wrong condition bug --- k11_extension/source/svc/ControlService.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/k11_extension/source/svc/ControlService.c b/k11_extension/source/svc/ControlService.c index de4349d..adc0b33 100644 --- a/k11_extension/source/svc/ControlService.c +++ b/k11_extension/source/svc/ControlService.c @@ -73,14 +73,11 @@ Result ControlService(ServiceOp op, u32 varg1, u32 varg2) { char name[12] = { 0 }; SessionInfo *info = NULL; - if(name != NULL) - { - s32 nb = usrToKernelStrncpy(name, (const char *)varg2, 12); - if(nb < 0) - return 0xD9001814; - else if(nb == 12 && name[11] != 0) - return 0xE0E0181E; - } + s32 nb = usrToKernelStrncpy(name, (const char *)varg2, 12); + if(nb < 0) + return 0xD9001814; + else if(nb == 12 && name[11] != 0) + return 0xE0E0181E; info = SessionInfo_FindFirst(name); From ea8f9f466793753da2f53b8501517a466dad1cd6 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Fri, 6 May 2022 19:53:27 +0100 Subject: [PATCH 4/5] loader: refactor part around HIO --- sysmodules/loader/source/loader.c | 84 ++++++++++--------------------- sysmodules/pm/source/info.c | 2 + 2 files changed, 28 insertions(+), 58 deletions(-) diff --git a/sysmodules/loader/source/loader.c b/sysmodules/loader/source/loader.c index d0d8a28..cb98d57 100644 --- a/sysmodules/loader/source/loader.c +++ b/sysmodules/loader/source/loader.c @@ -154,26 +154,21 @@ static Result loadCode(u64 titleId, prog_addrs_t *shared, u64 programHandle, int return 0; } -static Result GetProgramInfo(ExHeader_Info *exheaderInfo, u64 programHandle) +static inline bool IsHioId(u64 id) { - Result res = 0; + // FS load HIO titles at boot when it can. For HIO titles, title/programId and "program handle" + // are the same thing, although some of them can be aliased with their "real" titleId (i.e. in ExHeader). - if (programHandle >> 32 == 0xFFFF0000) - res = FSREG_GetProgramInfo(exheaderInfo, 1, programHandle); + if (id >> 32 == 0xFFFF0000u) + return true; else - { - res = FSREG_CheckHostLoadId(programHandle); - //if ((res >= 0 && (unsigned)res >> 27) || (res < 0 && ((unsigned)res >> 27)-32)) - //so use PXIPM if FSREG fails OR returns "info", is the second condition a bug? - if (R_FAILED(res) || (R_SUCCEEDED(res) && R_LEVEL(res) != RL_SUCCESS)) - { - TRY(PXIPM_GetProgramInfo(exheaderInfo, programHandle)); - } - else - { - TRY(FSREG_GetProgramInfo(exheaderInfo, 1, programHandle)); - } - } + return R_LEVEL(FSREG_CheckHostLoadId(id)) == RL_SUCCESS; // check if this is an alias to an HIO-loaded title +} + +static Result GetProgramInfo(ExHeader_Info *exheaderInfo, u64 programHandle) +{ + Result res; + TRY(IsHioId(programHandle) ? FSREG_GetProgramInfo(exheaderInfo, 1, programHandle) : PXIPM_GetProgramInfo(exheaderInfo, programHandle)); // Tweak 3dsx placeholder title exheaderInfo if (hbldrIs3dsxTitle(exheaderInfo->aci.local_caps.title_id)) @@ -287,56 +282,29 @@ static Result RegisterProgram(u64 *programHandle, FS_ProgramInfo *title, FS_Prog u64 titleId; titleId = title->programId; - if (titleId >> 32 != 0xFFFF0000) + if (IsHioId(titleId)) { - res = FSREG_CheckHostLoadId(titleId); - //if ((res >= 0 && (unsigned)res >> 27) || (res < 0 && ((unsigned)res >> 27)-32)) - if (R_FAILED(res) || (R_SUCCEEDED(res) && R_LEVEL(res) != RL_SUCCESS)) - { - TRY(PXIPM_RegisterProgram(programHandle, title, update)); - if (*programHandle >> 32 != 0xFFFF0000) - { - res = FSREG_CheckHostLoadId(*programHandle); - //if ((res >= 0 && (unsigned)res >> 27) || (res < 0 && ((unsigned)res >> 27)-32)) - if (R_FAILED(res) || (R_SUCCEEDED(res) && R_LEVEL(res) != RL_SUCCESS)) - { - return 0; - } - } - panic(0); - } - } + if ((title->mediaType != update->mediaType) || (titleId != update->programId)) + panic(1); - if ((title->mediaType != update->mediaType) || (titleId != update->programId)) - panic(1); + TRY(FSREG_LoadProgram(programHandle, title)); - TRY(FSREG_LoadProgram(programHandle, title)); - if (*programHandle >> 32 == 0xFFFF0000) - return 0; - - res = FSREG_CheckHostLoadId(*programHandle); - //if ((res >= 0 && (unsigned)res >> 27) || (res < 0 && ((unsigned)res >> 27)-32)) - if (R_FAILED(res) || (R_SUCCEEDED(res) && R_LEVEL(res) != RL_SUCCESS)) - panic(2); + if (!IsHioId(*programHandle)) // double check this is indeed HIO + panic(2); + } + else + { + TRY(PXIPM_RegisterProgram(programHandle, title, update)); + if (IsHioId(*programHandle)) // double check this is indeed *not* HIO + panic(0); + } return res; } static Result UnregisterProgram(u64 programHandle) { - Result res; - - if (programHandle >> 32 == 0xFFFF0000) - return FSREG_UnloadProgram(programHandle); - else - { - res = FSREG_CheckHostLoadId(programHandle); - //if ((res >= 0 && (unsigned)res >> 27) || (res < 0 && ((unsigned)res >> 27)-32)) - if (R_FAILED(res) || (R_SUCCEEDED(res) && R_LEVEL(res) != RL_SUCCESS)) - return PXIPM_UnregisterProgram(programHandle); - else - return FSREG_UnloadProgram(programHandle); - } + return IsHioId(programHandle) ? FSREG_UnloadProgram(programHandle) : PXIPM_UnregisterProgram(programHandle); } void loaderHandleCommands(void *ctx) diff --git a/sysmodules/pm/source/info.c b/sysmodules/pm/source/info.c index d8b5a16..7452cd6 100644 --- a/sysmodules/pm/source/info.c +++ b/sysmodules/pm/source/info.c @@ -12,6 +12,8 @@ Result registerProgram(u64 *programHandle, const FS_ProgramInfo *programInfo, co if (IS_N3DS) { if (pi.programId >> 48 == 0xFFFF) { + // Check for HIO TIDs. PM is a bit more lax, as the condition + // in Loader and FS is (x >> 32) == 0xFFFF0000 instead. return LOADER_RegisterProgram(programHandle, &pi, &piu); } pi.programId = (pi.programId & ~N3DS_TID_MASK) | N3DS_TID_BIT; From 4de0375bde0255c50096ba2518952e532cb0deaf Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sat, 21 May 2022 20:01:15 +0100 Subject: [PATCH 5/5] kext: fix bug in rosalinaThreadLockPredicate (thanks @hax0kartik) --- k11_extension/source/synchronization.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k11_extension/source/synchronization.c b/k11_extension/source/synchronization.c index 4b00072..ff41cc5 100644 --- a/k11_extension/source/synchronization.c +++ b/k11_extension/source/synchronization.c @@ -109,7 +109,7 @@ bool rosalinaThreadLockPredicate(KThread *thread, u32 mask) if (mask & 2) { if (highTitleId != 0x00040130) // non-sysmodules - false; + return false; return lowTitleId == 0x1C02; // gsp } if (mask & 4)