[Lldb-commits] [PATCH] D129455: [lldb] Reduce the stack alignment requirements for the Windows x86_64 ABI

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


This revision was automatically updated to reflect the committed changes.
Closed by commit rG66cdd6548ac5: [lldb] Reduce the stack alignment requirements for the Windows x86_64 ABI (authored by mstorsjo).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D129455/new/

https://reviews.llvm.org/D129455

Files:
  lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
  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


Index: lldb/test/Shell/Unwind/windows-unaligned-x86_64.test
===================================================================
--- /dev/null
+++ 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
Index: lldb/test/Shell/Unwind/Inputs/windows-unaligned-x86_64.cpp
===================================================================
--- /dev/null
+++ 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;
+}
Index: lldb/test/Shell/Unwind/Inputs/windows-unaligned-x86_64-asm.s
===================================================================
--- /dev/null
+++ 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
Index: lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
===================================================================
--- lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
+++ lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
@@ -40,10 +40,15 @@
 
   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;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D129455.443744.patch
Type: text/x-patch
Size: 3680 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20220711/ac50727e/attachment-0001.bin>


More information about the lldb-commits mailing list