Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e30b56b1
Commit
e30b56b1
authored
Aug 20, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wow64: Add a thunk for the NtRaiseException syscall.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
ee99bd4b
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
195 additions
and
3 deletions
+195
-3
process.c
dlls/wow64/process.c
+191
-0
syscall.c
dlls/wow64/syscall.c
+2
-3
syscall.h
dlls/wow64/syscall.h
+1
-0
wow64_private.h
dlls/wow64/wow64_private.h
+1
-0
No files found.
dlls/wow64/process.c
View file @
e30b56b1
...
...
@@ -27,6 +27,8 @@
#include "winnt.h"
#include "winternl.h"
#include "wow64_private.h"
#include "wine/asm.h"
#include "wine/exception.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
wow
);
...
...
@@ -71,6 +73,23 @@ static BOOL is_process_id_wow64( const CLIENT_ID *id )
}
static
EXCEPTION_RECORD
*
exception_record_32to64
(
const
EXCEPTION_RECORD32
*
rec32
)
{
EXCEPTION_RECORD
*
rec
;
unsigned
int
i
;
rec
=
Wow64AllocateTemp
(
sizeof
(
*
rec
)
);
rec
->
ExceptionCode
=
rec32
->
ExceptionCode
;
rec
->
ExceptionFlags
=
rec32
->
ExceptionFlags
;
rec
->
ExceptionRecord
=
rec32
->
ExceptionRecord
?
exception_record_32to64
(
ULongToPtr
(
rec32
->
ExceptionRecord
)
)
:
NULL
;
rec
->
ExceptionAddress
=
ULongToPtr
(
rec32
->
ExceptionAddress
);
rec
->
NumberParameters
=
rec32
->
NumberParameters
;
for
(
i
=
0
;
i
<
EXCEPTION_MAXIMUM_PARAMETERS
;
i
++
)
rec
->
ExceptionInformation
[
i
]
=
rec32
->
ExceptionInformation
[
i
];
return
rec
;
}
static
RTL_USER_PROCESS_PARAMETERS
*
process_params_32to64
(
RTL_USER_PROCESS_PARAMETERS
**
params
,
RTL_USER_PROCESS_PARAMETERS32
*
params32
)
{
...
...
@@ -274,6 +293,150 @@ void put_vm_counters( VM_COUNTERS_EX32 *info32, const VM_COUNTERS_EX *info, ULON
}
static
void
call_user_exception_dispatcher
(
EXCEPTION_RECORD32
*
rec
,
void
*
ctx32_ptr
,
void
*
ctx64_ptr
)
{
switch
(
current_machine
)
{
case
IMAGE_FILE_MACHINE_I386
:
{
struct
stack_layout
{
ULONG
rec_ptr
;
/* first arg for KiUserExceptionDispatcher */
ULONG
context_ptr
;
/* second arg for KiUserExceptionDispatcher */
EXCEPTION_RECORD32
rec
;
I386_CONTEXT
context
;
}
*
stack
;
I386_CONTEXT
*
context
,
ctx
=
{
CONTEXT_I386_ALL
};
CONTEXT_EX
*
context_ex
,
*
src_ex
=
NULL
;
ULONG
size
,
flags
;
NtQueryInformationThread
(
GetCurrentThread
(),
ThreadWow64Context
,
&
ctx
,
sizeof
(
ctx
),
NULL
);
if
(
ctx32_ptr
)
{
I386_CONTEXT
*
ctx32
=
ctx32_ptr
;
if
((
ctx32
->
ContextFlags
&
CONTEXT_I386_XSTATE
)
==
CONTEXT_I386_XSTATE
)
src_ex
=
(
CONTEXT_EX
*
)(
ctx32
+
1
);
}
else
if
(
native_machine
==
IMAGE_FILE_MACHINE_AMD64
)
{
AMD64_CONTEXT
*
ctx64
=
ctx64_ptr
;
if
((
ctx64
->
ContextFlags
&
CONTEXT_AMD64_FLOATING_POINT
)
==
CONTEXT_AMD64_FLOATING_POINT
)
memcpy
(
ctx
.
ExtendedRegisters
,
&
ctx64
->
FltSave
,
sizeof
(
ctx
.
ExtendedRegisters
)
);
if
((
ctx64
->
ContextFlags
&
CONTEXT_AMD64_XSTATE
)
==
CONTEXT_AMD64_XSTATE
)
src_ex
=
(
CONTEXT_EX
*
)(
ctx64
+
1
);
}
flags
=
ctx
.
ContextFlags
;
if
(
src_ex
)
flags
|=
CONTEXT_I386_XSTATE
;
RtlGetExtendedContextLength
(
flags
,
&
size
);
size
=
((
size
+
15
)
&
~
15
)
+
offsetof
(
struct
stack_layout
,
context
);
stack
=
(
struct
stack_layout
*
)(
ULONG_PTR
)(
ctx
.
Esp
-
size
);
stack
->
rec_ptr
=
PtrToUlong
(
&
stack
->
rec
);
stack
->
rec
=
*
rec
;
RtlInitializeExtendedContext
(
&
stack
->
context
,
flags
,
&
context_ex
);
context
=
RtlLocateLegacyContext
(
context_ex
,
NULL
);
*
context
=
ctx
;
context
->
ContextFlags
=
flags
;
stack
->
context_ptr
=
PtrToUlong
(
context
);
if
(
src_ex
)
{
XSTATE
*
src_xs
=
(
XSTATE
*
)((
char
*
)
src_ex
+
src_ex
->
XState
.
Offset
);
XSTATE
*
dst_xs
=
(
XSTATE
*
)((
char
*
)
context_ex
+
context_ex
->
XState
.
Offset
);
dst_xs
->
Mask
=
src_xs
->
Mask
&
~
(
ULONG64
)
3
;
dst_xs
->
CompactionMask
=
src_xs
->
CompactionMask
;
if
((
dst_xs
->
Mask
&
4
)
&&
src_ex
->
XState
.
Length
>=
sizeof
(
XSTATE
)
&&
context_ex
->
XState
.
Length
>=
sizeof
(
XSTATE
))
memcpy
(
&
dst_xs
->
YmmContext
,
&
src_xs
->
YmmContext
,
sizeof
(
dst_xs
->
YmmContext
)
);
}
ctx
.
Esp
=
PtrToUlong
(
stack
);
ctx
.
Eip
=
pLdrSystemDllInitBlock
->
pKiUserExceptionDispatcher
;
ctx
.
EFlags
&=
~
(
0x100
|
0x400
|
0x40000
);
NtSetInformationThread
(
GetCurrentThread
(),
ThreadWow64Context
,
&
ctx
,
sizeof
(
ctx
)
);
TRACE
(
"exception %08x dispatcher %08x stack %08x eip %08x
\n
"
,
rec
->
ExceptionCode
,
ctx
.
Eip
,
ctx
.
Esp
,
stack
->
context
.
Eip
);
}
break
;
case
IMAGE_FILE_MACHINE_ARMNT
:
{
struct
stack_layout
{
ARM_CONTEXT
context
;
EXCEPTION_RECORD32
rec
;
}
*
stack
;
ARM_CONTEXT
ctx
=
{
CONTEXT_ARM_ALL
};
NtQueryInformationThread
(
GetCurrentThread
(),
ThreadWow64Context
,
&
ctx
,
sizeof
(
ctx
),
NULL
);
stack
=
(
struct
stack_layout
*
)(
ULONG_PTR
)(
ctx
.
Sp
&
~
3
)
-
1
;
stack
->
rec
=
*
rec
;
stack
->
context
=
ctx
;
ctx
.
R0
=
PtrToUlong
(
&
stack
->
rec
);
/* first arg for KiUserExceptionDispatcher */
ctx
.
R1
=
PtrToUlong
(
&
stack
->
context
);
/* second arg for KiUserExceptionDispatcher */
ctx
.
Sp
=
PtrToUlong
(
stack
);
ctx
.
Pc
=
pLdrSystemDllInitBlock
->
pKiUserExceptionDispatcher
;
if
(
ctx
.
Pc
&
1
)
ctx
.
Cpsr
|=
0x20
;
else
ctx
.
Cpsr
&=
~
0x20
;
NtSetInformationThread
(
GetCurrentThread
(),
ThreadWow64Context
,
&
ctx
,
sizeof
(
ctx
)
);
TRACE
(
"exception %08x dispatcher %08x stack %08x pc %08x
\n
"
,
rec
->
ExceptionCode
,
ctx
.
Pc
,
ctx
.
Sp
,
stack
->
context
.
Sp
);
}
break
;
}
}
/* based on RtlRaiseException: call NtRaiseException with context setup to return to caller */
void
WINAPI
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
DECLSPEC_HIDDEN
;
#ifdef __x86_64__
__ASM_GLOBAL_FUNC
(
raise_exception
,
"sub $0x28,%rsp
\n\t
"
__ASM_SEH
(
".seh_stackalloc 0x28
\n\t
"
)
__ASM_SEH
(
".seh_endprologue
\n\t
"
)
__ASM_CFI
(
".cfi_adjust_cfa_offset 0x28
\n\t
"
)
"movq %rcx,(%rsp)
\n\t
"
"movq %rdx,%rcx
\n\t
"
"call "
__ASM_NAME
(
"RtlCaptureContext"
)
"
\n\t
"
"leaq 0x30(%rsp),%rax
\n\t
"
/* orig stack pointer */
"movq %rax,0x98(%rdx)
\n\t
"
/* context->Rsp */
"movq (%rsp),%rcx
\n\t
"
/* original first parameter */
"movq 0x28(%rsp),%rax
\n\t
"
/* return address */
"movq %rax,0xf8(%rdx)
\n\t
"
/* context->Rip */
"movq %rax,0x10(%rcx)
\n\t
"
/* rec->ExceptionAddress */
"call "
__ASM_NAME
(
"NtRaiseException"
)
)
#elif defined(__aarch64__)
__ASM_GLOBAL_FUNC
(
raise_exception
,
"stp x29, x30, [sp, #-32]!
\n\t
"
__ASM_SEH
(
".seh_stackalloc 32
\n\t
"
)
__ASM_SEH
(
".seh_save_fplr 0
\n\t
"
)
__ASM_SEH
(
".seh_endprologue
\n\t
"
)
__ASM_CFI
(
".cfi_def_cfa x29, 32
\n\t
"
)
__ASM_CFI
(
".cfi_offset x30, -24
\n\t
"
)
__ASM_CFI
(
".cfi_offset x29, -32
\n\t
"
)
"mov x29, sp
\n\t
"
"stp x0, x1, [sp, #16]
\n\t
"
"mov x0, x1
\n\t
"
"bl "
__ASM_NAME
(
"RtlCaptureContext"
)
"
\n\t
"
"ldp x0, x1, [sp, #16]
\n\t
"
/* orig parameters */
"ldp x4, x5, [sp]
\n\t
"
/* frame pointer, return address */
"stp x4, x5, [x1, #0xf0]
\n\t
"
/* context->Fp, Lr */
"add x4, sp, #32
\n\t
"
/* orig stack pointer */
"stp x4, x5, [x1, #0x100]
\n\t
"
/* context->Sp, Pc */
"str x5, [x0, #0x10]
\n\t
"
/* rec->ExceptionAddress */
"bl "
__ASM_NAME
(
"NtRaiseException"
)
)
#endif
/**********************************************************************
* wow64_NtAlertResumeThread
*/
...
...
@@ -806,6 +969,34 @@ NTSTATUS WINAPI wow64_NtQueueApcThread( UINT *args )
/**********************************************************************
* wow64_NtRaiseException
*/
NTSTATUS
WINAPI
wow64_NtRaiseException
(
UINT
*
args
)
{
EXCEPTION_RECORD32
*
rec32
=
get_ptr
(
&
args
);
void
*
context32
=
get_ptr
(
&
args
);
BOOL
first_chance
=
get_ulong
(
&
args
);
EXCEPTION_RECORD
*
rec
=
exception_record_32to64
(
rec32
);
CONTEXT
context
;
NtSetInformationThread
(
GetCurrentThread
(),
ThreadWow64Context
,
context32
,
get_machine_context_size
(
current_machine
));
__TRY
{
raise_exception
(
rec
,
&
context
,
first_chance
);
}
__EXCEPT_ALL
{
call_user_exception_dispatcher
(
rec32
,
context32
,
&
context
);
}
__ENDTRY
return
STATUS_SUCCESS
;
}
/**********************************************************************
* wow64_NtRemoveProcessDebug
*/
NTSTATUS
WINAPI
wow64_NtRemoveProcessDebug
(
UINT
*
args
)
...
...
dlls/wow64/syscall.c
View file @
e30b56b1
...
...
@@ -63,9 +63,7 @@ struct mem_header
BYTE
data
[
1
];
};
static
void
**
pWow64Transition
;
static
void
**
p__wine_syscall_dispatcher
;
static
SYSTEM_DLL_INIT_BLOCK
*
pLdrSystemDllInitBlock
;
SYSTEM_DLL_INIT_BLOCK
*
pLdrSystemDllInitBlock
=
NULL
;
/* cpu backend dll functions */
static
void
*
(
WINAPI
*
pBTCpuGetBopCode
)(
void
);
...
...
@@ -421,6 +419,7 @@ static HMODULE load_cpu_dll(void)
*/
static
DWORD
WINAPI
process_init
(
RTL_RUN_ONCE
*
once
,
void
*
param
,
void
**
context
)
{
void
**
pWow64Transition
,
**
p__wine_syscall_dispatcher
;
HMODULE
module
;
UNICODE_STRING
str
;
...
...
dlls/wow64/syscall.h
View file @
e30b56b1
...
...
@@ -171,6 +171,7 @@
SYSCALL_ENTRY( NtQueryVirtualMemory ) \
SYSCALL_ENTRY( NtQueryVolumeInformationFile ) \
SYSCALL_ENTRY( NtQueueApcThread ) \
SYSCALL_ENTRY( NtRaiseException ) \
SYSCALL_ENTRY( NtRaiseHardError ) \
SYSCALL_ENTRY( NtReadFile ) \
SYSCALL_ENTRY( NtReadFileScatter ) \
...
...
dlls/wow64/wow64_private.h
View file @
e30b56b1
...
...
@@ -37,6 +37,7 @@ extern BOOL get_file_redirect( OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;
extern
USHORT
native_machine
DECLSPEC_HIDDEN
;
extern
USHORT
current_machine
DECLSPEC_HIDDEN
;
extern
ULONG_PTR
args_alignment
DECLSPEC_HIDDEN
;
extern
SYSTEM_DLL_INIT_BLOCK
*
pLdrSystemDllInitBlock
DECLSPEC_HIDDEN
;
struct
object_attr64
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment