Last active
June 29, 2020 23:59
-
-
Save TuxSH/1cdcac015ab327371890fc4def0e5e2e to your computer and use it in GitHub Desktop.
k11 diagnostic table
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void CreateKernelDiagnosticTable(void) | |
{ | |
KernelDiagnosticTable *diagTable; // r0 | |
KPageManager **v1; // r3 | |
KernelDiagnosticTableSlabHeapEntry *v2; // r1 | |
int sp; // [sp+0h] [bp-10h] | |
diagTable = (KernelDiagnosticTable *)((unsigned int)&sp >> 12 << 12); | |
diagTable->mainKernelRegionStart = 0x1FF80000; | |
diagTable->mainKernelRegionSize = 0x80000; | |
diagTable->unk_18 = 0; | |
diagTable->sizeofKAutoObject = 8; // sizeof KAutoObject... probably? | |
diagTable->sizeofKThreadStackParams = 0xC8; | |
diagTable->clientPortOffset = 0x2C; // offsetof(KPort, client); | |
diagTable->unk_1c = 0; | |
v1 = &diagTable->pageManager; | |
*v1 = &g_memoryManager.pgMgr; | |
v1[1] = (KPageManager *)&g_hardwareTimer; | |
diagTable->event.heap = g_eventAllocator.slabHeap.first; | |
diagTable->event.numElements = 0x13B; | |
diagTable->event.elementSize = 0x28; | |
diagTable->event.head = &g_eventAllocator.slabHeap; | |
diagTable->mutex.heap = g_mutexAllocator.slabHeap.first; | |
diagTable->mutex.numElements = 0x55; | |
diagTable->mutex.elementSize = 0x2C; | |
diagTable->mutex.head = &g_mutexAllocator.slabHeap; | |
diagTable->semaphore.heap = g_semaphoreAllocator.slabHeap.first; | |
diagTable->semaphore.numElements = 0x53; | |
diagTable->semaphore.elementSize = 0x2C; | |
diagTable->semaphore.head = &g_semaphoreAllocator.slabHeap; | |
diagTable->timer.heap = g_timerAllocator.slabHeap.first; | |
diagTable->timer.numElements = 0x3C; | |
diagTable->timer.elementSize = 0x3C; | |
diagTable->timer.head = &g_timerAllocator.slabHeap; | |
diagTable->process.heap = g_processAllocator.slabHeap.first; | |
diagTable->process.numElements = 0x2F; | |
diagTable->process.elementSize = 0x270; | |
diagTable->process.head = &g_processAllocator.slabHeap; | |
diagTable->thread.heap = g_threadAllocator.slabHeap.first; | |
diagTable->thread.numElements = 0x12C; | |
diagTable->thread.elementSize = 0xB0; | |
diagTable->thread.head = &g_threadAllocator.slabHeap; | |
diagTable->port.heap = g_portAllocator.slabHeap.first; | |
diagTable->port.numElements = 0x99; | |
diagTable->port.elementSize = 0x48; | |
diagTable->port.head = &g_portAllocator.slabHeap; | |
diagTable->dmaObject.heap = g_dmaObjectAllocator.slabHeap.first; | |
diagTable->dmaObject.numElements = 0x10; | |
diagTable->dmaObject.elementSize = 0x18; | |
diagTable->dmaObject.head = &g_dmaObjectAllocator.slabHeap; | |
diagTable->sharedMemory.heap = g_sharedMemoryAllocator.slabHeap.first; | |
diagTable->sharedMemory.numElements = 0x3F; | |
diagTable->sharedMemory.elementSize = 0x28; | |
diagTable->sharedMemory.head = &g_sharedMemoryAllocator.slabHeap; | |
diagTable->session.heap = g_sessionAllocator.slabHeap.first; | |
diagTable->session.numElements = 0x159; | |
diagTable->session.elementSize = 0x4C; | |
diagTable->session.head = &g_sessionAllocator.slabHeap; | |
diagTable->resourceLimit.heap = g_resourceLimitAllocator.slabHeap.first; | |
diagTable->resourceLimit.numElements = 5; | |
diagTable->resourceLimit.elementSize = 0x74; | |
diagTable->resourceLimit.head = &g_resourceLimitAllocator.slabHeap; | |
diagTable->addressArbiter.heap = g_addressArbiterAllocator.slabHeap.first; | |
diagTable->addressArbiter.numElements = 0x33; | |
diagTable->addressArbiter.elementSize = 0x14; | |
diagTable->addressArbiter.head = &g_addressArbiterAllocator.slabHeap; | |
diagTable->codeSet.heap = g_codeSetAllocator.slabHeap.first; | |
diagTable->codeSet.numElements = 0x2F; | |
diagTable->codeSet.elementSize = 100; | |
diagTable->codeSet.head = &g_codeSetAllocator.slabHeap; | |
diagTable->linkedListNode.heap = g_linkedListNodeSlabHeap.first; | |
diagTable->linkedListNode.numElements = 0x10B1; | |
diagTable->linkedListNode.elementSize = 0xC; | |
diagTable->linkedListNode.head = &g_linkedListNodeSlabHeap; | |
diagTable->blockInfo.heap = g_blockInfoSlabHeap.first; | |
diagTable->blockInfo.numElements = 0x259; | |
diagTable->blockInfo.elementSize = 8; | |
diagTable->blockInfo.head = &g_blockInfoSlabHeap; | |
v2 = &diagTable->memoryBlock; | |
diagTable->memoryBlock.heap = g_memoryBlockSlabHeap.first; | |
v2->numElements = 0x6BB; | |
v2->elementSize = 0x14; | |
diagTable->memoryBlock.head = &g_memoryBlockSlabHeap; | |
diagTable->threadLocalPage.heap = g_threadLocalPageSlabHeap.first; | |
v2[1].numElements = 64; | |
v2[1].elementSize = 0x18; | |
diagTable->threadLocalPage.head = &g_threadLocalPageSlabHeap; | |
diagTable->objectName.heap = g_objectNameSlabHeap.first; | |
v2[2].numElements = 7; | |
v2[2].elementSize = 0x10; | |
diagTable->objectName.head = &g_objectNameSlabHeap; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <3ds.h> | |
#define NUM_SLAB_HEAPS 19u | |
typedef struct KernelDiagnosticTableSlabHeapEntry { | |
u32 heapAddr; | |
s16 numElements; | |
s16 elementSize; | |
u32 headAddr; | |
} KernelDiagnosticTableSlabHeapEntry; | |
typedef struct KernelDiagnosticTable | |
{ | |
u32 sizeofKThreadStackParams; | |
u32 sizeofKAutoObject; | |
u32 mainKernelRegionStart; | |
u32 mainKernelRegionSize; | |
u32 pageManagerAddr; | |
u32 hardwareTimerAddr; | |
u32 unk_18, unk_1c; | |
u32 clientPortOffset; | |
u8 _0x24[0x40 - 0x24]; | |
KernelDiagnosticTableSlabHeapEntry slabHeapInfo[NUM_SLAB_HEAPS]; | |
} KernelDiagnosticTable; | |
static const char *objNames[] = { | |
"KEvent", "KMutex", "KSemaphore", "KTimer", "KProcess", "KThread", "KPort", "KDmaObject", | |
"KSharedMemory", NULL /* KDebug (just a guess) UNUSED! */, "KSession", "KResourceLimit", | |
"KAddressArbiter", "KCodeSet", "KLinkedListNode", "KBlockInfo", "KMemoryBlock", "KThreadLocalPage", | |
"KObjectName", | |
// KDebugThread missing | |
// KEventInfo missing | |
}; | |
static KernelDiagnosticTable s_diagTable; | |
static s32 kCopyDiagTable(void) | |
{ | |
__asm__ __volatile__ ("cpsid aif"); | |
u32 loc = 0xFFFC9000 + 0x6000; | |
memcpy(&s_diagTable, (void *)loc, sizeof(KernelDiagnosticTable)); | |
return 0; | |
} | |
static void printDiagTable(void) | |
{ | |
svcBackdoor(kCopyDiagTable); | |
u32 mainRegionEnd = s_diagTable.mainKernelRegionStart + s_diagTable.mainKernelRegionSize; | |
printf("KThreadStackParams size: %#lx\n", s_diagTable.sizeofKThreadStackParams); | |
printf("KAutoObject size: %#lx\n", s_diagTable.sizeofKAutoObject); // maybe | |
printf("Main kernel region: %#08lx - %#08lx\n", s_diagTable.mainKernelRegionStart, mainRegionEnd); | |
printf("KPageManager addr: %#08lx\n", s_diagTable.pageManagerAddr); | |
printf("KHardwareTimer addr: %#08lx\n", s_diagTable.hardwareTimerAddr); | |
printf("KClientPort offset: %#lx\n", s_diagTable.clientPortOffset); | |
printf("\n--------------------------------------------------\n"); | |
printf("%-20s %-8s %-8s\n\n", "Name", "Size", "Number"); | |
for (u32 i = 0; i < NUM_SLAB_HEAPS; i++) { | |
const KernelDiagnosticTableSlabHeapEntry *info = &s_diagTable.slabHeapInfo[i]; | |
if (objNames[i] == NULL) { | |
continue; | |
} | |
printf("%-20s %#-8lx %-8lu\n", objNames[i], (u32)info->elementSize, (u32)info->numElements); | |
} | |
} | |
int main(int argc, char* argv[]) | |
{ | |
gfxInitDefault(); | |
consoleInit(GFX_TOP, NULL); | |
printDiagTable(); | |
// Main loop | |
while (aptMainLoop()) | |
{ | |
gspWaitForVBlank(); | |
gfxSwapBuffers(); | |
hidScanInput(); | |
// Your code goes here | |
u32 kDown = hidKeysDown(); | |
if (kDown & KEY_START) | |
break; // break in order to return to hbmenu | |
} | |
gfxExit(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment