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
f704b80a
Commit
f704b80a
authored
Jan 29, 2024
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Use a .seh handler for the unwind exception handler.
parent
658a0665
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
88 additions
and
59 deletions
+88
-59
signal_arm.c
dlls/ntdll/signal_arm.c
+50
-27
signal_arm64.c
dlls/ntdll/signal_arm64.c
+36
-30
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+2
-2
No files found.
dlls/ntdll/signal_arm.c
View file @
f704b80a
...
@@ -205,58 +205,81 @@ static NTSTATUS virtual_unwind( ULONG type, DISPATCHER_CONTEXT *dispatch, CONTEX
...
@@ -205,58 +205,81 @@ static NTSTATUS virtual_unwind( ULONG type, DISPATCHER_CONTEXT *dispatch, CONTEX
}
}
struct
unwind_exception_frame
{
EXCEPTION_REGISTRATION_RECORD
frame
;
DISPATCHER_CONTEXT
*
dispatch
;
};
/**********************************************************************
/**********************************************************************
* unwind_exception_handler
* unwind_exception_handler
*
*
* Handler for exceptions happening while calling an unwind handler.
* Handler for exceptions happening while calling an unwind handler.
*/
*/
static
DWORD
__cdecl
unwind_exception_handler
(
EXCEPTION_RECORD
*
rec
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
EXCEPTION_DISPOSITION
WINAPI
unwind_exception_handler
(
EXCEPTION_RECORD
*
record
,
void
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
)
CONTEXT
*
context
,
DISPATCHER_CONTEXT
*
dispatch
)
{
{
struct
unwind_exception_frame
*
unwind_frame
=
(
struct
unwind_exception_frame
*
)
frame
;
DISPATCHER_CONTEXT
*
orig_dispatch
=
((
DISPATCHER_CONTEXT
**
)
frame
)[
-
2
];
DISPATCHER_CONTEXT
*
dispatch
=
(
DISPATCHER_CONTEXT
*
)
dispatcher
;
/* copy the original dispatcher into the current one, except for the TargetIp */
/* copy the original dispatcher into the current one, except for the TargetIp */
dispatch
->
ControlPc
=
unwind_frame
->
dispatch
->
ControlPc
;
dispatch
->
ControlPc
=
orig_
dispatch
->
ControlPc
;
dispatch
->
ImageBase
=
unwind_frame
->
dispatch
->
ImageBase
;
dispatch
->
ImageBase
=
orig_
dispatch
->
ImageBase
;
dispatch
->
FunctionEntry
=
unwind_frame
->
dispatch
->
FunctionEntry
;
dispatch
->
FunctionEntry
=
orig_
dispatch
->
FunctionEntry
;
dispatch
->
EstablisherFrame
=
unwind_frame
->
dispatch
->
EstablisherFrame
;
dispatch
->
EstablisherFrame
=
orig_
dispatch
->
EstablisherFrame
;
dispatch
->
ContextRecord
=
unwind_frame
->
dispatch
->
ContextRecord
;
dispatch
->
ContextRecord
=
orig_
dispatch
->
ContextRecord
;
dispatch
->
LanguageHandler
=
unwind_frame
->
dispatch
->
LanguageHandler
;
dispatch
->
LanguageHandler
=
orig_
dispatch
->
LanguageHandler
;
dispatch
->
HandlerData
=
unwind_frame
->
dispatch
->
HandlerData
;
dispatch
->
HandlerData
=
orig_
dispatch
->
HandlerData
;
dispatch
->
HistoryTable
=
unwind_frame
->
dispatch
->
HistoryTable
;
dispatch
->
HistoryTable
=
orig_
dispatch
->
HistoryTable
;
dispatch
->
ScopeIndex
=
unwind_frame
->
dispatch
->
ScopeIndex
;
dispatch
->
ScopeIndex
=
orig_
dispatch
->
ScopeIndex
;
TRACE
(
"detected collided unwind
\n
"
);
TRACE
(
"detected collided unwind
\n
"
);
return
ExceptionCollidedUnwind
;
return
ExceptionCollidedUnwind
;
}
}
/**********************************************************************
/**********************************************************************
* unwind_handler_wrapper
*/
#ifdef __WINE_PE_BUILD
extern
DWORD
WINAPI
unwind_handler_wrapper
(
EXCEPTION_RECORD
*
rec
,
DISPATCHER_CONTEXT
*
dispatch
);
__ASM_GLOBAL_FUNC
(
unwind_handler_wrapper
,
"push {r1,lr}
\n\t
"
".seh_save_regs {r1,lr}
\n\t
"
".seh_endprologue
\n\t
"
".seh_handler "
__ASM_NAME
(
"unwind_exception_handler"
)
", %except, %unwind
\n\t
"
"mov r3, r1
\n\t
"
/* dispatch */
"ldr r1, [r3, #0x0c]
\n\t
"
/* dispatch->EstablisherFrame */
"ldr r2, [r3, #0x14]
\n\t
"
/* dispatch->ContextRecord */
"ldr ip, [r3, #0x18]
\n\t
"
/* dispatch->LanguageHandler */
"blx ip
\n\t
"
"pop {r1,pc}
\n\t
"
)
#else
static
DWORD
unwind_handler_wrapper
(
EXCEPTION_RECORD
*
rec
,
DISPATCHER_CONTEXT
*
dispatch
)
{
struct
{
DISPATCHER_CONTEXT
*
dispatch
;
ULONG
lr
;
EXCEPTION_REGISTRATION_RECORD
frame
;
}
frame
;
DWORD
res
;
frame
.
frame
.
Handler
=
(
PEXCEPTION_HANDLER
)
unwind_exception_handler
;
frame
.
dispatch
=
dispatch
;
__wine_push_frame
(
&
frame
.
frame
);
res
=
dispatch
->
LanguageHandler
(
rec
,
(
void
*
)
dispatch
->
EstablisherFrame
,
dispatch
->
ContextRecord
,
dispatch
);
__wine_pop_frame
(
&
frame
.
frame
);
return
res
;
}
#endif
/**********************************************************************
* call_unwind_handler
* call_unwind_handler
*
*
* Call a single unwind handler.
* Call a single unwind handler.
*/
*/
static
DWORD
call_unwind_handler
(
EXCEPTION_RECORD
*
rec
,
DISPATCHER_CONTEXT
*
dispatch
)
static
DWORD
call_unwind_handler
(
EXCEPTION_RECORD
*
rec
,
DISPATCHER_CONTEXT
*
dispatch
)
{
{
struct
unwind_exception_frame
frame
;
DWORD
res
;
DWORD
res
;
frame
.
frame
.
Handler
=
unwind_exception_handler
;
frame
.
dispatch
=
dispatch
;
__wine_push_frame
(
&
frame
.
frame
);
TRACE
(
"calling handler %p (rec=%p, frame=0x%lx context=%p, dispatch=%p)
\n
"
,
TRACE
(
"calling handler %p (rec=%p, frame=0x%lx context=%p, dispatch=%p)
\n
"
,
dispatch
->
LanguageHandler
,
rec
,
dispatch
->
EstablisherFrame
,
dispatch
->
ContextRecord
,
dispatch
);
dispatch
->
LanguageHandler
,
rec
,
dispatch
->
EstablisherFrame
,
dispatch
->
ContextRecord
,
dispatch
);
res
=
dispatch
->
LanguageHandler
(
rec
,
(
void
*
)
dispatch
->
EstablisherFrame
,
dispatch
->
ContextRecord
,
dispatch
);
res
=
unwind_handler_wrapper
(
rec
,
dispatch
);
TRACE
(
"handler %p returned %lx
\n
"
,
dispatch
->
LanguageHandler
,
res
);
TRACE
(
"handler %p returned %lx
\n
"
,
dispatch
->
LanguageHandler
,
res
);
__wine_pop_frame
(
&
frame
.
frame
);
switch
(
res
)
switch
(
res
)
{
{
case
ExceptionContinueSearch
:
case
ExceptionContinueSearch
:
...
...
dlls/ntdll/signal_arm64.c
View file @
f704b80a
...
@@ -206,58 +206,64 @@ static NTSTATUS virtual_unwind( ULONG type, DISPATCHER_CONTEXT *dispatch, CONTEX
...
@@ -206,58 +206,64 @@ static NTSTATUS virtual_unwind( ULONG type, DISPATCHER_CONTEXT *dispatch, CONTEX
}
}
struct
unwind_exception_frame
{
EXCEPTION_REGISTRATION_RECORD
frame
;
DISPATCHER_CONTEXT
*
dispatch
;
};
/**********************************************************************
/**********************************************************************
* unwind_exception_handler
* unwind_exception_handler
*
*
* Handler for exceptions happening while calling an unwind handler.
* Handler for exceptions happening while calling an unwind handler.
*/
*/
static
DWORD
__cdecl
unwind_exception_handler
(
EXCEPTION_RECORD
*
rec
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
EXCEPTION_DISPOSITION
WINAPI
unwind_exception_handler
(
EXCEPTION_RECORD
*
record
,
void
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
)
CONTEXT
*
context
,
DISPATCHER_CONTEXT
*
dispatch
)
{
{
struct
unwind_exception_frame
*
unwind_frame
=
(
struct
unwind_exception_frame
*
)
frame
;
DISPATCHER_CONTEXT
*
orig_dispatch
=
((
DISPATCHER_CONTEXT
**
)
frame
)[
-
2
];
DISPATCHER_CONTEXT
*
dispatch
=
(
DISPATCHER_CONTEXT
*
)
dispatcher
;
/* copy the original dispatcher into the current one, except for the TargetPc */
/* copy the original dispatcher into the current one, except for the TargetIp */
dispatch
->
ControlPc
=
orig_dispatch
->
ControlPc
;
dispatch
->
ControlPc
=
unwind_frame
->
dispatch
->
ControlPc
;
dispatch
->
ImageBase
=
orig_dispatch
->
ImageBase
;
dispatch
->
ImageBase
=
unwind_frame
->
dispatch
->
ImageBase
;
dispatch
->
FunctionEntry
=
orig_dispatch
->
FunctionEntry
;
dispatch
->
FunctionEntry
=
unwind_frame
->
dispatch
->
FunctionEntry
;
dispatch
->
EstablisherFrame
=
orig_dispatch
->
EstablisherFrame
;
dispatch
->
EstablisherFrame
=
unwind_frame
->
dispatch
->
EstablisherFrame
;
dispatch
->
ContextRecord
=
orig_dispatch
->
ContextRecord
;
dispatch
->
ContextRecord
=
unwind_frame
->
dispatch
->
ContextRecord
;
dispatch
->
LanguageHandler
=
orig_dispatch
->
LanguageHandler
;
dispatch
->
LanguageHandler
=
unwind_frame
->
dispatch
->
LanguageHandler
;
dispatch
->
HandlerData
=
orig_dispatch
->
HandlerData
;
dispatch
->
HandlerData
=
unwind_frame
->
dispatch
->
HandlerData
;
dispatch
->
HistoryTable
=
orig_dispatch
->
HistoryTable
;
dispatch
->
HistoryTable
=
unwind_frame
->
dispatch
->
HistoryTable
;
dispatch
->
ScopeIndex
=
orig_dispatch
->
ScopeIndex
;
dispatch
->
ScopeIndex
=
unwind_frame
->
dispatch
->
ScopeIndex
;
TRACE
(
"detected collided unwind
\n
"
);
TRACE
(
"detected collided unwind
\n
"
);
return
ExceptionCollidedUnwind
;
return
ExceptionCollidedUnwind
;
}
}
/**********************************************************************
/**********************************************************************
* unwind_handler_wrapper
*/
extern
DWORD
WINAPI
unwind_handler_wrapper
(
EXCEPTION_RECORD
*
rec
,
DISPATCHER_CONTEXT
*
dispatch
);
__ASM_GLOBAL_FUNC
(
unwind_handler_wrapper
,
"stp x29, x30, [sp, #-32]!
\n\t
"
".seh_save_fplr_x 32
\n\t
"
"mov x29, sp
\n\t
"
".seh_set_fp
\n\t
"
".seh_endprologue
\n\t
"
".seh_handler "
__ASM_NAME
(
"unwind_exception_handler"
)
", @except, @unwind
\n\t
"
"str x1, [sp, #16]
\n\t
"
/* frame[-2] = dispatch */
"mov x3, x1
\n\t
"
"ldr x1, [x3, #0x18]
\n\t
"
/* dispatch->EstablisherFrame */
"ldr x2, [x3, #0x28]
\n\t
"
/* dispatch->ContextRecord */
"ldr x15, [x3, #0x30]
\n\t
"
/* dispatch->LanguageHandler */
"blr x15
\n\t
"
"ldp x29, x30, [sp], #32
\n\t
"
"ret"
)
/**********************************************************************
* call_unwind_handler
* call_unwind_handler
*
*
* Call a single unwind handler.
* Call a single unwind handler.
*/
*/
static
DWORD
call_unwind_handler
(
EXCEPTION_RECORD
*
rec
,
DISPATCHER_CONTEXT
*
dispatch
)
static
DWORD
call_unwind_handler
(
EXCEPTION_RECORD
*
rec
,
DISPATCHER_CONTEXT
*
dispatch
)
{
{
struct
unwind_exception_frame
frame
;
DWORD
res
;
DWORD
res
;
frame
.
frame
.
Handler
=
unwind_exception_handler
;
frame
.
dispatch
=
dispatch
;
__wine_push_frame
(
&
frame
.
frame
);
TRACE
(
"calling handler %p (rec=%p, frame=%I64x context=%p, dispatch=%p)
\n
"
,
TRACE
(
"calling handler %p (rec=%p, frame=%I64x context=%p, dispatch=%p)
\n
"
,
dispatch
->
LanguageHandler
,
rec
,
dispatch
->
EstablisherFrame
,
dispatch
->
ContextRecord
,
dispatch
);
dispatch
->
LanguageHandler
,
rec
,
dispatch
->
EstablisherFrame
,
dispatch
->
ContextRecord
,
dispatch
);
res
=
dispatch
->
LanguageHandler
(
rec
,
(
void
*
)
dispatch
->
EstablisherFrame
,
dispatch
->
ContextRecord
,
dispatch
);
res
=
unwind_handler_wrapper
(
rec
,
dispatch
);
TRACE
(
"handler %p returned %lx
\n
"
,
dispatch
->
LanguageHandler
,
res
);
TRACE
(
"handler %p returned %lx
\n
"
,
dispatch
->
LanguageHandler
,
res
);
__wine_pop_frame
(
&
frame
.
frame
);
switch
(
res
)
switch
(
res
)
{
{
case
ExceptionContinueSearch
:
case
ExceptionContinueSearch
:
...
...
dlls/ntdll/signal_x86_64.c
View file @
f704b80a
...
@@ -367,9 +367,9 @@ DWORD WINAPI exception_handler_call_wrapper( EXCEPTION_RECORD *rec, void *frame,
...
@@ -367,9 +367,9 @@ DWORD WINAPI exception_handler_call_wrapper( EXCEPTION_RECORD *rec, void *frame,
C_ASSERT
(
offsetof
(
DISPATCHER_CONTEXT
,
LanguageHandler
)
==
0x30
);
C_ASSERT
(
offsetof
(
DISPATCHER_CONTEXT
,
LanguageHandler
)
==
0x30
);
__ASM_GLOBAL_FUNC
(
exception_handler_call_wrapper
,
__ASM_GLOBAL_FUNC
(
exception_handler_call_wrapper
,
".seh_endprologue
\n\t
"
"subq $0x28, %rsp
\n\t
"
"subq $0x28, %rsp
\n\t
"
".seh_stackalloc 0x28
\n\t
"
".seh_stackalloc 0x28
\n\t
"
".seh_endprologue
\n\t
"
"callq *0x30(%r9)
\n\t
"
/* dispatch->LanguageHandler */
"callq *0x30(%r9)
\n\t
"
/* dispatch->LanguageHandler */
"nop
\n\t
"
/* avoid epilogue so handler is called */
"nop
\n\t
"
/* avoid epilogue so handler is called */
"addq $0x28, %rsp
\n\t
"
"addq $0x28, %rsp
\n\t
"
...
@@ -1076,9 +1076,9 @@ C_ASSERT( offsetof(struct unwind_exception_frame, dispatch) == 0x20 );
...
@@ -1076,9 +1076,9 @@ C_ASSERT( offsetof(struct unwind_exception_frame, dispatch) == 0x20 );
C_ASSERT
(
offsetof
(
DISPATCHER_CONTEXT
,
LanguageHandler
)
==
0x30
);
C_ASSERT
(
offsetof
(
DISPATCHER_CONTEXT
,
LanguageHandler
)
==
0x30
);
__ASM_GLOBAL_FUNC
(
unwind_handler_call_wrapper
,
__ASM_GLOBAL_FUNC
(
unwind_handler_call_wrapper
,
".seh_endprologue
\n\t
"
"subq $0x28,%rsp
\n\t
"
"subq $0x28,%rsp
\n\t
"
".seh_stackalloc 0x28
\n\t
"
".seh_stackalloc 0x28
\n\t
"
".seh_endprologue
\n\t
"
"movq %r9,0x20(%rsp)
\n\t
"
/* unwind_exception_frame->dispatch */
"movq %r9,0x20(%rsp)
\n\t
"
/* unwind_exception_frame->dispatch */
"callq *0x30(%r9)
\n\t
"
/* dispatch->LanguageHandler */
"callq *0x30(%r9)
\n\t
"
/* dispatch->LanguageHandler */
"nop
\n\t
"
/* avoid epilogue so handler is called */
"nop
\n\t
"
/* avoid epilogue so handler is called */
...
...
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