Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
de1d35ea
Commit
de1d35ea
authored
Jun 20, 2011
by
André Hentschel
Committed by
Alexandre Julliard
Jun 21, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Improved implementation of the segv handler on ARM.
parent
71ae4774
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
131 additions
and
24 deletions
+131
-24
signal_arm.c
dlls/ntdll/signal_arm.c
+131
-24
No files found.
dlls/ntdll/signal_arm.c
View file @
de1d35ea
...
...
@@ -66,6 +66,8 @@ static pthread_key_t teb_key;
*/
#ifdef linux
typedef
ucontext_t
SIGCONTEXT
;
/* All Registers access - only for local access */
# define REG_sig(reg_name, context) ((context)->uc_mcontext.reg_name)
# define REGn_sig(reg_num, context) ((context)->uc_mcontext.arm_r##reg_num)
...
...
@@ -75,11 +77,25 @@ static pthread_key_t teb_key;
# define LR_sig(context) REG_sig(arm_lr, context)
/* Link register */
# define PC_sig(context) REG_sig(arm_pc, context)
/* Program counter */
# define CPSR_sig(context) REG_sig(arm_cpsr, context)
/* Current State Register */
# define IP_sig(context) REG_sig(arm_ip, context)
/*
Program counter (2?)
*/
# define IP_sig(context) REG_sig(arm_ip, context)
/*
Intra-Procedure-call scratch register
*/
# define FP_sig(context) REG_sig(arm_fp, context)
/* Frame pointer */
/* Exceptions */
# define ERROR_sig(context) REG_sig(error_code, context)
# define FAULT_sig(context) REG_sig(fault_address, context)
# define TRAP_sig(context) REG_sig(trap_no, context)
#endif
/* linux */
enum
arm_trap_code
{
TRAP_ARM_UNKNOWN
=
-
1
,
/* Unknown fault (TRAP_sig not defined) */
TRAP_ARM_PRIVINFLT
=
6
,
/* Invalid opcode exception */
TRAP_ARM_PAGEFLT
=
14
,
/* Page fault */
TRAP_ARM_ALIGNFLT
=
17
,
/* Alignment check exception */
};
typedef
void
(
WINAPI
*
raise_func
)(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
);
typedef
int
(
*
wine_signal_handler
)(
unsigned
int
sig
);
static
wine_signal_handler
handlers
[
256
];
...
...
@@ -206,11 +222,25 @@ __ASM_STDCALL_FUNC( RtlCaptureContext, 4,
*
* Set the new CPU context.
*/
void
set_cpu_context
(
const
CONTEXT
*
context
)
{
FIXME
(
"not implemented
\n
"
);
return
;
}
/* FIXME: What about the CPSR? */
__ASM_GLOBAL_FUNC
(
set_cpu_context
,
"mov IP, r0
\n\t
"
"ldr r0, [IP, #0x4]
\n\t
"
/* context->R0 */
"ldr r1, [IP, #0x8]
\n\t
"
/* context->R1 */
"ldr r2, [IP, #0xc]
\n\t
"
/* context->R2 */
"ldr r3, [IP, #0x10]
\n\t
"
/* context->R3 */
"ldr r4, [IP, #0x14]
\n\t
"
/* context->R4 */
"ldr r5, [IP, #0x18]
\n\t
"
/* context->R5 */
"ldr r6, [IP, #0x1c]
\n\t
"
/* context->R6 */
"ldr r7, [IP, #0x20]
\n\t
"
/* context->R7 */
"ldr r8, [IP, #0x24]
\n\t
"
/* context->R8 */
"ldr r9, [IP, #0x28]
\n\t
"
/* context->R9 */
"ldr r10, [IP, #0x2c]
\n\t
"
/* context->R10 */
"ldr r11, [IP, #0x30]
\n\t
"
/* context->Fp */
"ldr SP, [IP, #0x38]
\n\t
"
/* context->Sp */
"ldr LR, [IP, #0x3c]
\n\t
"
/* context->Lr */
"ldr PC, [IP, #0x40]
\n\t
"
/* context->Pc */
)
/***********************************************************************
...
...
@@ -326,6 +356,63 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
return
STATUS_SUCCESS
;
}
/***********************************************************************
* setup_exception_record
*
* Setup the exception record and context on the thread stack.
*/
static
EXCEPTION_RECORD
*
setup_exception_record
(
SIGCONTEXT
*
sigcontext
,
void
*
stack_ptr
,
raise_func
func
)
{
struct
stack_layout
{
CONTEXT
context
;
EXCEPTION_RECORD
rec
;
}
*
stack
=
stack_ptr
;
DWORD
exception_code
=
0
;
stack
--
;
/* push the stack_layout structure */
stack
->
rec
.
ExceptionRecord
=
NULL
;
stack
->
rec
.
ExceptionCode
=
exception_code
;
stack
->
rec
.
ExceptionFlags
=
EXCEPTION_CONTINUABLE
;
stack
->
rec
.
ExceptionAddress
=
(
LPVOID
)
PC_sig
(
sigcontext
);
stack
->
rec
.
NumberParameters
=
0
;
save_context
(
&
stack
->
context
,
sigcontext
);
/* now modify the sigcontext to return to the raise function */
SP_sig
(
sigcontext
)
=
(
DWORD
)
stack
;
PC_sig
(
sigcontext
)
=
(
DWORD
)
func
;
REGn_sig
(
0
,
sigcontext
)
=
(
DWORD
)
&
stack
->
rec
;
/* first arg for raise_func */
REGn_sig
(
1
,
sigcontext
)
=
(
DWORD
)
&
stack
->
context
;
/* second arg for raise_func */
return
&
stack
->
rec
;
}
/**********************************************************************
* raise_segv_exception
*/
static
void
WINAPI
raise_segv_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
NTSTATUS
status
;
switch
(
rec
->
ExceptionCode
)
{
case
EXCEPTION_ACCESS_VIOLATION
:
if
(
rec
->
NumberParameters
==
2
)
{
if
(
!
(
rec
->
ExceptionCode
=
virtual_handle_fault
(
(
void
*
)
rec
->
ExceptionInformation
[
1
],
rec
->
ExceptionInformation
[
0
]
)))
goto
done
;
}
break
;
}
status
=
NtRaiseException
(
rec
,
context
,
TRUE
);
if
(
status
)
raise_status
(
status
,
rec
);
done
:
set_cpu_context
(
context
);
}
/**********************************************************************
* call_stack_handlers
...
...
@@ -453,27 +540,47 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
*/
static
void
segv_handler
(
int
signal
,
siginfo_t
*
info
,
void
*
ucontext
)
{
EXCEPTION_RECORD
rec
;
CONTEXT
context
;
NTSTATUS
status
;
EXCEPTION_RECORD
*
rec
;
SIGCONTEXT
*
context
=
u
context
;
void
*
stack
=
(
void
*
)
(
SP_sig
(
context
)
&
~
3
)
;
rec
.
ExceptionCode
=
EXCEPTION_ACCESS_VIOLATION
;
/* check for page fault inside the thread stack */
if
(
TRAP_sig
(
context
)
==
TRAP_ARM_PAGEFLT
&&
(
char
*
)
info
->
si_addr
>=
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
&&
(
char
*
)
info
->
si_addr
<
(
char
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
&&
virtual_handle_stack_fault
(
info
->
si_addr
))
{
/* check if this was the last guard page */
if
((
char
*
)
info
->
si_addr
<
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
+
2
*
4096
)
{
rec
=
setup_exception_record
(
context
,
stack
,
raise_segv_exception
);
rec
->
ExceptionCode
=
EXCEPTION_STACK_OVERFLOW
;
}
return
;
}
/* we want the page-fault case to be fast */
if
(
info
->
si_code
==
SEGV_ACCERR
)
if
(
!
(
rec
.
ExceptionCode
=
virtual_handle_fault
(
info
->
si_addr
,
0
)))
return
;
rec
=
setup_exception_record
(
context
,
stack
,
raise_segv_exception
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_STACK_OVERFLOW
)
return
;
save_context
(
&
context
,
ucontext
);
rec
.
ExceptionRecord
=
NULL
;
rec
.
ExceptionFlags
=
EXCEPTION_CONTINUABLE
;
rec
.
ExceptionAddress
=
(
LPVOID
)
context
.
Pc
;
rec
.
NumberParameters
=
2
;
rec
.
ExceptionInformation
[
0
]
=
0
;
/* FIXME: read/write access ? */
rec
.
ExceptionInformation
[
1
]
=
(
ULONG_PTR
)
info
->
si_addr
;
status
=
raise_exception
(
&
rec
,
&
context
,
TRUE
);
if
(
status
)
raise_status
(
status
,
&
rec
);
restore_context
(
&
context
,
ucontext
);
switch
(
TRAP_sig
(
context
))
{
case
TRAP_ARM_PRIVINFLT
:
/* Invalid opcode exception */
rec
->
ExceptionCode
=
EXCEPTION_ILLEGAL_INSTRUCTION
;
break
;
case
TRAP_ARM_PAGEFLT
:
/* Page fault */
rec
->
ExceptionCode
=
EXCEPTION_ACCESS_VIOLATION
;
rec
->
NumberParameters
=
2
;
rec
->
ExceptionInformation
[
0
]
=
(
ERROR_sig
(
context
)
&
0x800
)
!=
0
;
rec
->
ExceptionInformation
[
1
]
=
(
ULONG_PTR
)
info
->
si_addr
;
break
;
case
TRAP_ARM_ALIGNFLT
:
/* Alignment check exception */
rec
->
ExceptionCode
=
EXCEPTION_DATATYPE_MISALIGNMENT
;
break
;
default
:
WINE_ERR
(
"Got unexpected trap %ld
\n
"
,
TRAP_sig
(
context
)
);
rec
->
ExceptionCode
=
EXCEPTION_ILLEGAL_INSTRUCTION
;
break
;
}
}
/**********************************************************************
...
...
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