Skip to content

Commit

Permalink
Add patch_freemem
Browse files Browse the repository at this point in the history
  • Loading branch information
rickgaiser committed Jul 7, 2024
1 parent 7f4c126 commit 7cf4211
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ all:
$(MAKE) -C iop/imgdrv all DEBUG=$(IOPCORE_DEBUG)
$(MAKE) -C iop/isofs all DEBUG=$(IOPCORE_DEBUG)
$(MAKE) -C iop/mc_emu all DEBUG=$(IOPCORE_DEBUG)
$(MAKE) -C iop/patch_freemem all DEBUG=1
$(MAKE) -C iop/patch_rc_uya all DEBUG=$(IOPCORE_DEBUG)
$(MAKE) -C iop/smap_udpbd all DEBUG=$(IOPCORE_DEBUG)
$(MAKE) -C iop/usbd_null all DEBUG=$(IOPCORE_DEBUG)
Expand Down Expand Up @@ -47,6 +48,7 @@ clean:
$(MAKE) -C iop/imgdrv clean
$(MAKE) -C iop/isofs clean
$(MAKE) -C iop/mc_emu clean
$(MAKE) -C iop/patch_freemem clean
$(MAKE) -C iop/patch_rc_uya clean
$(MAKE) -C iop/smap_udpbd clean
$(MAKE) -C iop/usbd_null clean
Expand Down
1 change: 1 addition & 0 deletions ee/loader/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ copy:
cp ../../iop/imgdrv/irx/imgdrv.irx modules
cp ../../iop/isofs/irx/isofs.irx modules
cp ../../iop/mc_emu/irx/mc_emu.irx modules
cp ../../iop/patch_freemem/irx/patch_freemem.irx modules
cp ../../iop/patch_rc_uya/irx/patch_rc_uya.irx modules
cp ../../iop/smap_udpbd/irx/smap_udpbd.irx modules
cp ../../iop/usbd_null/irx/usbd_null.irx modules
Expand Down
5 changes: 5 additions & 0 deletions iop/patch_freemem/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
IOP_OBJS = main.o ioplib.o imports.o

include ../../Defs.make
include ../Rules.bin.make
include ../Rules.make
20 changes: 20 additions & 0 deletions iop/patch_freemem/src/imports.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
intrman_IMPORTS_start
I_CpuSuspendIntr
I_CpuResumeIntr
intrman_IMPORTS_end

loadcore_IMPORTS_start
I_GetLoadcoreInternalData
loadcore_IMPORTS_end

#ifdef DEBUG
stdio_IMPORTS_start
I_printf
stdio_IMPORTS_end
#endif

#ifdef DEBUG
sysmem_IMPORTS_start
I_QueryTotalFreeMemSize
sysmem_IMPORTS_end
#endif
82 changes: 82 additions & 0 deletions iop/patch_freemem/src/ioplib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include "ioplib.h"
#include <intrman.h>
#include <stdint.h>

iop_library_t *ioplib_getByName(const char *name)
{
iop_library_t *libptr;
int i;

// Get first loaded library
libptr = GetLoadcoreInternalData()->let_next;
// Loop through all loaded libraries
while (libptr != NULL) {
// Compare library name only
for (i = 0; i < 8; i++) {
if (libptr->name[i] != name[i])
break;
}

// Return if match
if (i == 8)
return libptr;

// Next library
libptr = libptr->prev;
}

return NULL;
}

unsigned int ioplib_getTableSize(iop_library_t *lib)
{
void **exp;
unsigned int size;

exp = NULL;
if (lib != NULL) {
exp = lib->exports;
}
size = 0;

if (exp != NULL)
while (*exp++ != NULL)
size++;

return size;
}

void *ioplib_hookExportEntry(iop_library_t *lib, unsigned int entry, void *func)
{
if (entry < ioplib_getTableSize(lib)) {
int oldstate;
void **exp, *temp;

exp = &lib->exports[entry];

CpuSuspendIntr(&oldstate);
temp = *exp;
*exp = func;
func = temp;
CpuResumeIntr(oldstate);

return func;
}

return NULL;
}

void ioplib_relinkExports(iop_library_t *lib)
{
struct irx_import_table *table;
struct irx_import_stub *stub;

// go through each table that imports the library
for (table = lib->caller; table != NULL; table = table->next) {
// go through each import in the table
for (stub = (struct irx_import_stub *)table->stubs; stub->jump != 0; stub++) {
// patch the stub to jump to the address specified in the library export table for "fno"
stub->jump = 0x08000000 | (((uint32_t)lib->exports[stub->fno] << 4) >> 6);
}
}
}
14 changes: 14 additions & 0 deletions iop/patch_freemem/src/ioplib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef IOPLIB_H
#define IOPLIB_H


#include <loadcore.h>


iop_library_t *ioplib_getByName(const char *name);
unsigned int ioplib_getTableSize(iop_library_t *lib);
void *ioplib_hookExportEntry(iop_library_t *lib, unsigned int entry, void *func);
void ioplib_relinkExports(iop_library_t *lib);


#endif
13 changes: 13 additions & 0 deletions iop/patch_freemem/src/irx_imports.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef IOP_IRX_IMPORTS_H
#define IOP_IRX_IMPORTS_H

#include "irx.h"

#include <intrman.h>
#include <loadcore.h>
#ifdef DEBUG
#include <stdio.h>
#include <sysmem.h>
#endif

#endif
79 changes: 79 additions & 0 deletions iop/patch_freemem/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include <loadcore.h>
#include <sysmem.h>
#include <tamtypes.h>

#include "mprintf.h"
#include "ioplib.h"

#define MODNAME "freemem"
IRX_ID(MODNAME, 1, 1);

typedef void * (*fp_AllocSysMemory)(int mode, int size, void *ptr);
typedef u32 (*fp_QueryMaxFreeMemSize)();
fp_AllocSysMemory org_AllocSysMemory;
fp_QueryMaxFreeMemSize org_QueryMaxFreeMemSize;
static u32 limit;
static u32 block;

static void * hooked_AllocSysMemory(int mode, int size, void *ptr)
{
M_DEBUG("%s(%d, %dB/%dKiB, 0x%x)\n", __FUNCTION__, mode, size, size/1024, ptr);

if (size == block) {
M_DEBUG("-\n- HACK! denying requested memory!\n-\n");
return NULL;
}

return org_AllocSysMemory(mode, size, ptr);
}

static u32 hooked_QueryMaxFreeMemSize()
{
u32 rv = org_QueryMaxFreeMemSize();

M_DEBUG("%s() = %d (%dKiB) -> HACK! limit to %dKiB!\n", __FUNCTION__, rv, rv/1024, limit/1024);
if (rv > limit)
rv = limit;

return rv;
}

int _start(int argc, char **argv)
{
int i;

// Set defaults
limit = 512; // Default 512KiB limit
block = 0; // Default no blocking

// Parse arguments
for (i = 1; i < argc; i++) {
if (argv[i][0] == 'X') {
// Block max memory requests
block = 1;
} else {
// Size in KiB
// Note that there is NO checking for valid characters here!
char *c = argv[i];

limit = 0;
while (*c != 0) {
limit *= 10;
limit += (*c - '0');
c++;
}
}
}
limit *= 1024; // KiB to B
if (block != 0)
block = limit;

// Hook sysmem functions
iop_library_t * lib_sysmem = ioplib_getByName("sysmem");
if (block != 0)
org_AllocSysMemory = ioplib_hookExportEntry(lib_sysmem, 4, hooked_AllocSysMemory);
org_QueryMaxFreeMemSize = ioplib_hookExportEntry(lib_sysmem, 7, hooked_QueryMaxFreeMemSize);
ioplib_relinkExports(lib_sysmem);

return MODULE_RESIDENT_END;
}

0 comments on commit 7cf4211

Please sign in to comment.