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
c5a57e7d
Commit
c5a57e7d
authored
Apr 30, 2009
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Move NtRaiseException and RtlUnwind implementations to the CPU-specific files.
parent
53169b98
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
574 additions
and
314 deletions
+574
-314
exception.c
dlls/ntdll/exception.c
+2
-313
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+2
-1
signal_i386.c
dlls/ntdll/signal_i386.c
+242
-0
signal_powerpc.c
dlls/ntdll/signal_powerpc.c
+101
-0
signal_sparc.c
dlls/ntdll/signal_sparc.c
+100
-0
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+127
-0
No files found.
dlls/ntdll/exception.c
View file @
c5a57e7d
...
...
@@ -40,13 +40,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
seh
);
/* Exception record for handling exceptions happening inside exception handlers */
typedef
struct
{
EXCEPTION_REGISTRATION_RECORD
frame
;
EXCEPTION_REGISTRATION_RECORD
*
prevFrame
;
}
EXC_NESTED_FRAME
;
typedef
struct
{
struct
list
entry
;
...
...
@@ -64,82 +57,6 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
};
static
RTL_CRITICAL_SECTION
vectored_handlers_section
=
{
&
critsect_debug
,
-
1
,
0
,
0
,
0
,
0
};
#ifdef __i386__
# define GET_IP(context) ((LPVOID)(context)->Eip)
#elif defined(__sparc__)
# define GET_IP(context) ((LPVOID)(context)->pc)
#elif defined(__powerpc__)
# define GET_IP(context) ((LPVOID)(context)->Iar)
#elif defined(__ALPHA__)
# define GET_IP(context) ((LPVOID)(context)->Fir)
#elif defined(__x86_64__)
# define GET_IP(context) ((LPVOID)(context)->Rip)
#else
# error You must define GET_IP for this CPU
#endif
/*******************************************************************
* EXC_RaiseHandler
*
* Handler for exceptions happening inside a handler.
*/
static
DWORD
EXC_RaiseHandler
(
EXCEPTION_RECORD
*
rec
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
)
{
if
(
rec
->
ExceptionFlags
&
(
EH_UNWINDING
|
EH_EXIT_UNWIND
))
return
ExceptionContinueSearch
;
/* We shouldn't get here so we store faulty frame in dispatcher */
*
dispatcher
=
((
EXC_NESTED_FRAME
*
)
frame
)
->
prevFrame
;
return
ExceptionNestedException
;
}
/*******************************************************************
* EXC_UnwindHandler
*
* Handler for exceptions happening inside an unwind handler.
*/
static
DWORD
EXC_UnwindHandler
(
EXCEPTION_RECORD
*
rec
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
)
{
if
(
!
(
rec
->
ExceptionFlags
&
(
EH_UNWINDING
|
EH_EXIT_UNWIND
)))
return
ExceptionContinueSearch
;
/* We shouldn't get here so we store faulty frame in dispatcher */
*
dispatcher
=
((
EXC_NESTED_FRAME
*
)
frame
)
->
prevFrame
;
return
ExceptionCollidedUnwind
;
}
/*******************************************************************
* EXC_CallHandler
*
* Call an exception handler, setting up an exception frame to catch exceptions
* happening during the handler execution.
*
* For i386 this function is implemented in assembler in signal_i386.c.
*/
#ifndef __i386__
static
DWORD
EXC_CallHandler
(
EXCEPTION_RECORD
*
record
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
,
PEXCEPTION_HANDLER
handler
,
PEXCEPTION_HANDLER
nested_handler
)
{
EXC_NESTED_FRAME
newframe
;
DWORD
ret
;
newframe
.
frame
.
Handler
=
nested_handler
;
newframe
.
prevFrame
=
frame
;
__wine_push_frame
(
&
newframe
.
frame
);
ret
=
handler
(
record
,
frame
,
context
,
dispatcher
);
__wine_pop_frame
(
&
newframe
.
frame
);
return
ret
;
}
#else
/* in signal_i386.c */
extern
DWORD
EXC_CallHandler
(
EXCEPTION_RECORD
*
record
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
,
PEXCEPTION_HANDLER
handler
,
PEXCEPTION_HANDLER
nested_handler
);
#endif
/**********************************************************************
* wait_suspend
*
...
...
@@ -187,7 +104,7 @@ void wait_suspend( CONTEXT *context )
*
* Send an EXCEPTION_DEBUG_EVENT event to the debugger.
*/
static
NTSTATUS
send_debug_event
(
EXCEPTION_RECORD
*
rec
,
int
first_chance
,
CONTEXT
*
context
)
NTSTATUS
send_debug_event
(
EXCEPTION_RECORD
*
rec
,
int
first_chance
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
DWORD
i
;
...
...
@@ -236,7 +153,7 @@ static NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTE
*
* Call the vectored handlers chain.
*/
static
LONG
call_vectored_handlers
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
LONG
call_vectored_handlers
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
struct
list
*
ptr
;
LONG
ret
=
EXCEPTION_CONTINUE_SEARCH
;
...
...
@@ -260,156 +177,6 @@ static LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
}
/**********************************************************************
* call_stack_handlers
*
* Call the stack handlers chain.
*/
static
NTSTATUS
call_stack_handlers
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
EXCEPTION_REGISTRATION_RECORD
*
frame
,
*
dispatch
,
*
nested_frame
;
DWORD
res
;
frame
=
NtCurrentTeb
()
->
Tib
.
ExceptionList
;
nested_frame
=
NULL
;
while
(
frame
!=
(
EXCEPTION_REGISTRATION_RECORD
*
)
~
0UL
)
{
/* Check frame address */
if
(((
void
*
)
frame
<
NtCurrentTeb
()
->
Tib
.
StackLimit
)
||
((
void
*
)(
frame
+
1
)
>
NtCurrentTeb
()
->
Tib
.
StackBase
)
||
(
ULONG_PTR
)
frame
&
3
)
{
rec
->
ExceptionFlags
|=
EH_STACK_INVALID
;
break
;
}
/* Call handler */
TRACE
(
"calling handler at %p code=%x flags=%x
\n
"
,
frame
->
Handler
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
);
res
=
EXC_CallHandler
(
rec
,
frame
,
context
,
&
dispatch
,
frame
->
Handler
,
EXC_RaiseHandler
);
TRACE
(
"handler at %p returned %x
\n
"
,
frame
->
Handler
,
res
);
if
(
frame
==
nested_frame
)
{
/* no longer nested */
nested_frame
=
NULL
;
rec
->
ExceptionFlags
&=
~
EH_NESTED_CALL
;
}
switch
(
res
)
{
case
ExceptionContinueExecution
:
if
(
!
(
rec
->
ExceptionFlags
&
EH_NONCONTINUABLE
))
return
STATUS_SUCCESS
;
return
STATUS_NONCONTINUABLE_EXCEPTION
;
case
ExceptionContinueSearch
:
break
;
case
ExceptionNestedException
:
if
(
nested_frame
<
dispatch
)
nested_frame
=
dispatch
;
rec
->
ExceptionFlags
|=
EH_NESTED_CALL
;
break
;
default:
return
STATUS_INVALID_DISPOSITION
;
}
frame
=
frame
->
Prev
;
}
return
STATUS_UNHANDLED_EXCEPTION
;
}
/*******************************************************************
* raise_exception
*
* Implementation of NtRaiseException.
*/
NTSTATUS
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
;
if
(
first_chance
)
{
DWORD
c
;
TRACE
(
"code=%x flags=%x addr=%p ip=%p tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
GET_IP
(
context
),
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
rec
->
NumberParameters
;
c
++
)
TRACE
(
" info[%d]=%08lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
else
{
#ifdef __i386__
TRACE
(
" eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x
\n
"
,
context
->
Eax
,
context
->
Ebx
,
context
->
Ecx
,
context
->
Edx
,
context
->
Esi
,
context
->
Edi
);
TRACE
(
" ebp=%08x esp=%08x cs=%04x ds=%04x es=%04x fs=%04x gs=%04x flags=%08x
\n
"
,
context
->
Ebp
,
context
->
Esp
,
context
->
SegCs
,
context
->
SegDs
,
context
->
SegEs
,
context
->
SegFs
,
context
->
SegGs
,
context
->
EFlags
);
#elif defined(__x86_64__)
TRACE
(
" rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx
\n
"
,
context
->
Rax
,
context
->
Rbx
,
context
->
Rcx
,
context
->
Rdx
);
TRACE
(
" rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx
\n
"
,
context
->
Rsi
,
context
->
Rdi
,
context
->
Rbp
,
context
->
Rsp
);
TRACE
(
" r8=%016lx r9=%016lx r10=%016lx r11=%016lx
\n
"
,
context
->
R8
,
context
->
R9
,
context
->
R10
,
context
->
R11
);
TRACE
(
" r12=%016lx r13=%016lx r14=%016lx r15=%016lx
\n
"
,
context
->
R12
,
context
->
R13
,
context
->
R14
,
context
->
R15
);
#endif
}
status
=
send_debug_event
(
rec
,
TRUE
,
context
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
return
STATUS_SUCCESS
;
#ifdef __i386__
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Eip
--
;
#endif
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
return
STATUS_SUCCESS
;
if
((
status
=
call_stack_handlers
(
rec
,
context
))
!=
STATUS_UNHANDLED_EXCEPTION
)
return
status
;
}
/* last chance exception */
status
=
send_debug_event
(
rec
,
FALSE
,
context
);
if
(
status
!=
DBG_CONTINUE
)
{
if
(
rec
->
ExceptionFlags
&
EH_STACK_INVALID
)
ERR
(
"Exception frame is not in stack limits => unable to dispatch exception.
\n
"
);
else
if
(
rec
->
ExceptionCode
==
STATUS_NONCONTINUABLE_EXCEPTION
)
ERR
(
"Process attempted to continue execution after noncontinuable exception.
\n
"
);
else
ERR
(
"Unhandled exception code %x flags %x addr %p
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
);
NtTerminateProcess
(
NtCurrentProcess
(),
1
);
}
return
STATUS_SUCCESS
;
}
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
=
raise_exception
(
rec
,
context
,
first_chance
);
if
(
status
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
return
status
;
}
/*******************************************************************
* raise_status
*
...
...
@@ -427,84 +194,6 @@ void raise_status( NTSTATUS status, EXCEPTION_RECORD *rec )
}
/*******************************************************************
* RtlUnwind (NTDLL.@)
*/
void
WINAPI
__regs_RtlUnwind
(
EXCEPTION_REGISTRATION_RECORD
*
pEndFrame
,
PVOID
unusedEip
,
PEXCEPTION_RECORD
pRecord
,
PVOID
returnEax
,
CONTEXT
*
context
)
{
EXCEPTION_RECORD
record
;
EXCEPTION_REGISTRATION_RECORD
*
frame
,
*
dispatch
;
DWORD
res
;
#ifdef __i386__
context
->
Eax
=
(
DWORD
)
returnEax
;
#endif
/* build an exception record, if we do not have one */
if
(
!
pRecord
)
{
record
.
ExceptionCode
=
STATUS_UNWIND
;
record
.
ExceptionFlags
=
0
;
record
.
ExceptionRecord
=
NULL
;
record
.
ExceptionAddress
=
GET_IP
(
context
);
record
.
NumberParameters
=
0
;
pRecord
=
&
record
;
}
pRecord
->
ExceptionFlags
|=
EH_UNWINDING
|
(
pEndFrame
?
0
:
EH_EXIT_UNWIND
);
TRACE
(
"code=%x flags=%x
\n
"
,
pRecord
->
ExceptionCode
,
pRecord
->
ExceptionFlags
);
/* get chain of exception frames */
frame
=
NtCurrentTeb
()
->
Tib
.
ExceptionList
;
while
((
frame
!=
(
EXCEPTION_REGISTRATION_RECORD
*
)
~
0UL
)
&&
(
frame
!=
pEndFrame
))
{
/* Check frame address */
if
(
pEndFrame
&&
(
frame
>
pEndFrame
))
raise_status
(
STATUS_INVALID_UNWIND_TARGET
,
pRecord
);
if
(((
void
*
)
frame
<
NtCurrentTeb
()
->
Tib
.
StackLimit
)
||
((
void
*
)(
frame
+
1
)
>
NtCurrentTeb
()
->
Tib
.
StackBase
)
||
(
UINT_PTR
)
frame
&
3
)
raise_status
(
STATUS_BAD_STACK
,
pRecord
);
/* Call handler */
TRACE
(
"calling handler at %p code=%x flags=%x
\n
"
,
frame
->
Handler
,
pRecord
->
ExceptionCode
,
pRecord
->
ExceptionFlags
);
res
=
EXC_CallHandler
(
pRecord
,
frame
,
context
,
&
dispatch
,
frame
->
Handler
,
EXC_UnwindHandler
);
TRACE
(
"handler at %p returned %x
\n
"
,
frame
->
Handler
,
res
);
switch
(
res
)
{
case
ExceptionContinueSearch
:
break
;
case
ExceptionCollidedUnwind
:
frame
=
dispatch
;
break
;
default:
raise_status
(
STATUS_INVALID_DISPOSITION
,
pRecord
);
break
;
}
frame
=
__wine_pop_frame
(
frame
);
}
}
/**********************************************************************/
#ifdef DEFINE_REGS_ENTRYPOINT
DEFINE_REGS_ENTRYPOINT
(
RtlUnwind
,
4
)
#else
void
WINAPI
RtlUnwind
(
PVOID
pEndFrame
,
PVOID
unusedEip
,
PEXCEPTION_RECORD
pRecord
,
PVOID
returnEax
)
{
CONTEXT
context
;
RtlCaptureContext
(
&
context
);
__regs_RtlUnwind
(
pEndFrame
,
unusedEip
,
pRecord
,
returnEax
,
&
context
);
}
#endif
/***********************************************************************
* RtlRaiseStatus (NTDLL.@)
*
...
...
dlls/ntdll/ntdll_misc.h
View file @
c5a57e7d
...
...
@@ -41,7 +41,8 @@ struct drive_info
/* exceptions */
extern
void
wait_suspend
(
CONTEXT
*
context
);
extern
NTSTATUS
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
);
extern
NTSTATUS
send_debug_event
(
EXCEPTION_RECORD
*
rec
,
int
first_chance
,
CONTEXT
*
context
);
extern
LONG
call_vectored_handlers
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
);
extern
void
raise_status
(
NTSTATUS
status
,
EXCEPTION_RECORD
*
rec
)
DECLSPEC_NORETURN
;
extern
void
set_cpu_context
(
const
CONTEXT
*
context
);
extern
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
DWORD
flags
);
...
...
dlls/ntdll/signal_i386.c
View file @
c5a57e7d
...
...
@@ -465,6 +465,16 @@ enum i386_trap_code
#endif
};
/* Exception record for handling exceptions happening inside exception handlers */
typedef
struct
{
EXCEPTION_REGISTRATION_RECORD
frame
;
EXCEPTION_REGISTRATION_RECORD
*
prevFrame
;
}
EXC_NESTED_FRAME
;
extern
DWORD
EXC_CallHandler
(
EXCEPTION_RECORD
*
record
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
,
PEXCEPTION_HANDLER
handler
,
PEXCEPTION_HANDLER
nested_handler
);
/***********************************************************************
* dispatch_signal
...
...
@@ -528,6 +538,164 @@ static inline TEB *get_current_teb(void)
}
/*******************************************************************
* raise_handler
*
* Handler for exceptions happening inside a handler.
*/
static
DWORD
raise_handler
(
EXCEPTION_RECORD
*
rec
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
)
{
if
(
rec
->
ExceptionFlags
&
(
EH_UNWINDING
|
EH_EXIT_UNWIND
))
return
ExceptionContinueSearch
;
/* We shouldn't get here so we store faulty frame in dispatcher */
*
dispatcher
=
((
EXC_NESTED_FRAME
*
)
frame
)
->
prevFrame
;
return
ExceptionNestedException
;
}
/*******************************************************************
* unwind_handler
*
* Handler for exceptions happening inside an unwind handler.
*/
static
DWORD
unwind_handler
(
EXCEPTION_RECORD
*
rec
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
)
{
if
(
!
(
rec
->
ExceptionFlags
&
(
EH_UNWINDING
|
EH_EXIT_UNWIND
)))
return
ExceptionContinueSearch
;
/* We shouldn't get here so we store faulty frame in dispatcher */
*
dispatcher
=
((
EXC_NESTED_FRAME
*
)
frame
)
->
prevFrame
;
return
ExceptionCollidedUnwind
;
}
/**********************************************************************
* call_stack_handlers
*
* Call the stack handlers chain.
*/
static
NTSTATUS
call_stack_handlers
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
EXCEPTION_REGISTRATION_RECORD
*
frame
,
*
dispatch
,
*
nested_frame
;
DWORD
res
;
frame
=
NtCurrentTeb
()
->
Tib
.
ExceptionList
;
nested_frame
=
NULL
;
while
(
frame
!=
(
EXCEPTION_REGISTRATION_RECORD
*
)
~
0UL
)
{
/* Check frame address */
if
(((
void
*
)
frame
<
NtCurrentTeb
()
->
Tib
.
StackLimit
)
||
((
void
*
)(
frame
+
1
)
>
NtCurrentTeb
()
->
Tib
.
StackBase
)
||
(
ULONG_PTR
)
frame
&
3
)
{
rec
->
ExceptionFlags
|=
EH_STACK_INVALID
;
break
;
}
/* Call handler */
TRACE
(
"calling handler at %p code=%x flags=%x
\n
"
,
frame
->
Handler
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
);
res
=
EXC_CallHandler
(
rec
,
frame
,
context
,
&
dispatch
,
frame
->
Handler
,
raise_handler
);
TRACE
(
"handler at %p returned %x
\n
"
,
frame
->
Handler
,
res
);
if
(
frame
==
nested_frame
)
{
/* no longer nested */
nested_frame
=
NULL
;
rec
->
ExceptionFlags
&=
~
EH_NESTED_CALL
;
}
switch
(
res
)
{
case
ExceptionContinueExecution
:
if
(
!
(
rec
->
ExceptionFlags
&
EH_NONCONTINUABLE
))
return
STATUS_SUCCESS
;
return
STATUS_NONCONTINUABLE_EXCEPTION
;
case
ExceptionContinueSearch
:
break
;
case
ExceptionNestedException
:
if
(
nested_frame
<
dispatch
)
nested_frame
=
dispatch
;
rec
->
ExceptionFlags
|=
EH_NESTED_CALL
;
break
;
default:
return
STATUS_INVALID_DISPOSITION
;
}
frame
=
frame
->
Prev
;
}
return
STATUS_UNHANDLED_EXCEPTION
;
}
/*******************************************************************
* raise_exception
*
* Implementation of NtRaiseException.
*/
static
NTSTATUS
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
;
if
(
first_chance
)
{
DWORD
c
;
TRACE
(
"code=%x flags=%x addr=%p ip=%08x tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
Eip
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
rec
->
NumberParameters
;
c
++
)
TRACE
(
" info[%d]=%08lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
else
{
TRACE
(
" eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x
\n
"
,
context
->
Eax
,
context
->
Ebx
,
context
->
Ecx
,
context
->
Edx
,
context
->
Esi
,
context
->
Edi
);
TRACE
(
" ebp=%08x esp=%08x cs=%04x ds=%04x es=%04x fs=%04x gs=%04x flags=%08x
\n
"
,
context
->
Ebp
,
context
->
Esp
,
context
->
SegCs
,
context
->
SegDs
,
context
->
SegEs
,
context
->
SegFs
,
context
->
SegGs
,
context
->
EFlags
);
}
status
=
send_debug_event
(
rec
,
TRUE
,
context
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
return
STATUS_SUCCESS
;
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Eip
--
;
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
return
STATUS_SUCCESS
;
if
((
status
=
call_stack_handlers
(
rec
,
context
))
!=
STATUS_UNHANDLED_EXCEPTION
)
return
status
;
}
/* last chance exception */
status
=
send_debug_event
(
rec
,
FALSE
,
context
);
if
(
status
!=
DBG_CONTINUE
)
{
if
(
rec
->
ExceptionFlags
&
EH_STACK_INVALID
)
WINE_ERR
(
"Exception frame is not in stack limits => unable to dispatch exception.
\n
"
);
else
if
(
rec
->
ExceptionCode
==
STATUS_NONCONTINUABLE_EXCEPTION
)
WINE_ERR
(
"Process attempted to continue execution after noncontinuable exception.
\n
"
);
else
WINE_ERR
(
"Unhandled exception code %x flags %x addr %p
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
);
NtTerminateProcess
(
NtCurrentProcess
(),
1
);
}
return
STATUS_SUCCESS
;
}
#ifdef __HAVE_VM86
/***********************************************************************
* save_vm86_context
...
...
@@ -2008,6 +2176,80 @@ void __wine_enter_vm86( CONTEXT *context )
#endif
/* __HAVE_VM86 */
/*******************************************************************
* RtlUnwind (NTDLL.@)
*/
void
WINAPI
__regs_RtlUnwind
(
EXCEPTION_REGISTRATION_RECORD
*
pEndFrame
,
PVOID
targetIp
,
PEXCEPTION_RECORD
pRecord
,
PVOID
retval
,
CONTEXT
*
context
)
{
EXCEPTION_RECORD
record
;
EXCEPTION_REGISTRATION_RECORD
*
frame
,
*
dispatch
;
DWORD
res
;
context
->
Eax
=
(
DWORD
)
retval
;
/* build an exception record, if we do not have one */
if
(
!
pRecord
)
{
record
.
ExceptionCode
=
STATUS_UNWIND
;
record
.
ExceptionFlags
=
0
;
record
.
ExceptionRecord
=
NULL
;
record
.
ExceptionAddress
=
(
void
*
)
context
->
Eip
;
record
.
NumberParameters
=
0
;
pRecord
=
&
record
;
}
pRecord
->
ExceptionFlags
|=
EH_UNWINDING
|
(
pEndFrame
?
0
:
EH_EXIT_UNWIND
);
TRACE
(
"code=%x flags=%x
\n
"
,
pRecord
->
ExceptionCode
,
pRecord
->
ExceptionFlags
);
/* get chain of exception frames */
frame
=
NtCurrentTeb
()
->
Tib
.
ExceptionList
;
while
((
frame
!=
(
EXCEPTION_REGISTRATION_RECORD
*
)
~
0UL
)
&&
(
frame
!=
pEndFrame
))
{
/* Check frame address */
if
(
pEndFrame
&&
(
frame
>
pEndFrame
))
raise_status
(
STATUS_INVALID_UNWIND_TARGET
,
pRecord
);
if
(((
void
*
)
frame
<
NtCurrentTeb
()
->
Tib
.
StackLimit
)
||
((
void
*
)(
frame
+
1
)
>
NtCurrentTeb
()
->
Tib
.
StackBase
)
||
(
UINT_PTR
)
frame
&
3
)
raise_status
(
STATUS_BAD_STACK
,
pRecord
);
/* Call handler */
TRACE
(
"calling handler at %p code=%x flags=%x
\n
"
,
frame
->
Handler
,
pRecord
->
ExceptionCode
,
pRecord
->
ExceptionFlags
);
res
=
EXC_CallHandler
(
pRecord
,
frame
,
context
,
&
dispatch
,
frame
->
Handler
,
unwind_handler
);
TRACE
(
"handler at %p returned %x
\n
"
,
frame
->
Handler
,
res
);
switch
(
res
)
{
case
ExceptionContinueSearch
:
break
;
case
ExceptionCollidedUnwind
:
frame
=
dispatch
;
break
;
default:
raise_status
(
STATUS_INVALID_DISPOSITION
,
pRecord
);
break
;
}
frame
=
__wine_pop_frame
(
frame
);
}
}
DEFINE_REGS_ENTRYPOINT
(
RtlUnwind
,
4
)
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
=
raise_exception
(
rec
,
context
,
first_chance
);
if
(
status
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
return
status
;
}
/***********************************************************************
* RtlRaiseException (NTDLL.@)
*/
...
...
dlls/ntdll/signal_powerpc.c
View file @
c5a57e7d
...
...
@@ -610,6 +610,89 @@ static inline DWORD get_fpu_code( const CONTEXT *context )
return
EXCEPTION_FLT_INVALID_OPERATION
;
/* generic error */
}
/**********************************************************************
* call_stack_handlers
*
* Call the stack handlers chain.
*/
static
NTSTATUS
call_stack_handlers
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
EXCEPTION_POINTERS
ptrs
;
FIXME
(
"not implemented on PowerPC
\n
"
);
/* hack: call unhandled exception filter directly */
ptrs
.
ExceptionRecord
=
rec
;
ptrs
.
ContextRecord
=
context
;
unhandled_exception_filter
(
&
ptrs
);
return
STATUS_UNHANDLED_EXCEPTION
;
}
/*******************************************************************
* raise_exception
*
* Implementation of NtRaiseException.
*/
static
NTSTATUS
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
;
if
(
first_chance
)
{
DWORD
c
;
TRACE
(
"code=%x flags=%x addr=%p ip=%x tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
Iar
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
rec
->
NumberParameters
;
c
++
)
TRACE
(
" info[%d]=%08lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
else
{
/* FIXME: dump context */
}
status
=
send_debug_event
(
rec
,
TRUE
,
context
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
return
STATUS_SUCCESS
;
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
return
STATUS_SUCCESS
;
if
((
status
=
call_stack_handlers
(
rec
,
context
))
!=
STATUS_UNHANDLED_EXCEPTION
)
return
status
;
}
/* last chance exception */
status
=
send_debug_event
(
rec
,
FALSE
,
context
);
if
(
status
!=
DBG_CONTINUE
)
{
if
(
rec
->
ExceptionFlags
&
EH_STACK_INVALID
)
ERR
(
"Exception frame is not in stack limits => unable to dispatch exception.
\n
"
);
else
if
(
rec
->
ExceptionCode
==
STATUS_NONCONTINUABLE_EXCEPTION
)
ERR
(
"Process attempted to continue execution after noncontinuable exception.
\n
"
);
else
ERR
(
"Unhandled exception code %x flags %x addr %p
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
);
NtTerminateProcess
(
NtCurrentProcess
(),
1
);
}
return
STATUS_SUCCESS
;
}
/**********************************************************************
* do_segv
*
...
...
@@ -1002,6 +1085,24 @@ void __wine_enter_vm86( CONTEXT *context )
}
/***********************************************************************
* RtlUnwind (NTDLL.@)
*/
void
WINAPI
RtlUnwind
(
PVOID
pEndFrame
,
PVOID
targetIp
,
PEXCEPTION_RECORD
pRecord
,
PVOID
retval
)
{
FIXME
(
"Not implemented on PowerPC
\n
"
);
}
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
=
raise_exception
(
rec
,
context
,
first_chance
);
if
(
status
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
return
status
;
}
/***********************************************************************
* RtlRaiseException (NTDLL.@)
*/
void
WINAPI
RtlRaiseException
(
EXCEPTION_RECORD
*
rec
)
...
...
dlls/ntdll/signal_sparc.c
View file @
c5a57e7d
...
...
@@ -152,6 +152,88 @@ static void restore_fpu( CONTEXT *context, ucontext_t *ucontext )
}
/**********************************************************************
* call_stack_handlers
*
* Call the stack handlers chain.
*/
static
NTSTATUS
call_stack_handlers
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
EXCEPTION_POINTERS
ptrs
;
FIXME
(
"not implemented on Sparc
\n
"
);
/* hack: call unhandled exception filter directly */
ptrs
.
ExceptionRecord
=
rec
;
ptrs
.
ContextRecord
=
context
;
unhandled_exception_filter
(
&
ptrs
);
return
STATUS_UNHANDLED_EXCEPTION
;
}
/*******************************************************************
* raise_exception
*
* Implementation of NtRaiseException.
*/
static
NTSTATUS
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
;
if
(
first_chance
)
{
DWORD
c
;
TRACE
(
"code=%x flags=%x addr=%p ip=%x tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
pc
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
rec
->
NumberParameters
;
c
++
)
TRACE
(
" info[%d]=%08lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
else
{
/* FIXME: dump context */
}
status
=
send_debug_event
(
rec
,
TRUE
,
context
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
return
STATUS_SUCCESS
;
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
return
STATUS_SUCCESS
;
if
((
status
=
call_stack_handlers
(
rec
,
context
))
!=
STATUS_UNHANDLED_EXCEPTION
)
return
status
;
}
/* last chance exception */
status
=
send_debug_event
(
rec
,
FALSE
,
context
);
if
(
status
!=
DBG_CONTINUE
)
{
if
(
rec
->
ExceptionFlags
&
EH_STACK_INVALID
)
ERR
(
"Exception frame is not in stack limits => unable to dispatch exception.
\n
"
);
else
if
(
rec
->
ExceptionCode
==
STATUS_NONCONTINUABLE_EXCEPTION
)
ERR
(
"Process attempted to continue execution after noncontinuable exception.
\n
"
);
else
ERR
(
"Unhandled exception code %x flags %x addr %p
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
);
NtTerminateProcess
(
NtCurrentProcess
(),
1
);
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* RtlCaptureContext (NTDLL.@)
*/
...
...
@@ -716,6 +798,24 @@ void __wine_enter_vm86( CONTEXT *context )
}
/***********************************************************************
* RtlUnwind (NTDLL.@)
*/
void
WINAPI
RtlUnwind
(
PVOID
pEndFrame
,
PVOID
targetIp
,
PEXCEPTION_RECORD
pRecord
,
PVOID
retval
)
{
FIXME
(
"Not implemented on Sparc
\n
"
);
}
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
=
raise_exception
(
rec
,
context
,
first_chance
);
if
(
status
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
return
status
;
}
/***********************************************************************
* RtlRaiseException (NTDLL.@)
*/
void
WINAPI
RtlRaiseException
(
EXCEPTION_RECORD
*
rec
)
...
...
dlls/ntdll/signal_x86_64.c
View file @
c5a57e7d
...
...
@@ -470,6 +470,94 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
/**********************************************************************
* call_stack_handlers
*
* Call the stack handlers chain.
*/
static
NTSTATUS
call_stack_handlers
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
EXCEPTION_POINTERS
ptrs
;
FIXME
(
"not implemented on x86_64
\n
"
);
/* hack: call unhandled exception filter directly */
ptrs
.
ExceptionRecord
=
rec
;
ptrs
.
ContextRecord
=
context
;
unhandled_exception_filter
(
&
ptrs
);
return
STATUS_UNHANDLED_EXCEPTION
;
}
/*******************************************************************
* raise_exception
*
* Implementation of NtRaiseException.
*/
static
NTSTATUS
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
;
if
(
first_chance
)
{
DWORD
c
;
TRACE
(
"code=%x flags=%x addr=%p ip=%lx tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
Rip
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
rec
->
NumberParameters
;
c
++
)
TRACE
(
" info[%d]=%08lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
else
{
TRACE
(
" rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx
\n
"
,
context
->
Rax
,
context
->
Rbx
,
context
->
Rcx
,
context
->
Rdx
);
TRACE
(
" rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx
\n
"
,
context
->
Rsi
,
context
->
Rdi
,
context
->
Rbp
,
context
->
Rsp
);
TRACE
(
" r8=%016lx r9=%016lx r10=%016lx r11=%016lx
\n
"
,
context
->
R8
,
context
->
R9
,
context
->
R10
,
context
->
R11
);
TRACE
(
" r12=%016lx r13=%016lx r14=%016lx r15=%016lx
\n
"
,
context
->
R12
,
context
->
R13
,
context
->
R14
,
context
->
R15
);
}
status
=
send_debug_event
(
rec
,
TRUE
,
context
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
return
STATUS_SUCCESS
;
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
return
STATUS_SUCCESS
;
if
((
status
=
call_stack_handlers
(
rec
,
context
))
!=
STATUS_UNHANDLED_EXCEPTION
)
return
status
;
}
/* last chance exception */
status
=
send_debug_event
(
rec
,
FALSE
,
context
);
if
(
status
!=
DBG_CONTINUE
)
{
if
(
rec
->
ExceptionFlags
&
EH_STACK_INVALID
)
ERR
(
"Exception frame is not in stack limits => unable to dispatch exception.
\n
"
);
else
if
(
rec
->
ExceptionCode
==
STATUS_NONCONTINUABLE_EXCEPTION
)
ERR
(
"Process attempted to continue execution after noncontinuable exception.
\n
"
);
else
ERR
(
"Unhandled exception code %x flags %x addr %p
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
);
NtTerminateProcess
(
NtCurrentProcess
(),
rec
->
ExceptionCode
);
}
return
STATUS_SUCCESS
;
}
/**********************************************************************
* segv_handler
*
* Handler for SIGSEGV and related errors.
...
...
@@ -804,6 +892,45 @@ PVOID WINAPI RtlVirtualUnwind ( ULONG type, ULONG64 base, ULONG64 pc,
}
/*******************************************************************
* RtlUnwind (NTDLL.@)
*/
void
WINAPI
__regs_RtlUnwind
(
EXCEPTION_REGISTRATION_RECORD
*
pEndFrame
,
PVOID
targetIp
,
PEXCEPTION_RECORD
pRecord
,
PVOID
retval
,
CONTEXT
*
context
)
{
EXCEPTION_RECORD
record
;
/* build an exception record, if we do not have one */
if
(
!
pRecord
)
{
record
.
ExceptionCode
=
STATUS_UNWIND
;
record
.
ExceptionFlags
=
0
;
record
.
ExceptionRecord
=
NULL
;
record
.
ExceptionAddress
=
(
void
*
)
context
->
Rip
;
record
.
NumberParameters
=
0
;
pRecord
=
&
record
;
}
pRecord
->
ExceptionFlags
|=
EH_UNWINDING
|
(
pEndFrame
?
0
:
EH_EXIT_UNWIND
);
FIXME
(
"code=%x flags=%x not implemented on x86_64
\n
"
,
pRecord
->
ExceptionCode
,
pRecord
->
ExceptionFlags
);
NtTerminateProcess
(
GetCurrentProcess
(),
1
);
}
DEFINE_REGS_ENTRYPOINT
(
RtlUnwind
,
4
)
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
=
raise_exception
(
rec
,
context
,
first_chance
);
if
(
status
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
return
status
;
}
/***********************************************************************
* RtlRaiseException (NTDLL.@)
*/
...
...
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