Hack to detect register functions automatically so that relay debug
also works for functions using the DEFINE_REGS_ENTRY_POINT macros.
This commit is contained in:
parent
d427f731f0
commit
07f736bc3d
|
@ -463,7 +463,7 @@ void WINAPI RELAY_DoCallFrom32Regs( CONTEXT86 *context )
|
|||
|
||||
BYTE *relay_addr = *((BYTE **)context->Esp - 1);
|
||||
DEBUG_ENTRY_POINT *relay = (DEBUG_ENTRY_POINT *)(relay_addr - 5);
|
||||
WORD nb_args = (relay->args & ~0x8000) / sizeof(int);
|
||||
WORD nb_args = relay->args / sizeof(int);
|
||||
|
||||
/* remove extra stuff from the stack */
|
||||
context->Eip = stack32_pop(context);
|
||||
|
@ -523,6 +523,26 @@ __ASM_GLOBAL_FUNC( RELAY_CallFrom32Regs,
|
|||
"call " __ASM_NAME("__wine_call_from_32_regs") "\n\t"
|
||||
".long " __ASM_NAME("RELAY_DoCallFrom32Regs") ",0" );
|
||||
|
||||
|
||||
/* check whether the function at addr starts with a call to __wine_call_from_32_regs */
|
||||
static BOOL is_register_entry_point( const BYTE *addr )
|
||||
{
|
||||
extern void __wine_call_from_32_regs();
|
||||
int *offset;
|
||||
void *ptr;
|
||||
|
||||
if (*addr != 0xe8) return FALSE; /* not a call */
|
||||
/* check if call target is __wine_call_from_32_regs */
|
||||
offset = (int *)(addr + 1);
|
||||
if (*offset == (char *)__wine_call_from_32_regs - (char *)(offset + 1)) return TRUE;
|
||||
/* now check if call target is an import table jump to __wine_call_from_32_regs */
|
||||
addr = (BYTE *)(offset + 1) + *offset;
|
||||
if (addr[0] != 0xff || addr[1] != 0x25) return FALSE; /* not an indirect jmp */
|
||||
ptr = *(void **)(addr + 2); /* get indirect jmp target address */
|
||||
return (*(char **)ptr == (char *)__wine_call_from_32_regs);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RELAY_SetupDLL
|
||||
*
|
||||
|
@ -560,7 +580,7 @@ void RELAY_SetupDLL( const char *module )
|
|||
if (on)
|
||||
{
|
||||
debug->call = 0xe8; /* call relative */
|
||||
if (debug->args & 0x8000) /* register func */
|
||||
if (is_register_entry_point( debug->orig ))
|
||||
debug->callfrom32 = (char *)RELAY_CallFrom32Regs - (char *)&debug->ret;
|
||||
else
|
||||
debug->callfrom32 = (char *)RELAY_CallFrom32 - (char *)&debug->ret;
|
||||
|
|
|
@ -271,23 +271,19 @@ static int output_exports( FILE *outfile, int nr_exports )
|
|||
|
||||
name = odp->link_name;
|
||||
args = strlen(odp->u.func.arg_types) * sizeof(int);
|
||||
if (odp->flags & FLAG_REGISTER)
|
||||
{
|
||||
name = make_internal_name( odp, "regs" );
|
||||
args |= 0x8000;
|
||||
}
|
||||
if (odp->flags & FLAG_REGISTER) name = make_internal_name( odp, "regs" );
|
||||
|
||||
switch(odp->type)
|
||||
{
|
||||
case TYPE_STDCALL:
|
||||
fprintf( outfile, " \"\\tjmp " __ASM_NAME("%s") "\\n\"\n", name );
|
||||
fprintf( outfile, " \"\\tret $0x%04x\\n\"\n", args );
|
||||
fprintf( outfile, " \"\\tret $%d\\n\"\n", args );
|
||||
fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") ",0x%08x\\n\"\n", name, mask );
|
||||
break;
|
||||
case TYPE_CDECL:
|
||||
fprintf( outfile, " \"\\tjmp " __ASM_NAME("%s") "\\n\"\n", name );
|
||||
fprintf( outfile, " \"\\tret\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.short 0x%04x\\n\"\n", args );
|
||||
fprintf( outfile, " \"\\t.short %d\\n\"\n", args );
|
||||
fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") ",0x%08x\\n\"\n", name, mask );
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue