PSM
Jump to navigation
Jump to search
SceLibMonoBridge
Inside this module is the only documented case of executable memory being allocated by a user process.
struct { SceUID mem_block; void *base_addr; void *end_addr; u32_t is_allocated; } code_block; void pss_code_mem_initialize () { struct code_block *block = (void*)0x830032C0; u32_t r0 = 0x100; SceUID *mutex = (void*)0x830032BC; while(r0-- > 0) { block->mem_block = 0xFFFFFFFF; block->base_addr = 0xFFFFFFFF; block->end_addr = 0; block->is_allocated = 0; block++; // next element } *mutex = sceKernelCreateMutex ("ScePssCodeMutex", 0, 0, 0); } void pss_code_mem_lock () { u32_t *counter = (void*)0x83000284; SceUID *mutex = (void*)0x830032BC; if (*counter > 0) { SceSysmem_unkfunc6 (); // sub_82BB9BC0 (*counter)--; } sceKernelUnlockMutex (*mutex, 1); } void pss_code_mem_unlock () { u32_t *counter = (void*)0x83000284; SceUID *mutex = (void*)0x830032BC; sceKernelLockMutex (*mutex, 1, 0); if (*counter == 0) { SceSysmem_unkfunc2 (); // sub_82BB9B80 (*counter)++; } } void *pss_code_mem_alloc (unsigned int *length) { struct code_block *blocks = (void*)0x830032C0; u32_t len = *length; int i = 0; struct code_block *cur_block = NULL; for (i = 0; i < 0x100; i++) { if (!blocks[i].is_allocated) { cur_block = &blocks[i]; break; } } len = (len + 0xFFFFF) & ~0xFFFFF; // Round length to next 0x100000 cur_block->mem_block = SceSysmem_unkfunc7 ("ScePssCodeMemBlock", len); // sub_82BB9BD0 sceKernelGetMemBlockBase (cur_block->mem_block, &cur_block->base_addr); cur_block->end_addr = (void*) ((u32_t)cur_block->base_addr + len); cur_block->is_allocated = 1; pss_code_mem_unlock (); memset (cur_block->base_addr, 0, len); pss_code_mem_lock (); *length = len; } int pss_code_mem_free (void *code) { struct code_block *blocks = (void*)0x830032C0; struct code_block *cur_block = NULL; int i; for (i = 0; i < 0x100; i++) { if (code >= blocks[i].base_addr && code <= blocks[i].end_addr) { cur_block = &blocks[i]; break; } } if (cur_block->base_addr == code) { sceKernelFreeMemBlock (cur_block->mem_block); cur_block->is_allocated = 0; } return 0; } void pss_code_mem_flush_icache (uint8_t *code, int size) { struct code_block *blocks = (void*)0x830032C0; int i; for (i = 0; i < 0x100; i++) { if (code >= blocks[i].base_addr && code <= blocks[i].end_addr) { SceSysmem_unkfunc1 (blocks[i].mem_block, code, size); // sub_82BB9B70 break; } } } void pss_code_mem_terminate () { return; }