mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-12-25 02:29:49 +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
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
@ -63,6 +63,9 @@ enum {
|
||||
NATIVE_BITBLT,
|
||||
NATIVE_INVRECT,
|
||||
NATIVE_FILLRECT,
|
||||
NATIVE_NAMED_CHECK_LOAD_INVOC,
|
||||
NATIVE_GET_NAMED_RESOURCE,
|
||||
NATIVE_GET_1_NAMED_RESOURCE,
|
||||
NATIVE_OP_MAX
|
||||
};
|
||||
|
||||
|
@ -48,6 +48,8 @@
|
||||
#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_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_ADD_MULTI 0x28b4 // Pointer to ethernet A0_enable_multicast() function
|
||||
|
@ -89,6 +89,7 @@ extern uintptr SignalStackBase();
|
||||
|
||||
// From rsrc_patches.cpp
|
||||
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
|
||||
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);
|
||||
status = COMPILE_CODE_OK;
|
||||
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
|
||||
case NATIVE_BITBLT:
|
||||
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
|
||||
void sheepshaver_cpu::execute_native_op(uint32 selector)
|
||||
{
|
||||
@ -1070,27 +1072,29 @@ void sheepshaver_cpu::execute_native_op(uint32 selector)
|
||||
break;
|
||||
}
|
||||
case NATIVE_GET_RESOURCE:
|
||||
case NATIVE_GET_1_RESOURCE:
|
||||
case NATIVE_GET_IND_RESOURCE:
|
||||
case NATIVE_GET_1_IND_RESOURCE:
|
||||
case NATIVE_R_GET_RESOURCE: {
|
||||
typedef void (*GetResourceCallback)(void);
|
||||
static const GetResourceCallback get_resource_callbacks[] = {
|
||||
::get_resource,
|
||||
::get_1_resource,
|
||||
::get_ind_resource,
|
||||
::get_1_ind_resource,
|
||||
::r_get_resource
|
||||
};
|
||||
get_resource_callbacks[selector - NATIVE_GET_RESOURCE]();
|
||||
get_resource(ReadMacInt32(XLM_GET_RESOURCE));
|
||||
break;
|
||||
case NATIVE_GET_1_RESOURCE:
|
||||
get_resource(ReadMacInt32(XLM_GET_1_RESOURCE));
|
||||
break;
|
||||
case NATIVE_GET_IND_RESOURCE:
|
||||
get_resource(ReadMacInt32(XLM_GET_IND_RESOURCE));
|
||||
break;
|
||||
case NATIVE_GET_1_IND_RESOURCE:
|
||||
get_resource(ReadMacInt32(XLM_GET_1_IND_RESOURCE));
|
||||
break;
|
||||
case NATIVE_R_GET_RESOURCE:
|
||||
get_resource(ReadMacInt32(XLM_R_GET_RESOURCE));
|
||||
break;
|
||||
}
|
||||
case NATIVE_MAKE_EXECUTABLE:
|
||||
MakeExecutable(0, gpr(4), gpr(5));
|
||||
break;
|
||||
case NATIVE_CHECK_LOAD_INVOC:
|
||||
check_load_invoc(gpr(3), gpr(4), gpr(5));
|
||||
break;
|
||||
case NATIVE_NAMED_CHECK_LOAD_INVOC:
|
||||
named_check_load_invoc(gpr(3), gpr(4), gpr(5));
|
||||
break;
|
||||
default:
|
||||
printf("FATAL: NATIVE_OP called with bogus selector %d\n", selector);
|
||||
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 };
|
||||
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
|
||||
*/
|
||||
@ -601,6 +617,23 @@ void check_load_invoc(uint32 type, int16 id, uint32 h)
|
||||
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__
|
||||
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
|
||||
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
|
||||
// Routines in asm_linux.S
|
||||
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_1_ind_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
|
||||
|
||||
void PatchNativeResourceManager(void)
|
||||
@ -865,5 +966,39 @@ void PatchNativeResourceManager(void)
|
||||
#else
|
||||
WriteMacInt32(tvec, (uint32)r_get_resource);
|
||||
#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
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ uint32 NativeOpcode(int selector)
|
||||
uint32 opcode;
|
||||
switch (selector) {
|
||||
case NATIVE_CHECK_LOAD_INVOC:
|
||||
case NATIVE_NAMED_CHECK_LOAD_INVOC:
|
||||
opcode = POWERPC_NATIVE_OP(0, selector);
|
||||
break;
|
||||
case NATIVE_PATCH_NAME_REGISTRY:
|
||||
@ -85,6 +86,8 @@ uint32 NativeOpcode(int selector)
|
||||
case NATIVE_GET_IND_RESOURCE:
|
||||
case NATIVE_GET_1_IND_RESOURCE:
|
||||
case NATIVE_R_GET_RESOURCE:
|
||||
case NATIVE_GET_NAMED_RESOURCE:
|
||||
case NATIVE_GET_1_NAMED_RESOURCE:
|
||||
case NATIVE_MAKE_EXECUTABLE:
|
||||
case NATIVE_SYNC_HOOK:
|
||||
case NATIVE_BITBLT_HOOK:
|
||||
@ -112,9 +115,15 @@ static uint32 get_1_resource_func;
|
||||
static uint32 get_ind_resource_func;
|
||||
static uint32 get_1_ind_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)
|
||||
{
|
||||
// check_load_invoc() thunk
|
||||
uint32 check_load_invoc_opcode = NativeOpcode(NATIVE_CHECK_LOAD_INVOC);
|
||||
uint32 base;
|
||||
|
||||
static uint32 get_resource_template[] = {
|
||||
PL(0x7c0802a6), // mflr r0
|
||||
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);
|
||||
|
||||
uint32 check_load_invoc_opcode = NativeOpcode(NATIVE_CHECK_LOAD_INVOC);
|
||||
uint32 base;
|
||||
|
||||
// GetResource()
|
||||
get_resource_func = base = SheepMem::Reserve(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);
|
||||
WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_R_GET_RESOURCE);
|
||||
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
|
||||
|
||||
@ -217,6 +275,8 @@ bool ThunksInit(void)
|
||||
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_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
|
||||
#else
|
||||
#if defined(__linux__) || defined(__NetBSD__) || (defined(__APPLE__) && defined(__MACH__))
|
||||
|
Loading…
Reference in New Issue
Block a user