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
4e740387
Commit
4e740387
authored
Jun 10, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Fix some exception test failures on ARM.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
2a505efb
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
58 additions
and
62 deletions
+58
-62
signal_arm.c
dlls/ntdll/signal_arm.c
+10
-16
exception.c
dlls/ntdll/tests/exception.c
+41
-43
signal_arm.c
dlls/ntdll/unix/signal_arm.c
+7
-3
No files found.
dlls/ntdll/signal_arm.c
View file @
4e740387
...
...
@@ -61,24 +61,21 @@ __ASM_GLOBAL_FUNC( __chkstk, "lsl r4, r4, #2\n\t"
* RtlCaptureContext (NTDLL.@)
*/
__ASM_STDCALL_FUNC
(
RtlCaptureContext
,
4
,
"str r0, [r0, #0x4]
\n\t
"
/* context->R0 */
"str r1, [r0, #0x8]
\n\t
"
/* context->R1 */
"mov r1, #0x0200000
\n\t
"
/* CONTEXT_ARM */
"add r1, r1, #0x
3
\n\t
"
/* CONTEXT_FULL
*/
"add r1, r1, #0x
7
\n\t
"
/* CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT
*/
"str r1, [r0]
\n\t
"
/* context->ContextFlags */
"str SP, [r0, #0x38]
\n\t
"
/* context->Sp */
"str LR, [r0, #0x3c]
\n\t
"
/* context->Lr */
"str LR, [r0, #0x40]
\n\t
"
/* context->Pc */
"mrs r1, CPSR
\n\t
"
"tst lr, #1
\n\t
"
/* Thumb? */
"ite ne
\n\t
"
"orrne r1, r1, #0x20
\n\t
"
"biceq r1, r1, #0x20
\n\t
"
"bfi r1, lr, #5, #1
\n\t
"
/* Thumb bit */
"str r1, [r0, #0x44]
\n\t
"
/* context->Cpsr */
"mov r1, #0
\n\t
"
"str r1, [r0, #0x4]
\n\t
"
/* context->R0 */
"str r1, [r0, #0x3c]
\n\t
"
/* context->Lr */
"add r0, #0x0c
\n\t
"
"stm r0, {r2-r12}
\n\t
"
/* context->R2..R12 */
"bx lr"
)
"bx lr"
)
/**********************************************************************
...
...
@@ -280,11 +277,8 @@ __ASM_STDCALL_FUNC( RtlRaiseException, 4,
"ldr r0, [sp, #0x1a0]
\n\t
"
/* rec */
"ldr r1, [sp, #0x1a4]
\n\t
"
"str r1, [sp, #0x40]
\n\t
"
/* context->Pc */
"ldr r2, [sp, #0x44]
\n\t
"
/* context->Cpsr */
"tst r1, #1
\n\t
"
/* Thumb? */
"ite ne
\n\t
"
"orrne r2, r2, #0x20
\n\t
"
"biceq r2, r2, #0x20
\n\t
"
"mrs r2, CPSR
\n\t
"
"bfi r2, r1, #5, #1
\n\t
"
/* Thumb bit */
"str r2, [sp, #0x44]
\n\t
"
/* context->Cpsr */
"str r1, [r0, #12]
\n\t
"
/* rec->ExceptionAddress */
"add r1, sp, #0x1a8
\n\t
"
...
...
@@ -314,11 +308,11 @@ __ASM_GLOBAL_FUNC( signal_start_thread,
/**********************************************************************
* DbgBreakPoint (NTDLL.@)
*/
__ASM_STDCALL_FUNC
(
DbgBreakPoint
,
0
,
"
bkpt #0
; bx lr; nop; nop; nop; nop"
);
__ASM_STDCALL_FUNC
(
DbgBreakPoint
,
0
,
"
udf #0xfe
; bx lr; nop; nop; nop; nop"
);
/**********************************************************************
* DbgUserBreakPoint (NTDLL.@)
*/
__ASM_STDCALL_FUNC
(
DbgUserBreakPoint
,
0
,
"
bkpt #0
; bx lr; nop; nop; nop; nop"
);
__ASM_STDCALL_FUNC
(
DbgUserBreakPoint
,
0
,
"
udf #0xfe
; bx lr; nop; nop; nop; nop"
);
#endif
/* __arm__ */
dlls/ntdll/tests/exception.c
View file @
4e740387
...
...
@@ -4250,23 +4250,28 @@ static void test_thread_context(void)
{
DWORD
R0
,
R1
,
R2
,
R3
,
R4
,
R5
,
R6
,
R7
,
R8
,
R9
,
R10
,
R11
,
R12
,
Sp
,
Lr
,
Pc
,
Cpsr
;
}
expect
;
NTSTATUS
(
*
func_ptr
)(
void
*
arg1
,
void
*
arg2
,
struct
expected
*
res
,
void
*
func
)
=
code_mem
;
static
const
DWORD
call_func
[]
=
{
0xe92d4002
,
/* push {r1, lr} */
0xe8821fff
,
/* stm r2, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip} */
0xe582d034
,
/* str sp, [r2, #52] */
0xe582e038
,
/* str lr, [r2, #56] */
0xe10f1000
,
/* mrs r1, CPSR */
0xe5821040
,
/* str r1, [r2, #64] */
0xe59d1000
,
/* ldr r1, [sp] */
0xe582f03c
,
/* str pc, [r2, #60] */
0xe12fff33
,
/* blx r3 */
0xe8bd8002
,
/* pop {r1, pc} */
NTSTATUS
(
*
func_ptr
)(
void
*
arg1
,
void
*
arg2
,
struct
expected
*
res
,
void
*
func
);
static
const
WORD
call_func
[]
=
{
0xb502
,
/* push {r1, lr} */
0xe882
,
0x1fff
,
/* stmia.w r2, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip} */
0xf8c2
,
0xd034
,
/* str.w sp, [r2, #52] */
0xf8c2
,
0xe038
,
/* str.w lr, [r2, #56] */
0xf3ef
,
0x8100
,
/* mrs r1, CPSR */
0xf041
,
0x0120
,
/* orr.w r1, r1, #32 */
0x6411
,
/* str r1, [r2, #64] */
0x9900
,
/* ldr r1, [sp, #0] */
0x4679
,
/* mov r1, pc */
0xf101
,
0x0109
,
/* add.w r1, r1, #9 */
0x63d1
,
/* str r1, [r2, #60] */
0x9900
,
/* ldr r1, [sp, #0] */
0x4798
,
/* blx r3 */
0xbd02
,
/* pop {r1, pc} */
};
memcpy
(
func_ptr
,
call_func
,
sizeof
(
call_func
)
);
memcpy
(
code_mem
,
call_func
,
sizeof
(
call_func
)
);
func_ptr
=
(
void
*
)((
char
*
)
code_mem
+
1
);
/* thumb */
#define COMPARE(reg) \
ok( context.reg == expect.reg, "wrong " #reg " %08x/%08x\n", context.reg, expect.reg )
...
...
@@ -4283,9 +4288,9 @@ static void test_thread_context(void)
context
.
R0
,
context
.
R1
,
context
.
R2
,
context
.
R3
,
context
.
R4
,
context
.
R5
,
context
.
R6
,
context
.
R7
,
context
.
R8
,
context
.
R9
,
context
.
R10
,
context
.
R11
,
context
.
R12
,
context
.
Sp
,
context
.
Lr
,
context
.
Pc
,
context
.
Cpsr
);
ok
(
context
.
ContextFlags
==
CONTEXT_FULL
,
ok
(
context
.
ContextFlags
==
(
CONTEXT_CONTROL
|
CONTEXT_INTEGER
|
CONTEXT_FLOATING_POINT
)
,
"wrong flags %08x
\n
"
,
context
.
ContextFlags
);
COMPARE
(
R0
);
ok
(
!
context
.
R0
,
"wrong R0 %08x
\n
"
,
context
.
R0
);
COMPARE
(
R1
);
COMPARE
(
R2
);
COMPARE
(
R3
);
...
...
@@ -4301,7 +4306,7 @@ static void test_thread_context(void)
COMPARE
(
Sp
);
COMPARE
(
Pc
);
COMPARE
(
Cpsr
);
ok
(
context
.
Lr
==
expect
.
Pc
,
"wrong Lr %08x/%08x
\n
"
,
context
.
Lr
,
expect
.
Pc
);
ok
(
!
context
.
Lr
,
"wrong Lr %08x
\n
"
,
context
.
Lr
);
memset
(
&
context
,
0xcc
,
sizeof
(
context
)
);
memset
(
&
expect
,
0xcc
,
sizeof
(
expect
)
);
...
...
@@ -4326,13 +4331,13 @@ static void test_thread_context(void)
COMPARE
(
R9
);
COMPARE
(
R10
);
COMPARE
(
R11
);
ok
(
(
context
.
Cpsr
&
0xff0f00
00
)
==
(
expect
.
Cpsr
&
0xff0f000
0
),
ok
(
(
context
.
Cpsr
&
0xff0f00
30
)
==
(
expect
.
Cpsr
&
0xff0f003
0
),
"wrong Cpsr %08x/%08x
\n
"
,
context
.
Cpsr
,
expect
.
Cpsr
);
ok
(
context
.
Sp
==
expect
.
Sp
-
8
,
"wrong Sp %08x/%08x
\n
"
,
context
.
Sp
,
expect
.
Sp
-
8
);
ok
(
context
.
Sp
==
expect
.
Sp
-
16
,
"wrong Sp %08x/%08x
\n
"
,
context
.
Sp
,
expect
.
Sp
-
16
);
/* Pc is somewhere close to the NtGetContextThread implementation */
ok
(
(
char
*
)
context
.
Pc
>=
(
char
*
)
pNtGetContextThread
-
0x40000
&&
(
char
*
)
context
.
Pc
<=
(
char
*
)
pNtGetContextThread
+
0x
4000
0
,
ok
(
(
char
*
)
context
.
Pc
>=
(
char
*
)
pNtGetContextThread
&&
(
char
*
)
context
.
Pc
<=
(
char
*
)
pNtGetContextThread
+
0x
1
0
,
"wrong Pc %08x/%08x
\n
"
,
context
.
Pc
,
(
DWORD
)
pNtGetContextThread
);
#undef COMPARE
}
...
...
@@ -4427,7 +4432,6 @@ static void test_debugger(DWORD cont_status)
}
else
{
#if 0 /* RtlRaiseException test disabled for now */
if
(
stage
==
1
)
{
ok
((
char
*
)
ctx
.
Pc
==
(
char
*
)
code_mem_address
+
0xb
,
"Pc at %x instead of %p
\n
"
,
...
...
@@ -4461,16 +4465,14 @@ static void test_debugger(DWORD cont_status)
ok
((
char
*
)
ctx
.
Pc
==
(
char
*
)
code_mem_address
+
0xa
,
"Pc at 0x%x instead of %p
\n
"
,
ctx
.
Pc
,
(
char
*
)
code_mem_address
+
0xa
);
/* need to fixup Pc for debuggee */
/*ctx.Pc += 2; */
ctx
.
Pc
+=
2
;
}
else
ok
((
char
*
)
ctx
.
Pc
==
(
char
*
)
code_mem_address
+
0xb
,
"Pc at 0x%x instead of %p
\n
"
,
ctx
.
Pc
,
(
char
*
)
code_mem_address
+
0xb
);
/* here we handle exception */
}
}
else
#endif
if
(
stage
==
7
||
stage
==
8
)
else
if
(
stage
==
7
||
stage
==
8
)
{
ok
(
de
.
u
.
Exception
.
ExceptionRecord
.
ExceptionCode
==
EXCEPTION_BREAKPOINT
,
"expected EXCEPTION_BREAKPOINT, got %08x
\n
"
,
de
.
u
.
Exception
.
ExceptionRecord
.
ExceptionCode
);
...
...
@@ -4482,8 +4484,8 @@ static void test_debugger(DWORD cont_status)
{
ok
(
de
.
u
.
Exception
.
ExceptionRecord
.
ExceptionCode
==
EXCEPTION_BREAKPOINT
,
"expected EXCEPTION_BREAKPOINT, got %08x
\n
"
,
de
.
u
.
Exception
.
ExceptionRecord
.
ExceptionCode
);
ok
((
char
*
)
ctx
.
Pc
==
(
char
*
)
code_mem_address
+
4
,
"expected Pc = %p, got 0x%x
\n
"
,
(
char
*
)
code_mem_address
+
4
,
ctx
.
Pc
);
ok
((
char
*
)
ctx
.
Pc
==
(
char
*
)
code_mem_address
+
3
,
"expected Pc = %p, got 0x%x
\n
"
,
(
char
*
)
code_mem_address
+
3
,
ctx
.
Pc
);
if
(
stage
==
10
)
continuestatus
=
DBG_EXCEPTION_NOT_HANDLED
;
}
else
if
(
stage
==
11
||
stage
==
12
||
stage
==
13
)
...
...
@@ -6307,12 +6309,13 @@ static LONG CALLBACK breakpoint_handler(EXCEPTION_POINTERS *ExceptionInfo)
"got ExceptionInformation[0] = %lx
\n
"
,
rec
->
ExceptionInformation
[
0
]);
ExceptionInfo
->
ContextRecord
->
Rip
=
(
DWORD_PTR
)
code_mem
+
2
;
#elif defined(__arm__)
ok
(
ExceptionInfo
->
ContextRecord
->
Pc
==
(
DWORD
)
code_mem
+
4
,
"expected pc = %
lx, got %lx
\n
"
,
(
DWORD
)
code_mem
+
4
,
ExceptionInfo
->
ContextRecord
->
Pc
);
ok
(
ExceptionInfo
->
ContextRecord
->
Pc
==
(
DWORD
)
code_mem
+
1
,
"expected pc = %
x, got %x
\n
"
,
(
DWORD
)
code_mem
+
1
,
ExceptionInfo
->
ContextRecord
->
Pc
);
ok
(
rec
->
NumberParameters
==
1
,
"ExceptionParameters is %d instead of 1
\n
"
,
rec
->
NumberParameters
);
ok
(
rec
->
ExceptionInformation
[
0
]
==
0
,
"got ExceptionInformation[0] = %lx
\n
"
,
rec
->
ExceptionInformation
[
0
]);
ExceptionInfo
->
ContextRecord
->
Pc
+=
2
;
#elif defined(__aarch64__)
ok
(
ExceptionInfo
->
ContextRecord
->
Pc
==
(
DWORD_PTR
)
code_mem
+
4
,
"expected pc = %lx, got %lx
\n
"
,
(
DWORD_PTR
)
code_mem
+
4
,
ExceptionInfo
->
ContextRecord
->
Pc
);
...
...
@@ -6329,7 +6332,7 @@ static LONG CALLBACK breakpoint_handler(EXCEPTION_POINTERS *ExceptionInfo)
#if defined(__i386__) || defined(__x86_64__)
static
const
BYTE
breakpoint_code
[]
=
{
0xcd
,
0x03
,
0xc3
};
/* int $0x3; ret */
#elif defined(__arm__)
static
const
DWORD
breakpoint_code
[]
=
{
0x
e1200070
,
0xe12fff1e
};
/* bkpt #0
; bx lr */
static
const
DWORD
breakpoint_code
[]
=
{
0x
defe
,
0x4770
};
/* udf #0xfe
; bx lr */
#elif defined(__aarch64__)
static
const
DWORD
breakpoint_code
[]
=
{
0xd4200000
,
0xd65f03c0
};
/* brk #0; ret */
#endif
...
...
@@ -6340,7 +6343,9 @@ static void test_breakpoint(DWORD numexc)
void
*
vectored_handler
;
memcpy
(
code_mem
,
breakpoint_code
,
sizeof
(
breakpoint_code
));
#ifdef __arm__
func
=
(
void
*
)((
char
*
)
code_mem
+
1
);
/* thumb */
#endif
vectored_handler
=
pRtlAddVectoredExceptionHandler
(
TRUE
,
&
breakpoint_handler
);
ok
(
vectored_handler
!=
0
,
"RtlAddVectoredExceptionHandler failed
\n
"
);
...
...
@@ -6421,8 +6426,6 @@ static LONG CALLBACK invalid_handle_vectored_handler(EXCEPTION_POINTERS *Excepti
static
void
test_closehandle
(
DWORD
numexc
,
HANDLE
handle
)
{
PVOID
vectored_handler
;
NTSTATUS
status
;
DWORD
res
;
if
(
!
pRtlAddVectoredExceptionHandler
||
!
pRtlRemoveVectoredExceptionHandler
||
!
pRtlRaiseException
)
{
...
...
@@ -6434,17 +6437,12 @@ static void test_closehandle(DWORD numexc, HANDLE handle)
ok
(
vectored_handler
!=
0
,
"RtlAddVectoredExceptionHandler failed
\n
"
);
invalid_handle_exceptions
=
0
;
res
=
CloseHandle
(
handle
);
ok
(
!
res
||
(
is_wow64
&&
res
),
"CloseHandle(%p) unexpectedly succeeded
\n
"
,
handle
);
ok
(
GetLastError
()
==
ERROR_INVALID_HANDLE
,
"wrong error code %d instead of %d
\n
"
,
GetLastError
(),
ERROR_INVALID_HANDLE
);
CloseHandle
(
handle
);
ok
(
invalid_handle_exceptions
==
numexc
,
"CloseHandle generated %d exceptions, expected %d
\n
"
,
invalid_handle_exceptions
,
numexc
);
invalid_handle_exceptions
=
0
;
status
=
pNtClose
(
handle
);
ok
(
status
==
STATUS_INVALID_HANDLE
||
(
is_wow64
&&
status
==
0
),
"NtClose(%p) returned status %08x
\n
"
,
handle
,
status
);
pNtClose
(
handle
);
ok
(
invalid_handle_exceptions
==
numexc
,
"NtClose generated %d exceptions, expected %d
\n
"
,
invalid_handle_exceptions
,
numexc
);
...
...
dlls/ntdll/unix/signal_arm.c
View file @
4e740387
...
...
@@ -390,7 +390,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
}
if
(
needed_flags
&
CONTEXT_CONTROL
)
{
context
->
Sp
=
(
DWORD
)
&
frame
->
r4
;
context
->
Sp
=
(
DWORD
)
(
frame
+
1
)
;
context
->
Lr
=
frame
->
thunk_addr
;
context
->
Pc
=
frame
->
thunk_addr
;
context
->
Cpsr
=
frame
->
cpsr
;
...
...
@@ -439,8 +439,6 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
rec
->
ExceptionAddress
=
(
void
*
)
PC_sig
(
sigcontext
);
save_context
(
&
context
,
sigcontext
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
.
Pc
+=
CPSR_sig
(
sigcontext
)
&
0x20
?
2
:
4
;
status
=
send_debug_event
(
rec
,
&
context
,
TRUE
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
...
...
@@ -599,6 +597,12 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
switch
(
get_trap_code
(
signal
,
context
))
{
case
TRAP_ARM_PRIVINFLT
:
/* Invalid opcode exception */
if
(
*
(
WORD
*
)
PC_sig
(
context
)
==
0xdefe
)
/* breakpoint */
{
rec
.
ExceptionCode
=
EXCEPTION_BREAKPOINT
;
rec
.
NumberParameters
=
1
;
break
;
}
rec
.
ExceptionCode
=
EXCEPTION_ILLEGAL_INSTRUCTION
;
break
;
case
TRAP_ARM_PAGEFLT
:
/* Page fault */
...
...
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