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
5f890e3c
Commit
5f890e3c
authored
Mar 05, 2024
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Use a common wrapper to call unwind handlers on ARM64.
parent
d6285af1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
40 additions
and
78 deletions
+40
-78
signal_arm64.c
dlls/ntdll/signal_arm64.c
+40
-78
No files found.
dlls/ntdll/signal_arm64.c
View file @
5f890e3c
...
...
@@ -200,82 +200,22 @@ EXCEPTION_DISPOSITION WINAPI unwind_exception_handler( EXCEPTION_RECORD *record,
return
ExceptionCollidedUnwind
;
}
/**********************************************************************
*
unwind_handler_wrapp
er
*
call_unwind_handl
er
*/
extern
DWORD
WINAPI
unwind_handler_wrapper
(
EXCEPTION_RECORD
*
rec
,
DISPATCHER_CONTEXT
*
dispatch
);
__ASM_GLOBAL_FUNC
(
unwind_handler_wrapper
,
DWORD
WINAPI
call_unwind_handler
(
EXCEPTION_RECORD
*
rec
,
ULONG_PTR
frame
,
CONTEXT
*
context
,
void
*
dispatch
,
PEXCEPTION_ROUTINE
handler
);
__ASM_GLOBAL_FUNC
(
call_unwind_handler
,
"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
"
".seh_handler unwind_exception_handler, @except
\n\t
"
"str x3, [sp, #16]
\n\t
"
/* frame[-2] = dispatch */
"blr x4
\n\t
"
"ldp x29, x30, [sp], #32
\n\t
"
"ret"
)
/**********************************************************************
* call_unwind_handler
*
* Call a single unwind handler.
*/
static
DWORD
call_unwind_handler
(
EXCEPTION_RECORD
*
rec
,
DISPATCHER_CONTEXT
*
dispatch
)
{
DWORD
res
;
TRACE
(
"calling handler %p (rec=%p, frame=%I64x context=%p, dispatch=%p)
\n
"
,
dispatch
->
LanguageHandler
,
rec
,
dispatch
->
EstablisherFrame
,
dispatch
->
ContextRecord
,
dispatch
);
res
=
unwind_handler_wrapper
(
rec
,
dispatch
);
TRACE
(
"handler %p returned %lx
\n
"
,
dispatch
->
LanguageHandler
,
res
);
switch
(
res
)
{
case
ExceptionContinueSearch
:
case
ExceptionCollidedUnwind
:
break
;
default
:
raise_status
(
STATUS_INVALID_DISPOSITION
,
rec
);
break
;
}
return
res
;
}
/**********************************************************************
* call_teb_unwind_handler
*
* Call a single unwind handler from the TEB chain.
*/
static
DWORD
call_teb_unwind_handler
(
EXCEPTION_RECORD
*
rec
,
DISPATCHER_CONTEXT
*
dispatch
,
EXCEPTION_REGISTRATION_RECORD
*
teb_frame
)
{
DWORD
res
;
TRACE
(
"calling TEB handler %p (rec=%p, frame=%p context=%p, dispatch=%p)
\n
"
,
teb_frame
->
Handler
,
rec
,
teb_frame
,
dispatch
->
ContextRecord
,
dispatch
);
res
=
teb_frame
->
Handler
(
rec
,
teb_frame
,
dispatch
->
ContextRecord
,
(
EXCEPTION_REGISTRATION_RECORD
**
)
dispatch
);
TRACE
(
"handler at %p returned %lu
\n
"
,
teb_frame
->
Handler
,
res
);
switch
(
res
)
{
case
ExceptionContinueSearch
:
case
ExceptionCollidedUnwind
:
break
;
default
:
raise_status
(
STATUS_INVALID_DISPOSITION
,
rec
);
break
;
}
return
res
;
}
/***********************************************************************
* call_seh_handler
...
...
@@ -601,7 +541,7 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
CONTEXT
new_context
;
NTSTATUS
status
;
ULONG_PTR
frame
;
DWORD
i
;
DWORD
i
,
res
;
RtlCaptureContext
(
context
);
new_context
=
*
context
;
...
...
@@ -654,8 +594,20 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
raise_status
(
STATUS_INVALID_UNWIND_TARGET
,
rec
);
}
if
(
dispatch
.
EstablisherFrame
==
(
ULONG64
)
end_frame
)
rec
->
ExceptionFlags
|=
EXCEPTION_TARGET_UNWIND
;
if
(
call_unwind_handler
(
rec
,
&
dispatch
)
==
ExceptionCollidedUnwind
)
TRACE
(
"calling handler %p (rec=%p, frame=%I64x context=%p, dispatch=%p)
\n
"
,
dispatch
.
LanguageHandler
,
rec
,
dispatch
.
EstablisherFrame
,
dispatch
.
ContextRecord
,
&
dispatch
);
res
=
call_unwind_handler
(
rec
,
dispatch
.
EstablisherFrame
,
dispatch
.
ContextRecord
,
&
dispatch
,
dispatch
.
LanguageHandler
);
TRACE
(
"handler %p returned %lx
\n
"
,
dispatch
.
LanguageHandler
,
res
);
switch
(
res
)
{
case
ExceptionContinueSearch
:
rec
->
ExceptionFlags
&=
~
EXCEPTION_COLLIDED_UNWIND
;
break
;
case
ExceptionCollidedUnwind
:
new_context
=
*
context
;
RtlVirtualUnwind
(
UNW_FLAG_NHANDLER
,
dispatch
.
ImageBase
,
dispatch
.
ControlPc
,
dispatch
.
FunctionEntry
,
...
...
@@ -663,21 +615,30 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
NULL
);
rec
->
ExceptionFlags
|=
EXCEPTION_COLLIDED_UNWIND
;
goto
unwind_done
;
default
:
raise_status
(
STATUS_INVALID_DISPOSITION
,
rec
);
break
;
}
rec
->
ExceptionFlags
&=
~
EXCEPTION_COLLIDED_UNWIND
;
}
else
/* hack: call builtin handlers registered in the tib list */
{
DWORD64
backup_frame
=
dispatch
.
EstablisherFrame
;
while
(
is_valid_frame
(
(
ULONG_PTR
)
teb_frame
)
&&
(
ULONG64
)
teb_frame
<
new_context
.
Sp
&&
(
ULONG64
)
teb_frame
<
(
ULONG64
)
end_frame
)
{
TRACE
(
"found builtin frame %p handler %p
\n
"
,
teb_frame
,
teb_frame
->
Handler
);
dispatch
.
EstablisherFrame
=
(
ULONG64
)
teb_frame
;
if
(
call_teb_unwind_handler
(
rec
,
&
dispatch
,
teb_frame
)
==
ExceptionCollidedUnwind
)
TRACE
(
"calling TEB handler %p (rec=%p, frame=%p context=%p, dispatch=%p)
\n
"
,
teb_frame
->
Handler
,
rec
,
teb_frame
,
dispatch
.
ContextRecord
,
&
dispatch
);
res
=
call_unwind_handler
(
rec
,
(
ULONG_PTR
)
teb_frame
,
dispatch
.
ContextRecord
,
&
dispatch
,
(
PEXCEPTION_ROUTINE
)
teb_frame
->
Handler
);
TRACE
(
"handler at %p returned %lu
\n
"
,
teb_frame
->
Handler
,
res
);
teb_frame
=
__wine_pop_frame
(
teb_frame
);
switch
(
res
)
{
teb_frame
=
__wine_pop_frame
(
teb_frame
);
case
ExceptionContinueSearch
:
rec
->
ExceptionFlags
&=
~
EXCEPTION_COLLIDED_UNWIND
;
break
;
case
ExceptionCollidedUnwind
:
new_context
=
*
context
;
RtlVirtualUnwind
(
UNW_FLAG_NHANDLER
,
dispatch
.
ImageBase
,
dispatch
.
ControlPc
,
dispatch
.
FunctionEntry
,
...
...
@@ -685,11 +646,12 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
&
frame
,
NULL
);
rec
->
ExceptionFlags
|=
EXCEPTION_COLLIDED_UNWIND
;
goto
unwind_done
;
default
:
raise_status
(
STATUS_INVALID_DISPOSITION
,
rec
);
break
;
}
teb_frame
=
__wine_pop_frame
(
teb_frame
);
}
if
((
ULONG64
)
teb_frame
==
(
ULONG64
)
end_frame
&&
(
ULONG64
)
end_frame
<
new_context
.
Sp
)
break
;
dispatch
.
EstablisherFrame
=
backup_frame
;
}
if
(
dispatch
.
EstablisherFrame
==
(
ULONG64
)
end_frame
)
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