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
f135c81b
Commit
f135c81b
authored
Jun 06, 2018
by
Zebediah Figura
Committed by
Alexandre Julliard
Jun 12, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Implement RtlWow64GetThreadContext().
Signed-off-by:
Zebediah Figura
<
zfigura@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
36371075
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
137 additions
and
0 deletions
+137
-0
ntdll.spec
dlls/ntdll/ntdll.spec
+1
-0
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+100
-0
exception.c
dlls/ntdll/tests/exception.c
+36
-0
No files found.
dlls/ntdll/ntdll.spec
View file @
f135c81b
...
...
@@ -978,6 +978,7 @@
@ stdcall RtlWalkHeap(long ptr)
@ stdcall RtlWow64EnableFsRedirection(long)
@ stdcall RtlWow64EnableFsRedirectionEx(long ptr)
@ stdcall -arch=x86_64 RtlWow64GetThreadContext(long ptr)
@ stub RtlWriteMemoryStream
@ stdcall RtlWriteRegistryValue(long ptr ptr long ptr long)
@ stub RtlZeroHeap
...
...
dlls/ntdll/signal_x86_64.c
View file @
f135c81b
...
...
@@ -2200,6 +2200,106 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
}
/***********************************************************************
* wow64_get_server_context_flags
*/
static
unsigned
int
wow64_get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
WOW64_CONTEXT_i386
;
/* get rid of CPU id */
if
(
flags
&
WOW64_CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
WOW64_CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
if
(
flags
&
WOW64_CONTEXT_SEGMENTS
)
ret
|=
SERVER_CTX_SEGMENTS
;
if
(
flags
&
WOW64_CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
WOW64_CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
if
(
flags
&
WOW64_CONTEXT_EXTENDED_REGISTERS
)
ret
|=
SERVER_CTX_EXTENDED_REGISTERS
;
return
ret
;
}
/***********************************************************************
* wow64_context_from_server
*/
static
NTSTATUS
wow64_context_from_server
(
WOW64_CONTEXT
*
to
,
const
context_t
*
from
)
{
if
(
from
->
cpu
!=
CPU_x86
)
return
STATUS_INVALID_PARAMETER
;
to
->
ContextFlags
=
WOW64_CONTEXT_i386
;
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
{
to
->
ContextFlags
|=
WOW64_CONTEXT_CONTROL
;
to
->
Ebp
=
from
->
ctl
.
i386_regs
.
ebp
;
to
->
Esp
=
from
->
ctl
.
i386_regs
.
esp
;
to
->
Eip
=
from
->
ctl
.
i386_regs
.
eip
;
to
->
SegCs
=
from
->
ctl
.
i386_regs
.
cs
;
to
->
SegSs
=
from
->
ctl
.
i386_regs
.
ss
;
to
->
EFlags
=
from
->
ctl
.
i386_regs
.
eflags
;
}
if
(
from
->
flags
&
SERVER_CTX_INTEGER
)
{
to
->
ContextFlags
|=
WOW64_CONTEXT_INTEGER
;
to
->
Eax
=
from
->
integer
.
i386_regs
.
eax
;
to
->
Ebx
=
from
->
integer
.
i386_regs
.
ebx
;
to
->
Ecx
=
from
->
integer
.
i386_regs
.
ecx
;
to
->
Edx
=
from
->
integer
.
i386_regs
.
edx
;
to
->
Esi
=
from
->
integer
.
i386_regs
.
esi
;
to
->
Edi
=
from
->
integer
.
i386_regs
.
edi
;
}
if
(
from
->
flags
&
SERVER_CTX_SEGMENTS
)
{
to
->
ContextFlags
|=
WOW64_CONTEXT_SEGMENTS
;
to
->
SegDs
=
from
->
seg
.
i386_regs
.
ds
;
to
->
SegEs
=
from
->
seg
.
i386_regs
.
es
;
to
->
SegFs
=
from
->
seg
.
i386_regs
.
fs
;
to
->
SegGs
=
from
->
seg
.
i386_regs
.
gs
;
}
if
(
from
->
flags
&
SERVER_CTX_FLOATING_POINT
)
{
to
->
ContextFlags
|=
WOW64_CONTEXT_FLOATING_POINT
;
to
->
FloatSave
.
ControlWord
=
from
->
fp
.
i386_regs
.
ctrl
;
to
->
FloatSave
.
StatusWord
=
from
->
fp
.
i386_regs
.
status
;
to
->
FloatSave
.
TagWord
=
from
->
fp
.
i386_regs
.
tag
;
to
->
FloatSave
.
ErrorOffset
=
from
->
fp
.
i386_regs
.
err_off
;
to
->
FloatSave
.
ErrorSelector
=
from
->
fp
.
i386_regs
.
err_sel
;
to
->
FloatSave
.
DataOffset
=
from
->
fp
.
i386_regs
.
data_off
;
to
->
FloatSave
.
DataSelector
=
from
->
fp
.
i386_regs
.
data_sel
;
to
->
FloatSave
.
Cr0NpxState
=
from
->
fp
.
i386_regs
.
cr0npx
;
memcpy
(
to
->
FloatSave
.
RegisterArea
,
from
->
fp
.
i386_regs
.
regs
,
sizeof
(
to
->
FloatSave
.
RegisterArea
)
);
}
if
(
from
->
flags
&
SERVER_CTX_DEBUG_REGISTERS
)
{
to
->
ContextFlags
|=
WOW64_CONTEXT_DEBUG_REGISTERS
;
to
->
Dr0
=
from
->
debug
.
i386_regs
.
dr0
;
to
->
Dr1
=
from
->
debug
.
i386_regs
.
dr1
;
to
->
Dr2
=
from
->
debug
.
i386_regs
.
dr2
;
to
->
Dr3
=
from
->
debug
.
i386_regs
.
dr3
;
to
->
Dr6
=
from
->
debug
.
i386_regs
.
dr6
;
to
->
Dr7
=
from
->
debug
.
i386_regs
.
dr7
;
}
if
(
from
->
flags
&
SERVER_CTX_EXTENDED_REGISTERS
)
{
to
->
ContextFlags
|=
WOW64_CONTEXT_EXTENDED_REGISTERS
;
memcpy
(
to
->
ExtendedRegisters
,
from
->
ext
.
i386_regs
,
sizeof
(
to
->
ExtendedRegisters
)
);
}
return
STATUS_SUCCESS
;
}
/******************************************************************************
* RtlWow64GetThreadContext (NTDLL.@)
*/
NTSTATUS
WINAPI
RtlWow64GetThreadContext
(
HANDLE
handle
,
WOW64_CONTEXT
*
context
)
{
BOOL
self
;
NTSTATUS
ret
;
context_t
server_context
;
unsigned
int
server_flags
=
wow64_get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
(
self
)
return
STATUS_INVALID_PARAMETER
;
return
wow64_context_from_server
(
context
,
&
server_context
);
}
extern
void
raise_func_trampoline
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
raise_func
func
);
__ASM_GLOBAL_FUNC
(
raise_func_trampoline
,
__ASM_CFI
(
".cfi_signal_frame
\n\t
"
)
...
...
dlls/ntdll/tests/exception.c
View file @
f135c81b
...
...
@@ -149,6 +149,7 @@ static PRUNTIME_FUNCTION (WINAPI *pRtlLookupFunctionEntry)(ULONG64, ULONG64*, UN
static
EXCEPTION_DISPOSITION
(
WINAPI
*
p__C_specific_handler
)(
EXCEPTION_RECORD
*
,
ULONG64
,
CONTEXT
*
,
DISPATCHER_CONTEXT
*
);
static
VOID
(
WINAPI
*
pRtlCaptureContext
)(
CONTEXT
*
);
static
VOID
(
CDECL
*
pRtlRestoreContext
)(
CONTEXT
*
,
EXCEPTION_RECORD
*
);
static
NTSTATUS
(
WINAPI
*
pRtlWow64GetThreadContext
)(
HANDLE
,
WOW64_CONTEXT
*
);
static
VOID
(
CDECL
*
pRtlUnwindEx
)(
VOID
*
,
VOID
*
,
EXCEPTION_RECORD
*
,
VOID
*
,
CONTEXT
*
,
UNWIND_HISTORY_TABLE
*
);
static
int
(
CDECL
*
p_setjmp
)(
_JUMP_BUFFER
*
);
#endif
...
...
@@ -2490,6 +2491,38 @@ static void test_dpe_exceptions(void)
pRtlRemoveVectoredExceptionHandler
(
handler
);
}
static
void
test_wow64_context
(
void
)
{
char
cmdline
[]
=
"C:
\\
windows
\\
syswow64
\\
notepad.exe"
;
PROCESS_INFORMATION
pi
;
STARTUPINFOA
si
=
{
0
};
WOW64_CONTEXT
ctx
;
NTSTATUS
ret
;
memset
(
&
ctx
,
0x55
,
sizeof
(
ctx
));
ctx
.
ContextFlags
=
WOW64_CONTEXT_ALL
;
ret
=
pRtlWow64GetThreadContext
(
GetCurrentThread
(),
&
ctx
);
ok
(
ret
==
STATUS_INVALID_PARAMETER
||
broken
(
ret
==
STATUS_PARTIAL_COPY
),
"got %#x
\n
"
,
ret
);
CreateProcessA
(
NULL
,
cmdline
,
NULL
,
NULL
,
FALSE
,
CREATE_SUSPENDED
,
NULL
,
NULL
,
&
si
,
&
pi
);
ret
=
pRtlWow64GetThreadContext
(
pi
.
hThread
,
&
ctx
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %#x
\n
"
,
ret
);
ok
(
ctx
.
ContextFlags
==
WOW64_CONTEXT_ALL
,
"got context flags %#x
\n
"
,
ctx
.
ContextFlags
);
ok
(
!
ctx
.
Ebp
,
"got ebp %08x
\n
"
,
ctx
.
Ebp
);
ok
(
!
ctx
.
Ecx
,
"got ecx %08x
\n
"
,
ctx
.
Ecx
);
ok
(
!
ctx
.
Edx
,
"got edx %08x
\n
"
,
ctx
.
Edx
);
ok
(
!
ctx
.
Esi
,
"got esi %08x
\n
"
,
ctx
.
Esi
);
ok
(
!
ctx
.
Edi
,
"got edi %08x
\n
"
,
ctx
.
Edi
);
ok
((
ctx
.
EFlags
&
~
2
)
==
0x200
,
"got eflags %08x
\n
"
,
ctx
.
EFlags
);
ok
((
WORD
)
ctx
.
FloatSave
.
ControlWord
==
0x27f
,
"got control word %08x
\n
"
,
ctx
.
FloatSave
.
ControlWord
);
ok
(
*
(
WORD
*
)
ctx
.
ExtendedRegisters
==
0x27f
,
"got SSE control word %04x
\n
"
,
*
(
WORD
*
)
ctx
.
ExtendedRegisters
);
pNtTerminateProcess
(
pi
.
hProcess
,
0
);
}
#endif
/* __x86_64__ */
#if defined(__i386__) || defined(__x86_64__)
...
...
@@ -3128,6 +3161,8 @@ START_TEST(exception)
"RtlRestoreContext"
);
pRtlUnwindEx
=
(
void
*
)
GetProcAddress
(
hntdll
,
"RtlUnwindEx"
);
pRtlWow64GetThreadContext
=
(
void
*
)
GetProcAddress
(
hntdll
,
"RtlWow64GetThreadContext"
);
p_setjmp
=
(
void
*
)
GetProcAddress
(
hmsvcrt
,
"_setjmp"
);
...
...
@@ -3143,6 +3178,7 @@ START_TEST(exception)
test_restore_context
();
test_prot_fault
();
test_dpe_exceptions
();
test_wow64_context
();
if
(
pRtlAddFunctionTable
&&
pRtlDeleteFunctionTable
&&
pRtlInstallFunctionTableCallback
&&
pRtlLookupFunctionEntry
)
test_dynamic_unwind
();
...
...
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