mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-02-17 06:31:14 +00:00
Add patches for native GetNamedResource() and Get1NamedResource(). This will
be useful to fix a bug in the AppleShare extension (see DRVR .AFPTranslator in Basilisk II) Unrelated improvement: call sheepshaver_cpu::get_resource() directly, don't get it through another global function.
This commit is contained in:
parent
828b53b990
commit
21f35a34f0
@ -22,6 +22,7 @@
|
|||||||
#define RSRC_PATCHES_H
|
#define RSRC_PATCHES_H
|
||||||
|
|
||||||
extern void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size);
|
extern void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size);
|
||||||
|
extern void CheckLoad(uint32 type, const char *name, uint16 *p, uint32 size);
|
||||||
extern void PatchNativeResourceManager(void);
|
extern void PatchNativeResourceManager(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,6 +63,9 @@ enum {
|
|||||||
NATIVE_BITBLT,
|
NATIVE_BITBLT,
|
||||||
NATIVE_INVRECT,
|
NATIVE_INVRECT,
|
||||||
NATIVE_FILLRECT,
|
NATIVE_FILLRECT,
|
||||||
|
NATIVE_NAMED_CHECK_LOAD_INVOC,
|
||||||
|
NATIVE_GET_NAMED_RESOURCE,
|
||||||
|
NATIVE_GET_1_NAMED_RESOURCE,
|
||||||
NATIVE_OP_MAX
|
NATIVE_OP_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
#define XLM_EXEC_RETURN_OPCODE 0x284c // EXEC_RETURN opcode for Execute68k()
|
#define XLM_EXEC_RETURN_OPCODE 0x284c // EXEC_RETURN opcode for Execute68k()
|
||||||
#define XLM_ZERO_PAGE 0x2850 // Pointer to read-only page with all bits set to 0
|
#define XLM_ZERO_PAGE 0x2850 // Pointer to read-only page with all bits set to 0
|
||||||
#define XLM_R13 0x2854 // Pointer to .sdata section (Linux)
|
#define XLM_R13 0x2854 // Pointer to .sdata section (Linux)
|
||||||
|
#define XLM_GET_NAMED_RESOURCE 0x2858 // Pointer to native GetNamedResource() routine
|
||||||
|
#define XLM_GET_1_NAMED_RESOURCE 0x285c // Pointer to native Get1NamedResource() routine
|
||||||
|
|
||||||
#define XLM_ETHER_AO_GET_HWADDR 0x28b0 // Pointer to ethernet A0_get_ethernet_address() function
|
#define XLM_ETHER_AO_GET_HWADDR 0x28b0 // Pointer to ethernet A0_get_ethernet_address() function
|
||||||
#define XLM_ETHER_AO_ADD_MULTI 0x28b4 // Pointer to ethernet A0_enable_multicast() function
|
#define XLM_ETHER_AO_ADD_MULTI 0x28b4 // Pointer to ethernet A0_enable_multicast() function
|
||||||
|
@ -89,6 +89,7 @@ extern uintptr SignalStackBase();
|
|||||||
|
|
||||||
// From rsrc_patches.cpp
|
// From rsrc_patches.cpp
|
||||||
extern "C" void check_load_invoc(uint32 type, int16 id, uint32 h);
|
extern "C" void check_load_invoc(uint32 type, int16 id, uint32 h);
|
||||||
|
extern "C" void named_check_load_invoc(uint32 type, uint32 name, uint32 h);
|
||||||
|
|
||||||
// PowerPC EmulOp to exit from emulation looop
|
// PowerPC EmulOp to exit from emulation looop
|
||||||
const uint32 POWERPC_EXEC_RETURN = POWERPC_EMUL_OP | 1;
|
const uint32 POWERPC_EXEC_RETURN = POWERPC_EMUL_OP | 1;
|
||||||
@ -343,6 +344,13 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context)
|
|||||||
dg.gen_invoke_T0_T1_T2((void (*)(uint32, uint32, uint32))check_load_invoc);
|
dg.gen_invoke_T0_T1_T2((void (*)(uint32, uint32, uint32))check_load_invoc);
|
||||||
status = COMPILE_CODE_OK;
|
status = COMPILE_CODE_OK;
|
||||||
break;
|
break;
|
||||||
|
case NATIVE_NAMED_CHECK_LOAD_INVOC:
|
||||||
|
dg.gen_load_T0_GPR(3);
|
||||||
|
dg.gen_load_T1_GPR(4);
|
||||||
|
dg.gen_load_T2_GPR(5);
|
||||||
|
dg.gen_invoke_T0_T1_T2((void (*)(uint32, uint32, uint32))named_check_load_invoc);
|
||||||
|
status = COMPILE_CODE_OK;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case NATIVE_BITBLT:
|
case NATIVE_BITBLT:
|
||||||
dg.gen_load_T0_GPR(3);
|
dg.gen_load_T0_GPR(3);
|
||||||
@ -971,12 +979,6 @@ void HandleInterrupt(powerpc_registers *r)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_resource(void);
|
|
||||||
static void get_1_resource(void);
|
|
||||||
static void get_ind_resource(void);
|
|
||||||
static void get_1_ind_resource(void);
|
|
||||||
static void r_get_resource(void);
|
|
||||||
|
|
||||||
// Execute NATIVE_OP routine
|
// Execute NATIVE_OP routine
|
||||||
void sheepshaver_cpu::execute_native_op(uint32 selector)
|
void sheepshaver_cpu::execute_native_op(uint32 selector)
|
||||||
{
|
{
|
||||||
@ -1070,27 +1072,29 @@ void sheepshaver_cpu::execute_native_op(uint32 selector)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NATIVE_GET_RESOURCE:
|
case NATIVE_GET_RESOURCE:
|
||||||
case NATIVE_GET_1_RESOURCE:
|
get_resource(ReadMacInt32(XLM_GET_RESOURCE));
|
||||||
case NATIVE_GET_IND_RESOURCE:
|
break;
|
||||||
case NATIVE_GET_1_IND_RESOURCE:
|
case NATIVE_GET_1_RESOURCE:
|
||||||
case NATIVE_R_GET_RESOURCE: {
|
get_resource(ReadMacInt32(XLM_GET_1_RESOURCE));
|
||||||
typedef void (*GetResourceCallback)(void);
|
break;
|
||||||
static const GetResourceCallback get_resource_callbacks[] = {
|
case NATIVE_GET_IND_RESOURCE:
|
||||||
::get_resource,
|
get_resource(ReadMacInt32(XLM_GET_IND_RESOURCE));
|
||||||
::get_1_resource,
|
break;
|
||||||
::get_ind_resource,
|
case NATIVE_GET_1_IND_RESOURCE:
|
||||||
::get_1_ind_resource,
|
get_resource(ReadMacInt32(XLM_GET_1_IND_RESOURCE));
|
||||||
::r_get_resource
|
break;
|
||||||
};
|
case NATIVE_R_GET_RESOURCE:
|
||||||
get_resource_callbacks[selector - NATIVE_GET_RESOURCE]();
|
get_resource(ReadMacInt32(XLM_R_GET_RESOURCE));
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case NATIVE_MAKE_EXECUTABLE:
|
case NATIVE_MAKE_EXECUTABLE:
|
||||||
MakeExecutable(0, gpr(4), gpr(5));
|
MakeExecutable(0, gpr(4), gpr(5));
|
||||||
break;
|
break;
|
||||||
case NATIVE_CHECK_LOAD_INVOC:
|
case NATIVE_CHECK_LOAD_INVOC:
|
||||||
check_load_invoc(gpr(3), gpr(4), gpr(5));
|
check_load_invoc(gpr(3), gpr(4), gpr(5));
|
||||||
break;
|
break;
|
||||||
|
case NATIVE_NAMED_CHECK_LOAD_INVOC:
|
||||||
|
named_check_load_invoc(gpr(3), gpr(4), gpr(5));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("FATAL: NATIVE_OP called with bogus selector %d\n", selector);
|
printf("FATAL: NATIVE_OP called with bogus selector %d\n", selector);
|
||||||
QuitEmulator();
|
QuitEmulator();
|
||||||
@ -1177,32 +1181,3 @@ uint32 call_macos7(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 a
|
|||||||
const uint32 args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 };
|
const uint32 args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 };
|
||||||
return ppc_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args);
|
return ppc_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Resource Manager thunks
|
|
||||||
*/
|
|
||||||
|
|
||||||
void get_resource(void)
|
|
||||||
{
|
|
||||||
ppc_cpu->get_resource(ReadMacInt32(XLM_GET_RESOURCE));
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_1_resource(void)
|
|
||||||
{
|
|
||||||
ppc_cpu->get_resource(ReadMacInt32(XLM_GET_1_RESOURCE));
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_ind_resource(void)
|
|
||||||
{
|
|
||||||
ppc_cpu->get_resource(ReadMacInt32(XLM_GET_IND_RESOURCE));
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_1_ind_resource(void)
|
|
||||||
{
|
|
||||||
ppc_cpu->get_resource(ReadMacInt32(XLM_GET_1_IND_RESOURCE));
|
|
||||||
}
|
|
||||||
|
|
||||||
void r_get_resource(void)
|
|
||||||
{
|
|
||||||
ppc_cpu->get_resource(ReadMacInt32(XLM_R_GET_RESOURCE));
|
|
||||||
}
|
|
||||||
|
@ -580,6 +580,22 @@ void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resource patches via GetNamedResource() and Get1NamedResource()
|
||||||
|
*/
|
||||||
|
|
||||||
|
void CheckLoad(uint32 type, const char *name, uint8 *p, uint32 size)
|
||||||
|
{
|
||||||
|
uint16 *p16;
|
||||||
|
uint32 base;
|
||||||
|
D(bug("vCheckLoad %c%c%c%c (%08x) name \"%*s\", data %p, size %d\n", type >> 24, (type >> 16) & 0xff, (type >> 8) & 0xff, type & 0xff, type, name[0], &name[1], p, size));
|
||||||
|
|
||||||
|
// Don't modify resources in ROM
|
||||||
|
if ((uintptr)p >= (uintptr)ROMBaseHost && (uintptr)p <= (uintptr)(ROMBaseHost + ROM_SIZE))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Native Resource Manager patches
|
* Native Resource Manager patches
|
||||||
*/
|
*/
|
||||||
@ -601,6 +617,23 @@ void check_load_invoc(uint32 type, int16 id, uint32 h)
|
|||||||
CheckLoad(type, id, (uint16 *)Mac2HostAddr(p), size);
|
CheckLoad(type, id, (uint16 *)Mac2HostAddr(p), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __BEOS__
|
||||||
|
static
|
||||||
|
#else
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
void named_check_load_invoc(uint32 type, uint32 name, uint32 h)
|
||||||
|
{
|
||||||
|
if (h == 0)
|
||||||
|
return;
|
||||||
|
uint32 p = ReadMacInt32(h);
|
||||||
|
if (p == 0)
|
||||||
|
return;
|
||||||
|
uint32 size = ReadMacInt32(p - 2 * 4) & 0xffffff;
|
||||||
|
|
||||||
|
CheckLoad(type, (char *)Mac2HostAddr(name), Mac2HostAddr(p), size);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __BEOS__
|
#ifdef __BEOS__
|
||||||
static asm void **get_resource(register uint32 type, register int16 id)
|
static asm void **get_resource(register uint32 type, register int16 id)
|
||||||
{
|
{
|
||||||
@ -766,6 +799,72 @@ static asm void **r_get_resource(register uint32 type, register int16 id)
|
|||||||
addi r1,r1,56+12
|
addi r1,r1,56+12
|
||||||
blr
|
blr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static asm void **get_named_resource(register uint32 type, register uint32 name)
|
||||||
|
{
|
||||||
|
// Create stack frame
|
||||||
|
mflr r0
|
||||||
|
stw r0,8(r1)
|
||||||
|
stwu r1,-(56+12)(r1)
|
||||||
|
|
||||||
|
// Save type/ID
|
||||||
|
stw r3,56(r1)
|
||||||
|
stw r4,56+4(r1)
|
||||||
|
|
||||||
|
// Call old routine
|
||||||
|
lwz r0,XLM_GET_NAMED_RESOURCE
|
||||||
|
lwz r2,XLM_RES_LIB_TOC
|
||||||
|
mtctr r0
|
||||||
|
bctrl
|
||||||
|
lwz r2,XLM_TOC // Get TOC
|
||||||
|
stw r3,56+8(r1) // Save handle
|
||||||
|
|
||||||
|
// Call CheckLoad
|
||||||
|
lwz r3,56(r1)
|
||||||
|
lwz r4,56+4(r1)
|
||||||
|
lwz r5,56+8(r1)
|
||||||
|
bl named_check_load_invoc
|
||||||
|
lwz r3,56+8(r1) // Restore handle
|
||||||
|
|
||||||
|
// Return to caller
|
||||||
|
lwz r0,56+12+8(r1)
|
||||||
|
mtlr r0
|
||||||
|
addi r1,r1,56+12
|
||||||
|
blr
|
||||||
|
}
|
||||||
|
|
||||||
|
static asm void **get_1_named_resource(register uint32 type, register uint32 name)
|
||||||
|
{
|
||||||
|
// Create stack frame
|
||||||
|
mflr r0
|
||||||
|
stw r0,8(r1)
|
||||||
|
stwu r1,-(56+12)(r1)
|
||||||
|
|
||||||
|
// Save type/ID
|
||||||
|
stw r3,56(r1)
|
||||||
|
stw r4,56+4(r1)
|
||||||
|
|
||||||
|
// Call old routine
|
||||||
|
lwz r0,XLM_GET_1_NAMED_RESOURCE
|
||||||
|
lwz r2,XLM_RES_LIB_TOC
|
||||||
|
mtctr r0
|
||||||
|
bctrl
|
||||||
|
lwz r2,XLM_TOC // Get TOC
|
||||||
|
stw r3,56+8(r1) // Save handle
|
||||||
|
|
||||||
|
// Call CheckLoad
|
||||||
|
lwz r3,56(r1)
|
||||||
|
lwz r4,56+4(r1)
|
||||||
|
lwz r5,56+8(r1)
|
||||||
|
bl named_check_load_invoc
|
||||||
|
lwz r3,56+8(r1) // Restore handle
|
||||||
|
|
||||||
|
// Return to caller
|
||||||
|
lwz r0,56+12+8(r1)
|
||||||
|
mtlr r0
|
||||||
|
addi r1,r1,56+12
|
||||||
|
blr
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
// Routines in asm_linux.S
|
// Routines in asm_linux.S
|
||||||
extern "C" void get_resource(void);
|
extern "C" void get_resource(void);
|
||||||
@ -773,6 +872,8 @@ extern "C" void get_1_resource(void);
|
|||||||
extern "C" void get_ind_resource(void);
|
extern "C" void get_ind_resource(void);
|
||||||
extern "C" void get_1_ind_resource(void);
|
extern "C" void get_1_ind_resource(void);
|
||||||
extern "C" void r_get_resource(void);
|
extern "C" void r_get_resource(void);
|
||||||
|
extern "C" void get_named_resource(void);
|
||||||
|
extern "C" void get_1_named_resource(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void PatchNativeResourceManager(void)
|
void PatchNativeResourceManager(void)
|
||||||
@ -865,5 +966,39 @@ void PatchNativeResourceManager(void)
|
|||||||
#else
|
#else
|
||||||
WriteMacInt32(tvec, (uint32)r_get_resource);
|
WriteMacInt32(tvec, (uint32)r_get_resource);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Patch native GetNamedResource()
|
||||||
|
upp = ReadMacInt32(0x1484);
|
||||||
|
tvec = ReadMacInt32(upp + 5 * 4);
|
||||||
|
D(bug(" GetNamedResource() entry %08x, TOC %08x\n", ReadMacInt32(tvec), ReadMacInt32(tvec + 4)));
|
||||||
|
WriteMacInt32(XLM_GET_NAMED_RESOURCE, ReadMacInt32(tvec));
|
||||||
|
#if EMULATED_PPC
|
||||||
|
WriteMacInt32(tvec, NativeFunction(NATIVE_GET_NAMED_RESOURCE));
|
||||||
|
#else
|
||||||
|
#ifdef __BEOS__
|
||||||
|
tvec2 = (uint32 *)get_named_resource;
|
||||||
|
WriteMacInt32(tvec, tvec2[0]);
|
||||||
|
WriteMacInt32(tvec + 4, tvec2[1]);
|
||||||
|
#else
|
||||||
|
WriteMacInt32(tvec, (uint32)get_named_resource);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Patch native Get1NamedResource()
|
||||||
|
upp = ReadMacInt32(0x0e80);
|
||||||
|
tvec = ReadMacInt32(upp + 5 * 4);
|
||||||
|
D(bug(" Get1NamedResource() entry %08x, TOC %08x\n", ReadMacInt32(tvec), ReadMacInt32(tvec + 4)));
|
||||||
|
WriteMacInt32(XLM_GET_1_NAMED_RESOURCE, ReadMacInt32(tvec));
|
||||||
|
#if EMULATED_PPC
|
||||||
|
WriteMacInt32(tvec, NativeFunction(NATIVE_GET_1_NAMED_RESOURCE));
|
||||||
|
#else
|
||||||
|
#ifdef __BEOS__
|
||||||
|
tvec2 = (uint32 *)get_1_named_resource;
|
||||||
|
WriteMacInt32(tvec, tvec2[0]);
|
||||||
|
WriteMacInt32(tvec + 4, tvec2[1]);
|
||||||
|
#else
|
||||||
|
WriteMacInt32(tvec, (uint32)get_1_named_resource);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ uint32 NativeOpcode(int selector)
|
|||||||
uint32 opcode;
|
uint32 opcode;
|
||||||
switch (selector) {
|
switch (selector) {
|
||||||
case NATIVE_CHECK_LOAD_INVOC:
|
case NATIVE_CHECK_LOAD_INVOC:
|
||||||
|
case NATIVE_NAMED_CHECK_LOAD_INVOC:
|
||||||
opcode = POWERPC_NATIVE_OP(0, selector);
|
opcode = POWERPC_NATIVE_OP(0, selector);
|
||||||
break;
|
break;
|
||||||
case NATIVE_PATCH_NAME_REGISTRY:
|
case NATIVE_PATCH_NAME_REGISTRY:
|
||||||
@ -85,6 +86,8 @@ uint32 NativeOpcode(int selector)
|
|||||||
case NATIVE_GET_IND_RESOURCE:
|
case NATIVE_GET_IND_RESOURCE:
|
||||||
case NATIVE_GET_1_IND_RESOURCE:
|
case NATIVE_GET_1_IND_RESOURCE:
|
||||||
case NATIVE_R_GET_RESOURCE:
|
case NATIVE_R_GET_RESOURCE:
|
||||||
|
case NATIVE_GET_NAMED_RESOURCE:
|
||||||
|
case NATIVE_GET_1_NAMED_RESOURCE:
|
||||||
case NATIVE_MAKE_EXECUTABLE:
|
case NATIVE_MAKE_EXECUTABLE:
|
||||||
case NATIVE_SYNC_HOOK:
|
case NATIVE_SYNC_HOOK:
|
||||||
case NATIVE_BITBLT_HOOK:
|
case NATIVE_BITBLT_HOOK:
|
||||||
@ -112,9 +115,15 @@ static uint32 get_1_resource_func;
|
|||||||
static uint32 get_ind_resource_func;
|
static uint32 get_ind_resource_func;
|
||||||
static uint32 get_1_ind_resource_func;
|
static uint32 get_1_ind_resource_func;
|
||||||
static uint32 r_get_resource_func;
|
static uint32 r_get_resource_func;
|
||||||
|
static uint32 get_named_resource_func;
|
||||||
|
static uint32 get_1_named_resource_func;
|
||||||
|
|
||||||
static void generate_powerpc_thunks(void)
|
static void generate_powerpc_thunks(void)
|
||||||
{
|
{
|
||||||
|
// check_load_invoc() thunk
|
||||||
|
uint32 check_load_invoc_opcode = NativeOpcode(NATIVE_CHECK_LOAD_INVOC);
|
||||||
|
uint32 base;
|
||||||
|
|
||||||
static uint32 get_resource_template[] = {
|
static uint32 get_resource_template[] = {
|
||||||
PL(0x7c0802a6), // mflr r0
|
PL(0x7c0802a6), // mflr r0
|
||||||
PL(0x90010008), // stw r0,8(r1)
|
PL(0x90010008), // stw r0,8(r1)
|
||||||
@ -152,9 +161,6 @@ static void generate_powerpc_thunks(void)
|
|||||||
}
|
}
|
||||||
assert(xlm_index != -1 && check_load_invoc_index != -1);
|
assert(xlm_index != -1 && check_load_invoc_index != -1);
|
||||||
|
|
||||||
uint32 check_load_invoc_opcode = NativeOpcode(NATIVE_CHECK_LOAD_INVOC);
|
|
||||||
uint32 base;
|
|
||||||
|
|
||||||
// GetResource()
|
// GetResource()
|
||||||
get_resource_func = base = SheepMem::Reserve(get_resource_template_size);
|
get_resource_func = base = SheepMem::Reserve(get_resource_template_size);
|
||||||
Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
|
Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
|
||||||
@ -184,6 +190,58 @@ static void generate_powerpc_thunks(void)
|
|||||||
Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
|
Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
|
||||||
WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_R_GET_RESOURCE);
|
WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_R_GET_RESOURCE);
|
||||||
WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
|
WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
|
||||||
|
|
||||||
|
// named_check_load_invoc() thunk
|
||||||
|
check_load_invoc_opcode = NativeOpcode(NATIVE_NAMED_CHECK_LOAD_INVOC);
|
||||||
|
|
||||||
|
static uint32 get_named_resource_template[] = {
|
||||||
|
PL(0x7c0802a6), // mflr r0
|
||||||
|
PL(0x90010008), // stw r0,8(r1)
|
||||||
|
PL(0x9421ffbc), // stwu r1,-68(r1)
|
||||||
|
PL(0x90610038), // stw r3,56(r1)
|
||||||
|
PL(0x9081003c), // stw r4,60(r1)
|
||||||
|
PL(0x00000000), // lwz r0,XLM_GET_NAMED_RESOURCE(r0)
|
||||||
|
PL(0x80402834), // lwz r2,XLM_RES_LIB_TOC(r0)
|
||||||
|
PL(0x7c0903a6), // mtctr r0
|
||||||
|
PL(0x4e800421), // bctrl
|
||||||
|
PL(0x90610040), // stw r3,64(r1)
|
||||||
|
PL(0x80610038), // lwz r3,56(r1)
|
||||||
|
PL(0x8081003c), // lwz r4,60(r1)
|
||||||
|
PL(0x80a10040), // lwz r5,64(r1)
|
||||||
|
PL(0x00000001), // <named_check_load_invoc>
|
||||||
|
PL(0x80610040), // lwz r3,64(r1)
|
||||||
|
PL(0x8001004c), // lwz r0,76(r1)
|
||||||
|
PL(0x7c0803a6), // mtlr r0
|
||||||
|
PL(0x38210044), // addi r1,r1,68
|
||||||
|
PL(0x4e800020) // blr
|
||||||
|
};
|
||||||
|
const uint32 get_named_resource_template_size = sizeof(get_named_resource_template);
|
||||||
|
|
||||||
|
xlm_index = -1, check_load_invoc_index = -1;
|
||||||
|
for (int i = 0; i < get_resource_template_size/4; i++) {
|
||||||
|
uint32 opcode = ntohl(get_resource_template[i]);
|
||||||
|
switch (opcode) {
|
||||||
|
case 0x00000000:
|
||||||
|
xlm_index = i;
|
||||||
|
break;
|
||||||
|
case 0x00000001:
|
||||||
|
check_load_invoc_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(xlm_index != -1 && check_load_invoc_index != -1);
|
||||||
|
|
||||||
|
// GetNamedResource()
|
||||||
|
get_named_resource_func = base = SheepMem::Reserve(get_named_resource_template_size);
|
||||||
|
Host2Mac_memcpy(base, get_named_resource_template, get_named_resource_template_size);
|
||||||
|
WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_NAMED_RESOURCE);
|
||||||
|
WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
|
||||||
|
|
||||||
|
// Get1NamedResource()
|
||||||
|
get_1_named_resource_func = base = SheepMem::Reserve(get_named_resource_template_size);
|
||||||
|
Host2Mac_memcpy(base, get_named_resource_template, get_named_resource_template_size);
|
||||||
|
WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_1_NAMED_RESOURCE);
|
||||||
|
WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -217,6 +275,8 @@ bool ThunksInit(void)
|
|||||||
native_op[NATIVE_GET_IND_RESOURCE].func = get_ind_resource_func;
|
native_op[NATIVE_GET_IND_RESOURCE].func = get_ind_resource_func;
|
||||||
native_op[NATIVE_GET_1_IND_RESOURCE].func = get_1_ind_resource_func;
|
native_op[NATIVE_GET_1_IND_RESOURCE].func = get_1_ind_resource_func;
|
||||||
native_op[NATIVE_R_GET_RESOURCE].func = r_get_resource_func;
|
native_op[NATIVE_R_GET_RESOURCE].func = r_get_resource_func;
|
||||||
|
native_op[NATIVE_GET_NAMED_RESOURCE].func = get_named_resource_func;
|
||||||
|
native_op[NATIVE_GET_1_NAMED_RESOURCE].func = get_1_named_resource_func;
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#if defined(__linux__) || defined(__NetBSD__) || (defined(__APPLE__) && defined(__MACH__))
|
#if defined(__linux__) || defined(__NetBSD__) || (defined(__APPLE__) && defined(__MACH__))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user