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;
}