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
32f5efcd
Commit
32f5efcd
authored
Jan 26, 2024
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll/tests: Port the exception unwinding tests to ARM64.
parent
35c1cc6c
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
221 additions
and
18 deletions
+221
-18
exception.c
dlls/ntdll/tests/exception.c
+221
-18
No files found.
dlls/ntdll/tests/exception.c
View file @
32f5efcd
...
...
@@ -80,6 +80,11 @@ static void * (WINAPI *pLocateXStateFeature)(CONTEXT *context, DWORD feature_
static
BOOL
(
WINAPI
*
pSetXStateFeaturesMask
)(
CONTEXT
*
context
,
DWORD64
feature_mask
);
static
BOOL
(
WINAPI
*
pGetXStateFeaturesMask
)(
CONTEXT
*
context
,
DWORD64
*
feature_mask
);
static
BOOL
(
WINAPI
*
pWaitForDebugEventEx
)(
DEBUG_EVENT
*
,
DWORD
);
#ifndef __i386__
static
VOID
(
WINAPI
*
pRtlUnwindEx
)(
VOID
*
,
VOID
*
,
EXCEPTION_RECORD
*
,
VOID
*
,
CONTEXT
*
,
UNWIND_HISTORY_TABLE
*
);
static
BOOLEAN
(
CDECL
*
pRtlAddFunctionTable
)(
RUNTIME_FUNCTION
*
,
DWORD
,
DWORD64
);
static
BOOLEAN
(
CDECL
*
pRtlDeleteFunctionTable
)(
RUNTIME_FUNCTION
*
);
#endif
static
void
*
pKiUserApcDispatcher
;
static
void
*
pKiUserCallbackDispatcher
;
...
...
@@ -180,8 +185,6 @@ typedef struct _UNWIND_INFO
*/
}
UNWIND_INFO
;
static
BOOLEAN
(
CDECL
*
pRtlAddFunctionTable
)(
RUNTIME_FUNCTION
*
,
DWORD
,
DWORD64
);
static
BOOLEAN
(
CDECL
*
pRtlDeleteFunctionTable
)(
RUNTIME_FUNCTION
*
);
static
BOOLEAN
(
CDECL
*
pRtlInstallFunctionTableCallback
)(
DWORD64
,
DWORD64
,
DWORD
,
PGET_RUNTIME_FUNCTION_CALLBACK
,
PVOID
,
PCWSTR
);
static
PRUNTIME_FUNCTION
(
WINAPI
*
pRtlLookupFunctionEntry
)(
ULONG64
,
ULONG64
*
,
UNWIND_HISTORY_TABLE
*
);
static
DWORD
(
WINAPI
*
pRtlAddGrowableFunctionTable
)(
void
**
,
RUNTIME_FUNCTION
*
,
DWORD
,
DWORD
,
ULONG_PTR
,
ULONG_PTR
);
...
...
@@ -193,7 +196,6 @@ static VOID (CDECL *pRtlRestoreContext)(CONTEXT*, EXCEPTION_RECORD*);
static
NTSTATUS
(
WINAPI
*
pRtlWow64GetThreadContext
)(
HANDLE
,
WOW64_CONTEXT
*
);
static
NTSTATUS
(
WINAPI
*
pRtlWow64SetThreadContext
)(
HANDLE
,
const
WOW64_CONTEXT
*
);
static
NTSTATUS
(
WINAPI
*
pRtlWow64GetCpuAreaInfo
)(
WOW64_CPURESERVED
*
,
ULONG
,
WOW64_CPU_AREA_INFO
*
);
static
VOID
(
WINAPI
*
pRtlUnwindEx
)(
VOID
*
,
VOID
*
,
EXCEPTION_RECORD
*
,
VOID
*
,
CONTEXT
*
,
UNWIND_HISTORY_TABLE
*
);
static
int
(
CDECL
*
p_setjmp
)(
_JUMP_BUFFER
*
);
#endif
...
...
@@ -2014,7 +2016,7 @@ static void test_KiUserExceptionDispatcher(void)
memcpy
(
pKiUserExceptionDispatcher
,
patched_KiUserExceptionDispatcher_bytes
,
sizeof
(
patched_KiUserExceptionDispatcher_bytes
));
got_exception
=
0
;
run_exception_test
(
dbg_except_continue_handler
,
NULL
,
except_code
,
ARRAY_SIZE
(
except_code
),
run_exception_test
(
dbg_except_continue_handler
,
NULL
,
except_code
,
sizeof
(
except_code
),
PAGE_EXECUTE_READ
);
ok
(
got_exception
,
"Handler was not called.
\n
"
);
...
...
@@ -2797,6 +2799,12 @@ static void test_dynamic_unwind(void)
NTSTATUS
status
;
DWORD
count
;
if
(
!
pRtlInstallFunctionTableCallback
||
!
pRtlLookupFunctionEntry
)
{
win_skip
(
"Dynamic unwind functions not found
\n
"
);
return
;
}
/* Test RtlAddFunctionTable with aligned RUNTIME_FUNCTION pointer */
runtime_func
=
(
RUNTIME_FUNCTION
*
)
buf
;
runtime_func
->
BeginAddress
=
code_offset
;
...
...
@@ -5110,7 +5118,7 @@ static void test_KiUserExceptionDispatcher(void)
memcpy
(
pKiUserExceptionDispatcher
,
patched_KiUserExceptionDispatcher_bytes
,
sizeof
(
patched_KiUserExceptionDispatcher_bytes
));
got_exception
=
0
;
run_exception_test
(
dbg_except_continue_handler
,
NULL
,
except_code
,
ARRAY_SIZE
(
except_code
),
PAGE_EXECUTE_READ
);
run_exception_test
(
dbg_except_continue_handler
,
NULL
,
except_code
,
sizeof
(
except_code
),
PAGE_EXECUTE_READ
);
ok
(
got_exception
,
"Handler was not called.
\n
"
);
ok
(
hook_called
,
"Hook was not called.
\n
"
);
...
...
@@ -5174,7 +5182,7 @@ static void test_KiUserExceptionDispatcher(void)
got_exception
=
0
;
hook_called
=
FALSE
;
run_exception_test
(
dbg_except_continue_handler
,
NULL
,
except_code
,
ARRAY_SIZE
(
except_code
),
PAGE_EXECUTE_READ
);
run_exception_test
(
dbg_except_continue_handler
,
NULL
,
except_code
,
sizeof
(
except_code
),
PAGE_EXECUTE_READ
);
ok
(
got_exception
,
"Handler was not called.
\n
"
);
ok
(
hook_called
,
"Hook was not called.
\n
"
);
...
...
@@ -5442,7 +5450,7 @@ static const BYTE nested_except_code[] =
static
void
test_nested_exception
(
void
)
{
got_nested_exception
=
got_prev_frame_exception
=
FALSE
;
run_exception_test
(
nested_exception_handler
,
NULL
,
nested_except_code
,
ARRAY_SIZE
(
nested_except_code
),
PAGE_EXECUTE_READ
);
run_exception_test
(
nested_exception_handler
,
NULL
,
nested_except_code
,
sizeof
(
nested_except_code
),
PAGE_EXECUTE_READ
);
ok
(
got_nested_exception
,
"Did not get nested exception.
\n
"
);
ok
(
got_prev_frame_exception
,
"Did not get nested exception in the previous frame.
\n
"
);
}
...
...
@@ -5510,7 +5518,7 @@ static void test_collided_unwind(void)
{
got_nested_exception
=
got_prev_frame_exception
=
FALSE
;
collided_unwind_exception_count
=
0
;
run_exception_test_flags
(
collided_exception_handler
,
NULL
,
nested_except_code
,
ARRAY_SIZE
(
nested_except_code
),
run_exception_test_flags
(
collided_exception_handler
,
NULL
,
nested_except_code
,
sizeof
(
nested_except_code
),
PAGE_EXECUTE_READ
,
UNW_FLAG_EHANDLER
|
UNW_FLAG_UHANDLER
);
ok
(
collided_unwind_exception_count
==
6
,
"got %u.
\n
"
,
collided_unwind_exception_count
);
}
...
...
@@ -7742,7 +7750,7 @@ static void WINAPI hook_KiUserCallbackDispatcher(void *sp)
NtCallbackReturn
(
NULL
,
0
,
func
(
stack
->
args
,
stack
->
len
));
}
void
test_KiUserCallbackDispatcher
(
void
)
static
void
test_KiUserCallbackDispatcher
(
void
)
{
DWORD
old_protect
;
BOOL
ret
;
...
...
@@ -7841,6 +7849,8 @@ static const char * const reg_names[48] =
#define ORIG_LR 0xCCCCCCCC
static
int
got_exception
;
static
void
call_virtual_unwind
(
int
testnum
,
const
struct
unwind_test
*
test
)
{
static
const
int
code_offset
=
1024
;
...
...
@@ -9380,7 +9390,7 @@ static void WINAPI hook_KiUserCallbackDispatcher(void *sp)
NtCallbackReturn
(
NULL
,
0
,
func
(
stack
->
args
,
stack
->
len
));
}
void
test_KiUserCallbackDispatcher
(
void
)
static
void
test_KiUserCallbackDispatcher
(
void
)
{
DWORD
old_protect
;
BOOL
ret
;
...
...
@@ -9401,6 +9411,199 @@ static void WINAPI hook_KiUserCallbackDispatcher(void *sp)
VirtualProtect
(
pKiUserCallbackDispatcher
,
sizeof
(
saved_code
),
old_protect
,
&
old_protect
);
}
struct
unwind_info
{
DWORD
function_length
:
18
;
DWORD
version
:
2
;
DWORD
x
:
1
;
DWORD
e
:
1
;
DWORD
epilog
:
5
;
DWORD
codes
:
5
;
};
static
void
run_exception_test
(
void
*
handler
,
const
void
*
context
,
const
void
*
code
,
unsigned
int
code_size
,
unsigned
int
func2_offset
,
DWORD
access
,
DWORD
handler_flags
)
{
DWORD
buf
[
14
];
RUNTIME_FUNCTION
runtime_func
[
2
];
struct
unwind_info
unwind
;
void
(
*
func
)(
void
)
=
code_mem
;
DWORD
oldaccess
,
oldaccess2
;
runtime_func
[
0
].
BeginAddress
=
0
;
runtime_func
[
0
].
UnwindData
=
0x1000
;
runtime_func
[
1
].
BeginAddress
=
func2_offset
;
runtime_func
[
1
].
UnwindData
=
0x1014
;
unwind
.
function_length
=
func2_offset
/
4
;
unwind
.
version
=
0
;
unwind
.
x
=
1
;
unwind
.
e
=
1
;
unwind
.
epilog
=
1
;
unwind
.
codes
=
1
;
buf
[
0
]
=
*
(
DWORD
*
)
&
unwind
;
buf
[
1
]
=
0xe3e481e1
;
/* mov x29,sp; stp r29,lr,[sp,-#0x10]!; end; nop */
buf
[
2
]
=
0x1028
;
*
(
const
void
**
)
&
buf
[
3
]
=
context
;
unwind
.
function_length
=
(
code_size
-
func2_offset
)
/
4
;
buf
[
5
]
=
*
(
DWORD
*
)
&
unwind
;
buf
[
6
]
=
0xe3e481e1
;
/* mov x29,sp; stp r29,lr,[sp,-#0x10]!; end; nop */
buf
[
7
]
=
0x1028
;
*
(
const
void
**
)
&
buf
[
8
]
=
context
;
buf
[
10
]
=
0x5800004f
;
/* ldr x15, 1f */
buf
[
11
]
=
0xd61f01e0
;
/* br x15 */
*
(
const
void
**
)
&
buf
[
12
]
=
handler
;
memcpy
((
unsigned
char
*
)
code_mem
+
0x1000
,
buf
,
sizeof
(
buf
));
memcpy
(
code_mem
,
code
,
code_size
);
if
(
access
)
VirtualProtect
(
code_mem
,
code_size
,
access
,
&
oldaccess
);
FlushInstructionCache
(
GetCurrentProcess
(),
code_mem
,
0x2000
);
RtlAddFunctionTable
(
runtime_func
,
ARRAY_SIZE
(
runtime_func
),
(
ULONG_PTR
)
code_mem
);
func
();
pRtlDeleteFunctionTable
(
runtime_func
);
if
(
access
)
VirtualProtect
(
code_mem
,
code_size
,
oldaccess
,
&
oldaccess2
);
}
static
BOOL
got_nested_exception
,
got_prev_frame_exception
;
static
void
*
nested_exception_initial_frame
;
static
DWORD
nested_exception_handler
(
EXCEPTION_RECORD
*
rec
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
)
{
trace
(
"nested_exception_handler pc %p, sp %p, code %#lx, flags %#lx, ExceptionAddress %p.
\n
"
,
(
void
*
)
context
->
Pc
,
(
void
*
)
context
->
Sp
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
);
if
(
rec
->
ExceptionCode
==
0x80000003
&&
!
(
rec
->
ExceptionFlags
&
EH_NESTED_CALL
))
{
ok
(
rec
->
NumberParameters
==
1
,
"Got unexpected rec->NumberParameters %lu.
\n
"
,
rec
->
NumberParameters
);
ok
((
char
*
)
context
->
Sp
==
(
char
*
)
frame
-
0x10
,
"Got unexpected frame %p / %p.
\n
"
,
frame
,
(
void
*
)
context
->
Sp
);
ok
((
char
*
)
context
->
Fp
==
(
char
*
)
frame
-
0x10
,
"Got unexpected frame %p / %p.
\n
"
,
frame
,
(
void
*
)
context
->
Fp
);
ok
((
char
*
)
context
->
Lr
==
(
char
*
)
code_mem
+
0x0c
,
"Got unexpected lr %p.
\n
"
,
(
void
*
)
context
->
Lr
);
ok
((
char
*
)
context
->
Pc
==
(
char
*
)
code_mem
+
0x1c
,
"Got unexpected pc %p.
\n
"
,
(
void
*
)
context
->
Pc
);
nested_exception_initial_frame
=
frame
;
RaiseException
(
0xdeadbeef
,
0
,
0
,
0
);
context
->
Pc
+=
4
;
return
ExceptionContinueExecution
;
}
if
(
rec
->
ExceptionCode
==
0xdeadbeef
&&
(
rec
->
ExceptionFlags
==
EH_NESTED_CALL
||
rec
->
ExceptionFlags
==
(
EH_NESTED_CALL
|
EXCEPTION_SOFTWARE_ORIGINATE
)))
{
ok
(
!
rec
->
NumberParameters
,
"Got unexpected rec->NumberParameters %lu.
\n
"
,
rec
->
NumberParameters
);
got_nested_exception
=
TRUE
;
ok
(
frame
==
nested_exception_initial_frame
,
"Got unexpected frame %p / %p.
\n
"
,
frame
,
nested_exception_initial_frame
);
return
ExceptionContinueSearch
;
}
ok
(
rec
->
ExceptionCode
==
0xdeadbeef
&&
(
!
rec
->
ExceptionFlags
||
rec
->
ExceptionFlags
==
EXCEPTION_SOFTWARE_ORIGINATE
),
"Got unexpected exception code %#lx, flags %#lx.
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
);
ok
(
!
rec
->
NumberParameters
,
"Got unexpected rec->NumberParameters %lu.
\n
"
,
rec
->
NumberParameters
);
ok
((
char
*
)
frame
==
(
char
*
)
nested_exception_initial_frame
+
0x10
,
"Got unexpected frame %p / %p.
\n
"
,
frame
,
nested_exception_initial_frame
);
got_prev_frame_exception
=
TRUE
;
return
ExceptionContinueExecution
;
}
static
const
DWORD
nested_except_code
[]
=
{
0xa9bf7bfd
,
/* 00: stp x29, x30, [sp, #-16]! */
0x910003fd
,
/* 04: mov x29, sp */
0x94000003
,
/* 08: bl 1f */
0xa8c17bfd
,
/* 0c: ldp x29, x30, [sp], #16 */
0xd65f03c0
,
/* 10: ret */
0xa9bf7bfd
,
/* 14: stp x29, x30, [sp, #-16]! */
0x910003fd
,
/* 18: mov x29, sp */
0xd43e0000
,
/* 1c: brk #0xf000 */
0xd503201f
,
/* 20: nop */
0xa8c17bfd
,
/* 24: ldp x29, x30, [sp], #16 */
0xd65f03c0
,
/* 28: ret */
};
static
void
test_nested_exception
(
void
)
{
got_nested_exception
=
got_prev_frame_exception
=
FALSE
;
run_exception_test
(
nested_exception_handler
,
NULL
,
nested_except_code
,
sizeof
(
nested_except_code
),
5
*
sizeof
(
DWORD
),
PAGE_EXECUTE_READ
,
UNW_FLAG_EHANDLER
);
ok
(
got_nested_exception
,
"Did not get nested exception.
\n
"
);
ok
(
got_prev_frame_exception
,
"Did not get nested exception in the previous frame.
\n
"
);
}
static
unsigned
int
collided_unwind_exception_count
;
static
DWORD
collided_exception_handler
(
EXCEPTION_RECORD
*
rec
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
)
{
CONTEXT
ctx
;
trace
(
"collided_exception_handler pc %p, sp %p, code %#lx, flags %#lx, ExceptionAddress %p, frame %p.
\n
"
,
(
void
*
)
context
->
Pc
,
(
void
*
)
context
->
Sp
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
frame
);
switch
(
collided_unwind_exception_count
++
)
{
case
0
:
/* Initial exception from nested_except_code. */
ok
(
rec
->
ExceptionCode
==
STATUS_BREAKPOINT
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
nested_exception_initial_frame
=
frame
;
/* Start unwind. */
pRtlUnwindEx
((
char
*
)
frame
+
0x10
,
(
char
*
)
code_mem
+
0x0c
,
NULL
,
NULL
,
&
ctx
,
NULL
);
ok
(
0
,
"shouldn't be reached
\n
"
);
break
;
case
1
:
ok
(
rec
->
ExceptionCode
==
STATUS_UNWIND
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
ok
(
rec
->
ExceptionFlags
==
EH_UNWINDING
,
"got %#lx.
\n
"
,
rec
->
ExceptionFlags
);
ok
((
char
*
)
context
->
Pc
==
(
char
*
)
code_mem
+
0x1c
,
"got %p.
\n
"
,
(
void
*
)
context
->
Pc
);
/* generate exception in unwind handler. */
RaiseException
(
0xdeadbeef
,
0
,
0
,
0
);
ok
(
0
,
"shouldn't be reached
\n
"
);
break
;
case
2
:
/* Inner call frame, continue search. */
ok
(
rec
->
ExceptionCode
==
0xdeadbeef
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
ok
(
!
rec
->
ExceptionFlags
||
rec
->
ExceptionFlags
==
EXCEPTION_SOFTWARE_ORIGINATE
,
"got %#lx.
\n
"
,
rec
->
ExceptionFlags
);
ok
(
frame
==
nested_exception_initial_frame
,
"got %p, expected %p.
\n
"
,
frame
,
nested_exception_initial_frame
);
break
;
case
3
:
/* Top level call frame, handle exception by unwinding. */
ok
(
rec
->
ExceptionCode
==
0xdeadbeef
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
ok
(
!
rec
->
ExceptionFlags
||
rec
->
ExceptionFlags
==
EXCEPTION_SOFTWARE_ORIGINATE
,
"got %#lx.
\n
"
,
rec
->
ExceptionFlags
);
ok
((
char
*
)
frame
==
(
char
*
)
nested_exception_initial_frame
+
0x10
,
"got %p, expected %p.
\n
"
,
frame
,
nested_exception_initial_frame
);
pRtlUnwindEx
((
char
*
)
nested_exception_initial_frame
+
0x10
,
(
char
*
)
code_mem
+
0x0c
,
NULL
,
NULL
,
&
ctx
,
NULL
);
ok
(
0
,
"shouldn't be reached
\n
"
);
break
;
case
4
:
/* Collided unwind. */
ok
(
rec
->
ExceptionCode
==
STATUS_UNWIND
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
ok
(
rec
->
ExceptionFlags
==
(
EH_UNWINDING
|
EH_COLLIDED_UNWIND
),
"got %#lx.
\n
"
,
rec
->
ExceptionFlags
);
ok
(
frame
==
nested_exception_initial_frame
,
"got %p, expected %p.
\n
"
,
frame
,
nested_exception_initial_frame
);
break
;
case
5
:
/* EH_COLLIDED_UNWIND cleared for the following frames. */
ok
(
rec
->
ExceptionCode
==
STATUS_UNWIND
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
ok
(
rec
->
ExceptionFlags
==
(
EH_UNWINDING
|
EH_TARGET_UNWIND
),
"got %#lx.
\n
"
,
rec
->
ExceptionFlags
);
ok
((
char
*
)
frame
==
(
char
*
)
nested_exception_initial_frame
+
0x10
,
"got %p, expected %p.
\n
"
,
frame
,
nested_exception_initial_frame
);
break
;
}
return
ExceptionContinueSearch
;
}
static
void
test_collided_unwind
(
void
)
{
got_nested_exception
=
got_prev_frame_exception
=
FALSE
;
collided_unwind_exception_count
=
0
;
run_exception_test
(
collided_exception_handler
,
NULL
,
nested_except_code
,
sizeof
(
nested_except_code
),
5
*
sizeof
(
DWORD
),
PAGE_EXECUTE_READ
,
UNW_FLAG_EHANDLER
|
UNW_FLAG_UHANDLER
);
ok
(
collided_unwind_exception_count
==
6
,
"got %u.
\n
"
,
collided_unwind_exception_count
);
}
#endif
/* __aarch64__ */
#if defined(__i386__) || defined(__x86_64__)
...
...
@@ -12480,6 +12683,11 @@ START_TEST(exception)
X
(
KiUserApcDispatcher
);
X
(
KiUserCallbackDispatcher
);
X
(
KiUserExceptionDispatcher
);
#ifndef __i386__
X
(
RtlUnwindEx
);
X
(
RtlAddFunctionTable
);
X
(
RtlDeleteFunctionTable
);
#endif
#undef X
#define X(f) p##f = (void*)GetProcAddress(hkernel32, #f)
...
...
@@ -12609,8 +12817,6 @@ START_TEST(exception)
#elif defined(__x86_64__)
#define X(f) p##f = (void*)GetProcAddress(hntdll, #f)
X
(
RtlAddFunctionTable
);
X
(
RtlDeleteFunctionTable
);
X
(
RtlInstallFunctionTableCallback
);
X
(
RtlLookupFunctionEntry
);
X
(
RtlAddGrowableFunctionTable
);
...
...
@@ -12619,7 +12825,6 @@ START_TEST(exception)
X
(
__C_specific_handler
);
X
(
RtlCaptureContext
);
X
(
RtlRestoreContext
);
X
(
RtlUnwindEx
);
X
(
RtlWow64GetThreadContext
);
X
(
RtlWow64SetThreadContext
);
X
(
RtlWow64GetCpuAreaInfo
);
...
...
@@ -12641,11 +12846,7 @@ START_TEST(exception)
test_wow64_context
();
test_nested_exception
();
test_collided_unwind
();
if
(
pRtlAddFunctionTable
&&
pRtlDeleteFunctionTable
&&
pRtlInstallFunctionTableCallback
&&
pRtlLookupFunctionEntry
)
test_dynamic_unwind
();
else
win_skip
(
"Dynamic unwind functions not found
\n
"
);
test_dynamic_unwind
();
test_extended_context
();
test_copy_context
();
test_set_live_context
();
...
...
@@ -12657,6 +12858,8 @@ START_TEST(exception)
test_continue
();
test_virtual_unwind
();
test_nested_exception
();
test_collided_unwind
();
#elif defined(__arm__)
...
...
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