[JITLink][MachO] Add support for non-subsections-via-symbols objects.
authorLang Hames <lhames@gmail.com>
Wed, 27 Jul 2022 17:56:22 +0000 (10:56 -0700)
committerLang Hames <lhames@gmail.com>
Wed, 17 Aug 2022 22:55:42 +0000 (15:55 -0700)
This patch updates MachOLinkGraphBuilder to honor the MH_SUBSECTIONS_VIA_SYMBOLS
flag. Prior to this patch we assumed MH_SUBSECTIONS_VIA_SYMBOLS, but never
checked the flag.

If MH_SUBSECTIONS_VIA_SYMBOLS is set (the default for MachO output on modern
compilers) then MachOLinkGraphBuilder will break MachO section content into
jitlink::Blocks on symbol boundaries. (This is how JITLink has always handled
MachO sections previously).

If MH_SUBSECTIONS_VIA_SYMBOLS is not set then MachOLinkGraphBuilder will create
a single jitlink::Block for each MachO section.

Existing hand-written testcases that were _not_ using the
.subsections_via_symbols directive are updated to use it. A new testcase for
non-subsections-via-symbols behavior is included.

llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
llvm/test/ExecutionEngine/JITLink/X86/Inputs/x86-64_self_relocation.s
llvm/test/ExecutionEngine/JITLink/X86/MachO-duplicate-local.test
llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_load_hidden_expect_success.s
llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_support.s
llvm/test/ExecutionEngine/JITLink/X86/MachO_non_subsections_via_symbols.s [new file with mode: 0644]
llvm/test/ExecutionEngine/JITLink/X86/MachO_weak_local.s

index 1bf12f4..1315654 100644 (file)
@@ -51,7 +51,10 @@ MachOLinkGraphBuilder::MachOLinkGraphBuilder(
     : Obj(Obj),
       G(std::make_unique<LinkGraph>(
           std::string(Obj.getFileName()), std::move(TT), getPointerSize(Obj),
-          getEndianness(Obj), std::move(GetEdgeKindName))) {}
+          getEndianness(Obj), std::move(GetEdgeKindName))) {
+  auto &MachHeader = Obj.getHeader64();
+  SubsectionsViaSymbols = MachHeader.flags & MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
+}
 
 void MachOLinkGraphBuilder::addCustomSectionParser(
     StringRef SectionName, SectionParserFunction Parser) {
@@ -485,15 +488,24 @@ Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
     }
 
     // Visit section symbols in order by popping off the reverse-sorted stack,
-    // building blocks for each alt-entry chain and creating symbols as we go.
+    // building graph symbols as we go.
+    //
+    // If MH_SUBSECTIONS_VIA_SYMBOLS is set we'll build a block for each
+    // alt-entry chain.
+    //
+    // If MH_SUBSECTIONS_VIA_SYMBOLS is not set then we'll just build one block
+    // for the whole section.
     while (!SecNSymStack.empty()) {
       SmallVector<NormalizedSymbol *, 8> BlockSyms;
 
+      // Get the symbols in this alt-entry chain, or the whole section (if
+      // !SubsectionsViaSymbols).
       BlockSyms.push_back(SecNSymStack.back());
       SecNSymStack.pop_back();
       while (!SecNSymStack.empty() &&
              (isAltEntry(*SecNSymStack.back()) ||
-              SecNSymStack.back()->Value == BlockSyms.back()->Value)) {
+              SecNSymStack.back()->Value == BlockSyms.back()->Value ||
+             !SubsectionsViaSymbols)) {
         BlockSyms.push_back(SecNSymStack.back());
         SecNSymStack.pop_back();
       }
index 2951a85..7cbc9f3 100644 (file)
@@ -226,6 +226,7 @@ private:
   const object::MachOObjectFile &Obj;
   std::unique_ptr<LinkGraph> G;
 
+  bool SubsectionsViaSymbols = false;
   DenseMap<unsigned, NormalizedSection> IndexToSection;
   Section *CommonSection = nullptr;
 
index 3738440..8afb7e2 100644 (file)
@@ -32,4 +32,6 @@ _main:
   movzbl  %al, %eax
   addq  $32, %rsp
   popq  %rbp
-  retq
\ No newline at end of file
+  retq
+
+  .subsections_via_symbols
index 25def26..d2895e4 100644 (file)
@@ -19,7 +19,7 @@ FileHeader:
   filetype:        0x1
   ncmds:           4
   sizeofcmds:      280
-  flags:           0x0
+  flags:           0x2000
   reserved:        0x0
 LoadCommands:
   - cmd:             LC_SEGMENT_64
index 77f3960..800bf66 100644 (file)
@@ -21,3 +21,5 @@ _main:
        .p2align        3
 ExtraDefRef:
        .quad   ExtraDef
+
+        .subsections_via_symbols
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/MachO_non_subsections_via_symbols.s b/llvm/test/ExecutionEngine/JITLink/X86/MachO_non_subsections_via_symbols.s
new file mode 100644 (file)
index 0000000..e1adb3b
--- /dev/null
@@ -0,0 +1,21 @@
+# The assembly below does NOT include the usual .subsections_via_symbols
+# directive. Check that when the directive is absent we only create one block
+# to cover the whole data section.
+#
+# REQUIRES: asserts
+# RUN: llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o %t %s
+# RUN: llvm-jitlink -debug-only=jitlink -noexec %t 2>&1 | FileCheck %s
+
+# CHECK:        Creating graph symbols...
+# CHECK:          Graphifying regular section __DATA,__data...
+# CHECK-NEXT:       Creating block {{.*}} with 2 symbol(s)...
+# CHECK-NEXT:         0x0000000000000004 -- 0x0000000000000008: _b
+# CHECK-NEXT:         0x0000000000000000 -- 0x0000000000000008: _main
+
+       .section        __DATA,__data
+       .p2align        2
+        .globl  _main
+_main:
+       .long   1
+_b:
+        .long   2