[ORC] Pad section start to account for alignment offset in MachO GDB JIT plugin.
authorLang Hames <lhames@gmail.com>
Tue, 7 Dec 2021 01:22:30 +0000 (12:22 +1100)
committerLang Hames <lhames@gmail.com>
Tue, 7 Dec 2021 03:28:31 +0000 (14:28 +1100)
In order to present a well-formed MachO debug object for debugger registration
the first block in each section must have a zero alignment offset (since there
is no way to represent a non-zero offset in a MachO section load command). This
patch updates the MachODebugObjectSynthesizer class to introduce a padding
padding block at the start of the section if necessary to guarantee a zero
alignment offset.

llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp
llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_strong_def_extra.s [new file with mode: 0644]
llvm/test/ExecutionEngine/JITLink/X86/MachO_gdb_jit_nonzero_alignment_offsets.s [new file with mode: 0644]

index 8479495..fe62138 100644 (file)
@@ -154,8 +154,24 @@ public:
         }
         DebugSecInfos.push_back({&Sec, Sec.getName().substr(0, SepPos),
                                  Sec.getName().substr(SepPos + 1), 0, 0});
-      } else
+      } else {
         NonDebugSections.push_back(&Sec);
+
+        // If the first block in the section has a non-zero alignment offset
+        // then we need to add a padding block, since the section command in
+        // the header doesn't allow for aligment offsets.
+        SectionRange R(Sec);
+        if (!R.empty()) {
+          auto &FB = *R.getFirstBlock();
+          if (FB.getAlignmentOffset() != 0) {
+            auto Padding = G.allocateBuffer(FB.getAlignmentOffset());
+            memset(Padding.data(), 0, Padding.size());
+            G.createContentBlock(Sec, Padding,
+                                 FB.getAddress() - FB.getAlignmentOffset(),
+                                 FB.getAlignment(), 0);
+          }
+        }
+      }
     }
 
     // Create container block.
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_strong_def_extra.s b/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_strong_def_extra.s
new file mode 100644 (file)
index 0000000..15785ed
--- /dev/null
@@ -0,0 +1,11 @@
+# Supplies a strong definition of WeakDef.
+
+       .section        __TEXT,__text,regular,pure_instructions
+       .build_version macos, 10, 14    sdk_version 10, 14
+       .section        __DATA,__data
+       .globl  WeakDef
+       .p2align        2
+WeakDef:
+       .long   3
+
+.subsections_via_symbols
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/MachO_gdb_jit_nonzero_alignment_offsets.s b/llvm/test/ExecutionEngine/JITLink/X86/MachO_gdb_jit_nonzero_alignment_offsets.s
new file mode 100644 (file)
index 0000000..e8618e0
--- /dev/null
@@ -0,0 +1,38 @@
+# REQUIRES: system-darwin && asserts
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
+# RUN:   -o %t/MachO_strong_def_extra.o %S/Inputs/MachO_strong_def_extra.s
+# RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
+# RUN:   -o %t/MachO_gdb_jit_nonzero_alignment_offsets.o %s
+# RUN: llvm-jitlink -noexec -debugger-support \
+# RUN:   %t/MachO_gdb_jit_nonzero_alignment_offsets.o \
+# RUN:   %t/MachO_strong_def_extra.o
+#
+# Check that blocks with non-zero alignment offsets don't break debugging
+# support.
+#
+# In this test case the WeakDef symbol below will be overridden by a strong def
+# in MachO_strong_defs_extra.s. This will leave main (with alignment 16,
+# alignment offset 4) as the only block in __TEXT,__text. The testcase ensures
+# that the debugging support plugin doesn't crash or throw an error in this
+# case.
+
+        .section       __TEXT,__text,regular,pure_instructions
+       .p2align        4, 0x90
+
+       .globl  WeakDef
+       .weak_definition        WeakDef
+       .p2align        2
+WeakDef:
+       .long   42
+
+       .globl  _main
+_main:
+       xorq    %rax, %rax
+       retq
+
+       .section        __DWARF,__debug_str,regular,debug
+Linfo_string:
+       .asciz  "test dwarf string"
+
+.subsections_via_symbols