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:
gbeauche 2006-05-03 21:45:14 +00:00
parent 828b53b990
commit 21f35a34f0
6 changed files with 228 additions and 52 deletions

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

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

View File

@ -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__))