[PATCH] ntdll: Fix valid frame detection in ARM/ARM64.

Jinoh Kang jinoh.kang.kr at gmail.com
Thu Dec 9 02:55:35 CST 2021


Today, Wine cannot properly handle the end of call stack when unwinding
in ARM/ARM64, erroneously setting EH_STACK_INVALID in the exception
record when the base of the thread stack is reached.

This is because the is_valid_frame function was copied from i386, where
every function sets up a frame pointer next to the return address.
However, this does not hold on any other architectures (e.g. x86-64),
which instead rely on stack unwinding information tables to properly
recognise stack frames.

On these architectures, reaching the bottom of the call stack means the
stack pointer equals StackBase.   This is why signal_x86_64.c explicitly
recognises Rsp == StackBase to be a valid condition; however, this was
not copied to ARM/ARM64 when unwinding was implemented on these
architectures.

Fix this by allowing frame pointer to equal StackBase, just like X86-64.

Signed-off-by; Jinoh Kang <jinoh.kang.kr at gmail.com>
---
 dlls/ntdll/signal_arm.c   | 2 +-
 dlls/ntdll/signal_arm64.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c
index 72f3b023e45..12ffbb3663a 100644
--- a/dlls/ntdll/signal_arm.c
+++ b/dlls/ntdll/signal_arm.c
@@ -89,7 +89,7 @@ static inline BOOL is_valid_frame( ULONG_PTR frame )
 {
     if (frame & 3) return FALSE;
     return ((void *)frame >= NtCurrentTeb()->Tib.StackLimit &&
-            (void **)frame < (void **)NtCurrentTeb()->Tib.StackBase - 1);
+            (void *)frame <= NtCurrentTeb()->Tib.StackBase);
 }
 
 
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c
index 290639b676b..034c78f6b4d 100644
--- a/dlls/ntdll/signal_arm64.c
+++ b/dlls/ntdll/signal_arm64.c
@@ -96,7 +96,7 @@ static inline BOOL is_valid_frame( ULONG_PTR frame )
 {
     if (frame & 7) return FALSE;
     return ((void *)frame >= NtCurrentTeb()->Tib.StackLimit &&
-            (void **)frame < (void **)NtCurrentTeb()->Tib.StackBase - 1);
+            (void *)frame <= NtCurrentTeb()->Tib.StackBase);
 }
 
 
-- 
2.34.1




More information about the wine-devel mailing list