Skip to content

Instantly share code, notes, and snippets.

@TuxSH
Last active June 29, 2020 23:59
Show Gist options
  • Save TuxSH/1cdcac015ab327371890fc4def0e5e2e to your computer and use it in GitHub Desktop.
Save TuxSH/1cdcac015ab327371890fc4def0e5e2e to your computer and use it in GitHub Desktop.
k11 diagnostic table
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;
}
#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