[Lldb-commits] [lldb] 66cdd65 - [lldb] Reduce the stack alignment requirements for the Windows x86_64 ABI

Martin Storsjö via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 11 13:42:32 PDT 2022


Author: Martin Storsjö
Date: 2022-07-11T23:41:35+03:00
New Revision: 66cdd6548ac51f2039b9f0bc10ec03f387b210c4

URL: https://github.com/llvm/llvm-project/commit/66cdd6548ac51f2039b9f0bc10ec03f387b210c4
DIFF: https://github.com/llvm/llvm-project/commit/66cdd6548ac51f2039b9f0bc10ec03f387b210c4.diff

LOG: [lldb] Reduce the stack alignment requirements for the Windows x86_64 ABI

This fixes https://github.com/llvm/llvm-project/issues/56095.

Differential Revision: https://reviews.llvm.org/D129455

Added: 
    lldb/test/Shell/Unwind/Inputs/windows-unaligned-x86_64-asm.s
    lldb/test/Shell/Unwind/Inputs/windows-unaligned-x86_64.cpp
    lldb/test/Shell/Unwind/windows-unaligned-x86_64.test

Modified: 
    lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h b/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
index e74b9126404e1..a9c2ed9c2f141 100644
--- a/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
+++ b/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
@@ -40,10 +40,15 @@ class ABIWindows_x86_64 : public ABIX86_64 {
 
   bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
 
-  // In Windows_x86_64 ABI, stack will always be maintained 16-byte aligned
+  // In Windows_x86_64 ABI requires that the stack will be maintained 16-byte
+  // aligned.
+  // When ntdll invokes callbacks such as KiUserExceptionDispatcher or
+  // KiUserCallbackDispatcher, those functions won't have a properly 16-byte
+  // aligned stack - but tolerate unwinding through them by relaxing the
+  // requirement to 8 bytes.
   bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
-	  if (cfa & (16ull - 1ull))
-      return false; // Not 16 byte aligned
+    if (cfa & (8ull - 1ull))
+      return false; // Not 8 byte aligned
     if (cfa == 0)
       return false; // Zero is not a valid stack address
     return true;

diff  --git a/lldb/test/Shell/Unwind/Inputs/windows-unaligned-x86_64-asm.s b/lldb/test/Shell/Unwind/Inputs/windows-unaligned-x86_64-asm.s
new file mode 100644
index 0000000000000..c042901683648
--- /dev/null
+++ b/lldb/test/Shell/Unwind/Inputs/windows-unaligned-x86_64-asm.s
@@ -0,0 +1,25 @@
+        .globl    call_func
+        .def      call_func;   .scl    2;      .type   32;     .endef
+        .seh_proc call_func
+call_func:
+        subq    $32, %rsp
+        .seh_stackalloc 32
+        .seh_endprologue
+        call    realign_stack
+        addq    $32, %rsp
+        ret
+        .seh_endproc
+
+        .globl    realign_stack
+        .def      realign_stack;   .scl    2;      .type   32;     .endef
+        .seh_proc realign_stack
+realign_stack:
+        subq    $32, %rsp
+        .seh_stackalloc 32
+        .seh_endprologue
+        movq    %rcx, %rax
+        movl    %edx, %ecx
+        call    *%rax
+        addq    $32, %rsp
+        ret
+        .seh_endproc

diff  --git a/lldb/test/Shell/Unwind/Inputs/windows-unaligned-x86_64.cpp b/lldb/test/Shell/Unwind/Inputs/windows-unaligned-x86_64.cpp
new file mode 100644
index 0000000000000..d310ef7d7ed2f
--- /dev/null
+++ b/lldb/test/Shell/Unwind/Inputs/windows-unaligned-x86_64.cpp
@@ -0,0 +1,8 @@
+extern "C" void call_func(void (*ptr)(int a), int a);
+
+extern "C" void func(int arg) { }
+
+int main(int argc, char **argv) {
+  call_func(func, 42);
+  return 0;
+}

diff  --git a/lldb/test/Shell/Unwind/windows-unaligned-x86_64.test b/lldb/test/Shell/Unwind/windows-unaligned-x86_64.test
new file mode 100644
index 0000000000000..94f1c011ebd2a
--- /dev/null
+++ b/lldb/test/Shell/Unwind/windows-unaligned-x86_64.test
@@ -0,0 +1,26 @@
+# Test unwinding through stack frames that aren't aligned to 16 bytes.
+# (In real world code, this happens when unwinding through
+# KiUserExceptionDispatcher and KiUserCallbackDispatcher in ntdll.dll.)
+
+# REQUIRES: target-x86_64, native, system-windows
+
+# RUN: %build %p/Inputs/windows-unaligned-x86_64.cpp %p/Inputs/windows-unaligned-x86_64-asm.s -o %t
+# RUN: %lldb %t -s %s -o exit | FileCheck %s
+
+# Future TODO: If %build could compile the source file in C mode, the symbol
+# name handling would be easier across msvc and mingw build configurations.
+# (In mingw mode, the extern C symbol "func" is printed as "::func" while
+# it's plain "func" in msvc mode. Without the extern C, it's "func(..." in
+# mingw mode, but "void __cdecl func(..." in msvc mode.)
+
+breakpoint set -n func
+# CHECK: Breakpoint 1: where = {{.*}}`{{(::)?}}func
+
+process launch
+# CHECK: stop reason = breakpoint 1.1
+
+thread backtrace
+# CHECK: frame #0: {{.*}}`{{(::)?}}func
+# CHECK: frame #1: {{.*}}`realign_stack
+# CHECK: frame #2: {{.*}}`call_func
+# CHECK: frame #3: {{.*}}`main


        


More information about the lldb-commits mailing list