ntdll: Add support for dispatching exception from 32-bit code in Wow64 mode.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-12-01 11:27:51 +01:00
parent 971480aacc
commit e5e857c290
4 changed files with 29 additions and 1 deletions

View File

@ -3855,6 +3855,8 @@ static void load_global_options(void)
static void (WINAPI *pWow64LdrpInitialize)( CONTEXT *ctx );
void (WINAPI *pWow64PrepareForException)( EXCEPTION_RECORD *rec, CONTEXT *context ) = NULL;
static void init_wow64( CONTEXT *context )
{
if (!imports_fixup_done)
@ -3874,6 +3876,7 @@ static void init_wow64( CONTEXT *context )
if (!(p ## name = RtlFindExportedRoutineByName( wow64, #name ))) ERR( "failed to load %s\n", #name )
GET_PTR( Wow64LdrpInitialize );
GET_PTR( Wow64PrepareForException );
#undef GET_PTR
imports_fixup_done = TRUE;
}

View File

@ -52,6 +52,7 @@ extern void WINAPI LdrInitializeThunk(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR) DE
extern NTSTATUS WINAPI KiUserExceptionDispatcher(EXCEPTION_RECORD*,CONTEXT*) DECLSPEC_HIDDEN;
extern void WINAPI KiUserApcDispatcher(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC) DECLSPEC_HIDDEN;
extern void WINAPI KiUserCallbackDispatcher(ULONG,void*,ULONG) DECLSPEC_HIDDEN;
extern void (WINAPI *pWow64PrepareForException)( EXCEPTION_RECORD *rec, CONTEXT *context ) DECLSPEC_HIDDEN;
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
extern RUNTIME_FUNCTION *lookup_function_info( ULONG_PTR pc, ULONG_PTR *base, LDR_DATA_TABLE_ENTRY **module ) DECLSPEC_HIDDEN;

View File

@ -566,12 +566,35 @@ NTSTATUS WINAPI dispatch_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
}
NTSTATUS WINAPI dispatch_wow_exception( EXCEPTION_RECORD *rec_ptr, CONTEXT *context_ptr )
{
char buffer[sizeof(CONTEXT) + sizeof(CONTEXT_EX) + sizeof(XSTATE) + 128];
CONTEXT *context;
CONTEXT_EX *context_ex;
EXCEPTION_RECORD rec = *rec_ptr;
RtlInitializeExtendedContext( buffer, context_ptr->ContextFlags, &context_ex );
context = RtlLocateLegacyContext( context_ex, NULL );
RtlCopyContext( context, context_ptr->ContextFlags, context_ptr );
pWow64PrepareForException( &rec, context );
return dispatch_exception( &rec, context );
}
/*******************************************************************
* KiUserExceptionDispatcher (NTDLL.@)
*/
__ASM_GLOBAL_FUNC( KiUserExceptionDispatcher,
"mov 0x98(%rsp),%rcx\n\t" /* context->Rsp */
"mov 0xf8(%rsp),%rdx\n\t" /* context->Rip */
"movw %cs,%ax\n\t"
"cmpw %ax,0x38(%rsp)\n\t" /* context->SegCs */
"je 1f\n\t"
"mov %rsp,%rdx\n\t" /* context */
"lea 0x4f0(%rsp),%rcx\n\t" /* rec */
"movq %r14,%rsp\n\t" /* switch to 64-bit stack */
"call " __ASM_NAME("dispatch_wow_exception") "\n\t"
"int3\n"
"1:\tmov 0xf8(%rsp),%rdx\n\t" /* context->Rip */
"mov %rdx,-0x8(%rcx)\n\t"
"mov %rbp,-0x10(%rcx)\n\t"
"mov %rdi,-0x18(%rcx)\n\t"

View File

@ -2171,6 +2171,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
}
}
CS_sig(sigcontext) = cs64_sel;
RIP_sig(sigcontext) = (ULONG_PTR)pKiUserExceptionDispatcher;
RSP_sig(sigcontext) = (ULONG_PTR)stack;
/* clear single-step, direction, and align check flag */