[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
Sun Jul 10 15:05:40 PDT 2022


mstorsjo created this revision.
mstorsjo added reviewers: labath, jasonmolenda.
Herald added a subscriber: jsji.
Herald added a project: All.
mstorsjo requested review of this revision.
Herald added a project: LLDB.

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

@labath, FWIW while making the testcase, I realized why most tests on
Windows need the %build script instead of plain %clang_host.

For this testcase, I do need to have at least symbols available
(full debug info isn't needed). On unix-like systems, a command like
"clang source.c -o exec" will produce an executable with symbols.
With MSVC and clang in MSVC mode, the default linking command won't
produce any debug info at all, no symbols, nothing. We can fix it by
passing "-fuse-ld=lld -Wl,-debug:symtab", but that breaks mingw builds
(where symbols are kept by default).

The %build script handles all the options that are needed for creating
PDB debug info with clang-cl/lld-link, and produces symbols when building
in mingw mode too.


Repository:
  rG LLVM Github Monorepo

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.443529.patch
Type: text/x-patch
Size: 3680 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20220710/69d7f4b4/attachment.bin>


More information about the lldb-commits mailing list