Module: wine
Branch: master
Commit: d007c91d46bb9868ccde0c32865c616b1f255827
URL: https://source.winehq.org/git/wine.git/?a=commit;h=d007c91d46bb9868ccde0c32…
Author: Martin Storsjö <martin(a)martin.st>
Date: Tue Jun 7 14:10:07 2022 +0300
ntdll: Use ControlPcIsUnwound for the RtlVirtualUnwind pc parameter in virtual_unwind.
Don't just use ControlPcIsUnwound for picking which RUNTIME_FUNCTION
to use, but also use it for adjusting the pc value that is passed
to RtlVirtualUnwind.
This fixes one testcase (that I had missed to build and run before),
where the pc points at the start of an epilogue (which would mean
that no handler is returned from RtlVirtualUnwind). By taking
ControlPcIsUnwound and adjusting the pc pointer, the unwind handler
is returned and executed.
Signed-off-by: Martin Storsjö <martin(a)martin.st>
---
dlls/ntdll/signal_arm.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c
index 01c911660de..c4cf557edaf 100644
--- a/dlls/ntdll/signal_arm.c
+++ b/dlls/ntdll/signal_arm.c
@@ -133,6 +133,7 @@ static NTSTATUS virtual_unwind( ULONG type, DISPATCHER_CONTEXT *dispatch, CONTEX
{
LDR_DATA_TABLE_ENTRY *module;
NTSTATUS status;
+ DWORD pc;
dispatch->ImageBase = 0;
dispatch->ScopeIndex = 0;
@@ -143,14 +144,14 @@ static NTSTATUS virtual_unwind( ULONG type, DISPATCHER_CONTEXT *dispatch, CONTEX
* signal frame.
*/
dispatch->ControlPcIsUnwound = (context->ContextFlags & CONTEXT_UNWOUND_TO_CALL) != 0;
+ pc = context->Pc - (dispatch->ControlPcIsUnwound ? 2 : 0);
/* first look for PE exception information */
- if ((dispatch->FunctionEntry = lookup_function_info(
- context->Pc - (dispatch->ControlPcIsUnwound ? 2 : 0),
+ if ((dispatch->FunctionEntry = lookup_function_info(pc,
(ULONG_PTR*)&dispatch->ImageBase, &module )))
{
- dispatch->LanguageHandler = RtlVirtualUnwind( type, dispatch->ImageBase, context->Pc,
+ dispatch->LanguageHandler = RtlVirtualUnwind( type, dispatch->ImageBase, pc,
dispatch->FunctionEntry, context,
&dispatch->HandlerData, (ULONG_PTR *)&dispatch->EstablisherFrame,
NULL );
Module: wine
Branch: master
Commit: 2d43653a2e789ed67a3c66db92276783b849051c
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2d43653a2e789ed67a3c66db…
Author: Martin Storsjö <martin(a)martin.st>
Date: Wed May 11 00:52:10 2022 +0300
ntdll: Add SEH unwind info in ARM assembly functions/trampolines.
Clang generates SEH unwind info on ARM in both MSVC and mingw mode
since Clang 15. The unwind info gets which gets enabled automatically
by building with a new enough compiler.
For functions/trampolines that are implemented in assembly, the unwind
information needs to be provided by hand - in particular for cases
where unwinding should be diverted.
Contrary to AArch64, Clang got SEH assembler directives directly from
the start when SEH was implemented (when the __SEH__ compiler define
gets set), so there's no need for compiler version checks (like for
AArch64 in include/wine/asm.h), but the default check for __SEH__
works fine for enabling the __ARM_SEH() macro.
Use a custom unwind opcode in the private opcode space for unwinding
to a specific CONTEXT instead of up to the caller. (Contrary to
AArch64, there's no specific unwind opcode for restoring a full
CONTEXT, but the unwind opcode space does have a couple
unallocated values marked as "available", which can be used
for vendor specific needs here.)
This fixes unwinding in ARM PE builds.
Signed-off-by: Martin Storsjö <martin(a)martin.st>
---
dlls/ntdll/signal_arm.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c
index 7872962bbbe..01c911660de 100644
--- a/dlls/ntdll/signal_arm.c
+++ b/dlls/ntdll/signal_arm.c
@@ -731,6 +731,8 @@ static void process_unwind_codes( BYTE *ptr, BYTE *end, CONTEXT *context,
WARN( "unsupported code %02x\n", *ptr );
else if (*ptr <= 0xef && ((val & 0xff) <= 0x0f)) /* ldr lr, [sp], #x */
pop_lr( 4 * (val & 0x0f), context, ptrs );
+ else if (*ptr == 0xf4) /* Custom private (unallocated) opcode, saved a full CONTEXT on the stack */
+ memcpy( context, (DWORD *)context->Sp, sizeof(CONTEXT) );
else if (*ptr <= 0xf4) /* Available */
WARN( "unsupported code %02x\n", *ptr );
else if (*ptr <= 0xf5) /* vpop {dS-dE} */
@@ -1075,11 +1077,18 @@ extern void * WINAPI call_consolidate_callback( CONTEXT *context,
EXCEPTION_RECORD *rec );
__ASM_GLOBAL_FUNC( call_consolidate_callback,
"push {r0-r2,lr}\n\t"
+ __ASM_SEH(".seh_nop\n\t")
"sub sp, sp, #0x1a0\n\t"
+ __ASM_SEH(".seh_nop\n\t")
"mov r1, r0\n\t"
+ __ASM_SEH(".seh_nop\n\t")
"mov r0, sp\n\t"
+ __ASM_SEH(".seh_nop\n\t")
"mov r2, #0x1a0\n\t"
+ __ASM_SEH(".seh_nop_w\n\t")
"bl " __ASM_NAME("memcpy") "\n\t"
+ __ASM_SEH(".seh_custom 0xf4\n\t") /* A custom (unallocated) SEH opcode for CONTEXT on stack */
+ __ASM_SEH(".seh_endprologue\n\t")
__ASM_CFI(".cfi_def_cfa 13, 0\n\t")
__ASM_CFI(".cfi_escape 0x0f,0x04,0x7d,0xb8,0x00,0x06\n\t") /* DW_CFA_def_cfa_expression: DW_OP_breg13 + 56, DW_OP_deref */
__ASM_CFI(".cfi_escape 0x10,0x04,0x02,0x7d,0x14\n\t") /* DW_CFA_expression: R4 DW_OP_breg13 + 20 */
@@ -1300,6 +1309,8 @@ extern LONG __C_ExecuteExceptionFilter(PEXCEPTION_POINTERS ptrs, PVOID frame,
PUCHAR nonvolatile);
__ASM_GLOBAL_FUNC( __C_ExecuteExceptionFilter,
"push {r4-r11,lr}\n\t"
+ __ASM_SEH(".seh_save_regs_w {r4-r11,lr}\n\t")
+ __ASM_SEH(".seh_endprologue\n\t")
__ASM_CFI(".cfi_def_cfa 13, 36\n\t")
__ASM_CFI(".cfi_offset r4, -36\n\t")
@@ -1410,7 +1421,10 @@ EXCEPTION_DISPOSITION WINAPI __C_specific_handler( EXCEPTION_RECORD *rec,
*/
__ASM_STDCALL_FUNC( RtlRaiseException, 4,
"push {r0, lr}\n\t"
+ __ASM_SEH(".seh_save_regs {r0, lr}\n\t")
"sub sp, sp, #0x1a0\n\t" /* sizeof(CONTEXT) */
+ __ASM_SEH(".seh_stackalloc 0x1a0\n\t")
+ __ASM_SEH(".seh_endprologue\n\t")
__ASM_CFI(".cfi_adjust_cfa_offset 424\n\t")
__ASM_CFI(".cfi_offset lr, -4\n\t")
"mov r0, sp\n\t" /* context */