[compiler-rt] 9d701c8 - [ORC] Fix fallout from switch to _objc_map/load_images-based registration.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 11 16:48:33 PDT 2023


Author: Lang Hames
Date: 2023-04-11T16:48:26-07:00
New Revision: 9d701c8a8d65a830c3d454479b13a50dcc097b57

URL: https://github.com/llvm/llvm-project/commit/9d701c8a8d65a830c3d454479b13a50dcc097b57
DIFF: https://github.com/llvm/llvm-project/commit/9d701c8a8d65a830c3d454479b13a50dcc097b57.diff

LOG: [ORC] Fix fallout from switch to _objc_map/load_images-based registration.

In f448d44663a we switched to calling _objc_map_images and _objc_load_images
for MachO language metadata registration. This patch fixes some bugs arising
from that change:

(1) __objc_imageinfo processing was moved to a post-allocation pass, but this
    prevents us from discarding the redundant copies. This commit moves
    processing back to a pre-prune pass and inserts a symbol for the uniqued
    __objc_image section. Runtime objects use an edge pointing to this symbol
    to access the address.

(2) We were assuming that _objc_map_images & _objc_load_images were available
    in the Objective-C runtime on 10.15, but these functions didn't become
    available until later. This commit bumps the macOS version requirement to
    13.1 where the functions should be available.

(3) The ORC-RT trivial-swift-types-section.S test was missing an
    __objc_unwindinfo section, which triggered an assert that should have
    been an error. The assert has been turned into an error, and the testcase
    has been updated to include an __objc_imageinfo.

rdar://107846455

Added: 
    

Modified: 
    compiler-rt/lib/orc/macho_platform.cpp
    compiler-rt/test/lit.common.cfg.py
    compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-swift-types-section.S
    llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
    llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/orc/macho_platform.cpp b/compiler-rt/lib/orc/macho_platform.cpp
index 1ca51c4c2171a..33f7fbb8b347c 100644
--- a/compiler-rt/lib/orc/macho_platform.cpp
+++ b/compiler-rt/lib/orc/macho_platform.cpp
@@ -859,6 +859,8 @@ Error MachOPlatformRuntimeState::deregisterEHFrames(
 
 Error MachOPlatformRuntimeState::registerObjCRegistrationObjects(
     JITDylibState &JDS) {
+  ORC_RT_DEBUG(printdbg("Registering Objective-C / Swift metadata.\n"));
+
   if (!_objc_map_images || !_objc_load_image)
     return make_error<StringError>(
         "Could not register Objective-C / Swift metadata: _objc_map_images / "

diff  --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py
index 5401d25dd2285..6ea6c19f43efc 100644
--- a/compiler-rt/test/lit.common.cfg.py
+++ b/compiler-rt/test/lit.common.cfg.py
@@ -403,8 +403,8 @@ def get_ios_commands_dir():
     if osx_version >= (10, 11):
       config.available_features.add('osx-autointerception')
       config.available_features.add('osx-ld64-live_support')
-    if osx_version >= (10, 15):
-      config.available_features.add('osx-swift-runtime')
+    if osx_version >= (13, 1):
+      config.available_features.add('jit-compatible-osx-swift-runtime')
   except subprocess.CalledProcessError:
     pass
 

diff  --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-swift-types-section.S b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-swift-types-section.S
index f6bb257bb46bf..c3cd767511fa2 100644
--- a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-swift-types-section.S
+++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-swift-types-section.S
@@ -1,94 +1,129 @@
 # RUN: %clang -c -o %t %s
 # RUN: %llvm_jitlink -preload /usr/lib/swift/libswiftCore.dylib %t
 
-# REQUIRES: osx-swift-runtime
+# REQUIRES: jit-compatible-osx-swift-runtime
 
 # Check that _typeByName is able to find a type registered by metadata in
 # the __swift5_types section.
 
-  .section  __TEXT,__text,regular,pure_instructions
-  .globl  _main
-  .p2align  4, 0x90
+        .section        __TEXT,__text,regular,pure_instructions
+        .build_version macos, 14, 0     sdk_version 14, 0
+        .globl  _main
+        .p2align        4, 0x90
 _main:
-  .cfi_startproc
-  pushq %rbp
-  .cfi_def_cfa_offset 16
-  .cfi_offset %rbp, -16
-  movq  %rsp, %rbp
-  .cfi_def_cfa_register %rbp
-  # Constant String for "4Test3FooV"
-  movabsq $8018152761824990260, %rdi
-  movabsq $-1585267068834392465, %rsi
-  callq _$ss11_typeByNameyypXpSgSSF
-  xorl  %edi, %edi
-  testq %rax, %rax
-  sete  %dil
-  callq _exit
-  .cfi_endproc
-
-  .private_extern _$s4Test3FooVMa
-  .globl  _$s4Test3FooVMa
-  .p2align  4, 0x90
+        .cfi_startproc
+        pushq   %rbp
+        .cfi_def_cfa_offset 16
+        .cfi_offset %rbp, -16
+        movq    %rsp, %rbp
+        .cfi_def_cfa_register %rbp
+        # Constant String for "4Test3FooV"
+        movabsq $8018152761824990260, %rdi
+        movabsq $-1585267068834392465, %rsi
+        callq   _$ss11_typeByNameyypXpSgSSF
+        xorl    %edi, %edi
+        testq   %rax, %rax
+        sete    %dil
+        callq   _exit
+        .cfi_endproc
+
+	.private_extern	_$s4Test3FooVACycfC
+	.globl	_$s4Test3FooVACycfC
+	.p2align	4, 0x90
+_$s4Test3FooVACycfC:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	popq	%rbp
+	retq
+
+	.private_extern	_$s4Test3FooVMa
+	.globl	_$s4Test3FooVMa
+	.p2align	4, 0x90
 _$s4Test3FooVMa:
-  leaq  _$s4Test3FooVMf+8(%rip), %rax
-  xorl  %edx, %edx
-  retq
-
-  .section  __TEXT,__const
-l___unnamed_1:
-  .asciz  "Test"
-
-  .private_extern _$s4TestMXM
-  .globl  _$s4TestMXM
-  .weak_definition  _$s4TestMXM
-  .p2align  2
+	leaq	_$s4Test3FooVMf+8(%rip), %rax
+	xorl	%edx, %edx
+	retq
+
+	.section	__TEXT,__swift5_entry,regular,no_dead_strip
+	.p2align	2
+l_entry_point:
+	.long	_main-l_entry_point
+	.long	0
+
+	.section	__TEXT,__const
+l_.str.4.Test:
+	.asciz	"Test"
+
+	.private_extern	_$s4TestMXM
+	.globl	_$s4TestMXM
+	.weak_definition	_$s4TestMXM
+	.p2align	2
 _$s4TestMXM:
-  .long 0
-  .long 0
-  .long (l___unnamed_1-_$s4TestMXM)-8
+	.long	0
+	.long	0
+	.long	(l_.str.4.Test-_$s4TestMXM)-8
 
-l___unnamed_2:
-  .asciz  "Foo"
+l_.str.3.Foo:
+	.asciz	"Foo"
 
-  .private_extern _$s4Test3FooVMn
-  .globl  _$s4Test3FooVMn
-  .p2align  2
+	.private_extern	_$s4Test3FooVMn
+	.globl	_$s4Test3FooVMn
+	.p2align	2
 _$s4Test3FooVMn:
-  .long 81
-  .long (_$s4TestMXM-_$s4Test3FooVMn)-4
-  .long (l___unnamed_2-_$s4Test3FooVMn)-8
-  .long (_$s4Test3FooVMa-_$s4Test3FooVMn)-12
-  .long (_$s4Test3FooVMF-_$s4Test3FooVMn)-16
-  .long 0
-  .long 2
-
-  .section  __DATA,__const
-  .p2align  3
+	.long	81
+	.long	(_$s4TestMXM-_$s4Test3FooVMn)-4
+	.long	(l_.str.3.Foo-_$s4Test3FooVMn)-8
+	.long	(_$s4Test3FooVMa-_$s4Test3FooVMn)-12
+	.long	(_$s4Test3FooVMF-_$s4Test3FooVMn)-16
+	.long	0
+	.long	2
+
+	.section	__DATA,__const
+	.p2align	3
 _$s4Test3FooVMf:
-  .quad _$sytWV
-  .quad 512
-  .quad _$s4Test3FooVMn
-
-  .private_extern "_symbolic _____ 4Test3FooV"
-  .section  __TEXT,__swift5_typeref,regular,no_dead_strip
-  .globl  "_symbolic _____ 4Test3FooV"
-  .weak_definition  "_symbolic _____ 4Test3FooV"
-  .p2align  1
+	.quad	_$sytWV
+	.quad	512
+	.quad	_$s4Test3FooVMn
+
+	.private_extern	"_symbolic _____ 4Test3FooV"
+	.section	__TEXT,__swift5_typeref
+	.globl	"_symbolic _____ 4Test3FooV"
+	.weak_definition	"_symbolic _____ 4Test3FooV"
+	.p2align	1
 "_symbolic _____ 4Test3FooV":
-  .byte 1
-  .long (_$s4Test3FooVMn-"_symbolic _____ 4Test3FooV")-1
-  .byte 0
+	.byte	1
+	.long	(_$s4Test3FooVMn-"_symbolic _____ 4Test3FooV")-1
+	.byte	0
 
-  .section  __TEXT,__swift5_fieldmd,regular,no_dead_strip
-  .p2align  2
+	.section	__TEXT,__swift5_fieldmd
+	.p2align	2
 _$s4Test3FooVMF:
-  .long "_symbolic _____ 4Test3FooV"-_$s4Test3FooVMF
-  .long 0
-  .short  0
-  .short  12
-  .long 0
-
-  .section  __TEXT,__swift5_types,regular,no_dead_strip
-  .p2align  2
-l_type_metadata_table:
-  .long _$s4Test3FooVMn-l_type_metadata_table
+	.long	"_symbolic _____ 4Test3FooV"-_$s4Test3FooVMF
+	.long	0
+	.short	0
+	.short	12
+	.long	0
+
+	.section	__TEXT,__swift5_types
+	.p2align	2
+l_$s4Test3FooVHn:
+	.long	_$s4Test3FooVMn-l_$s4Test3FooVHn
+
+	.private_extern	___swift_reflection_version
+	.section	__TEXT,__const
+	.globl	___swift_reflection_version
+	.weak_definition	___swift_reflection_version
+	.p2align	1
+___swift_reflection_version:
+	.short	3
+
+	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
+L_OBJC_IMAGE_INFO:
+	.long	0
+	.long	84477760
+
+	.globl	_$s4Test3FooVN
+	.private_extern	_$s4Test3FooVN
+	.alt_entry	_$s4Test3FooVN
+.set _$s4Test3FooVN, _$s4Test3FooVMf+8
+.subsections_via_symbols

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
index a89ed606531ce..4800686d817d5 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
@@ -159,7 +159,6 @@ class MachOPlatform : public Platform {
     struct ObjCImageInfo {
       uint32_t Version = 0;
       uint32_t Flags = 0;
-      ExecutorAddr Addr;
     };
 
     Error bootstrapPipelineStart(jitlink::LinkGraph &G);

diff  --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
index c769108c1fa99..c6eb12012a1e1 100644
--- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
@@ -10,6 +10,7 @@
 
 #include "llvm/BinaryFormat/MachO.h"
 #include "llvm/ExecutionEngine/JITLink/MachO.h"
+#include "llvm/ExecutionEngine/JITLink/aarch64.h"
 #include "llvm/ExecutionEngine/JITLink/x86_64.h"
 #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
@@ -262,6 +263,9 @@ static StringRef ObjCRuntimeObjectSectionsText[] = {
 static StringRef ObjCRuntimeObjectSectionName =
     "__llvm_jitlink_ObjCRuntimeRegistrationObject";
 
+static StringRef ObjCImageInfoSymbolName =
+    "__llvm_jitlink_macho_objc_imageinfo";
+
 } // end anonymous namespace
 
 namespace llvm {
@@ -758,15 +762,15 @@ void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
     // If the object contains an init symbol other than the header start symbol
     // then add passes to preserve, process and register the init
     // sections/symbols.
-    Config.PrePrunePasses.push_back(
-        [this, &MR](LinkGraph &G) { return preserveImportantSections(G, MR); });
-    Config.PostPrunePasses.push_back(
-        [this](LinkGraph &G) { return createObjCRuntimeObject(G); });
-    Config.PostAllocationPasses.push_back([this, &MR](LinkGraph &G) {
-      if (auto Err = processObjCImageInfo(G, MR))
+    Config.PrePrunePasses.push_back([this, &MR](LinkGraph &G) {
+      if (auto Err = preserveImportantSections(G, MR))
         return Err;
-      return populateObjCRuntimeObject(G, MR);
+      return processObjCImageInfo(G, MR);
     });
+    Config.PostPrunePasses.push_back(
+        [this](LinkGraph &G) { return createObjCRuntimeObject(G); });
+    Config.PostAllocationPasses.push_back(
+        [this, &MR](LinkGraph &G) { return populateObjCRuntimeObject(G, MR); });
   }
 
   // Insert TLV lowering at the start of the PostPrunePasses, since we want
@@ -1023,8 +1027,14 @@ Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
   } else {
     // We haven't registered an __objc_imageinfo section yet. Register and
     // move on. The section should already be marked no-dead-strip.
-    ObjCImageInfos[&MR.getTargetJITDylib()] = {Version, Flags,
-                                               ObjCImageInfoBlock.getAddress()};
+    G.addDefinedSymbol(ObjCImageInfoBlock, 0, ObjCImageInfoSymbolName,
+                       ObjCImageInfoBlock.getSize(), jitlink::Linkage::Strong,
+                       jitlink::Scope::Hidden, false, true);
+    if (auto Err = MR.defineMaterializing(
+            {{MR.getExecutionSession().intern(ObjCImageInfoSymbolName),
+              JITSymbolFlags()}}))
+      return Err;
+    ObjCImageInfos[&MR.getTargetJITDylib()] = {Version, Flags};
   }
 
   return Error::success();
@@ -1312,33 +1322,84 @@ Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
   if (!ObjCRuntimeObjectSec)
     return Error::success();
 
+  switch (G.getTargetTriple().getArch()) {
+  case Triple::aarch64:
+  case Triple::x86_64:
+    // Supported.
+    break;
+  default:
+    return make_error<StringError>("Unrecognized MachO arch in triple " +
+                                       G.getTargetTriple().str(),
+                                   inconvertibleErrorCode());
+  }
+
   auto &SecBlock = **ObjCRuntimeObjectSec->blocks().begin();
 
-  std::vector<MachO::section_64> TextSections, DataSections;
-  auto AddSection = [&](MachO::section_64 &Sec, jitlink::Section &GraphSec) {
+  struct SecDesc {
+    MachO::section_64 Sec;
+    unique_function<void(size_t RecordOffset)> AddFixups;
+  };
+
+  std::vector<SecDesc> TextSections, DataSections;
+  auto AddSection = [&](SecDesc &SD, jitlink::Section &GraphSec) {
     jitlink::SectionRange SR(GraphSec);
     StringRef FQName = GraphSec.getName();
-    memset(&Sec, 0, sizeof(MachO::section_64));
-    memcpy(Sec.sectname, FQName.drop_front(7).data(), FQName.size() - 7);
-    memcpy(Sec.segname, FQName.data(), 6);
-    Sec.addr = SR.getStart() - SecBlock.getAddress();
-    Sec.size = SR.getSize();
-    Sec.flags = MachO::S_REGULAR;
+    memset(&SD.Sec, 0, sizeof(MachO::section_64));
+    memcpy(SD.Sec.sectname, FQName.drop_front(7).data(), FQName.size() - 7);
+    memcpy(SD.Sec.segname, FQName.data(), 6);
+    SD.Sec.addr = SR.getStart() - SecBlock.getAddress();
+    SD.Sec.size = SR.getSize();
+    SD.Sec.flags = MachO::S_REGULAR;
   };
 
   // Add the __objc_imageinfo section.
   {
     DataSections.push_back({});
-    auto &Sec = DataSections.back();
-    memset(&Sec, 0, sizeof(Sec));
-    strcpy(Sec.sectname, "__objc_imageinfo");
-    strcpy(Sec.segname, "__DATA");
-    std::lock_guard<std::mutex> Lock(PluginMutex);
-    auto I = ObjCImageInfos.find(&MR.getTargetJITDylib());
-    assert(I != ObjCImageInfos.end() && "Missing __objc_imageinfo");
-    assert(I->second.Addr && "Null __objc_imageinfo");
-    Sec.addr = I->second.Addr - SecBlock.getAddress();
-    Sec.size = 8;
+    auto &SD = DataSections.back();
+    memset(&SD.Sec, 0, sizeof(SD.Sec));
+    strcpy(SD.Sec.sectname, "__objc_imageinfo");
+    strcpy(SD.Sec.segname, "__DATA");
+    SD.Sec.size = 8;
+    SD.AddFixups = [&](size_t RecordOffset) {
+      jitlink::Edge::Kind PointerEdge = jitlink::Edge::Invalid;
+      switch (G.getTargetTriple().getArch()) {
+      case Triple::aarch64:
+        PointerEdge = jitlink::aarch64::Pointer64;
+        break;
+      case Triple::x86_64:
+        PointerEdge = jitlink::x86_64::Pointer64;
+        break;
+      default:
+        llvm_unreachable("Unsupported architecture");
+      }
+
+      // Look for an existing __objc_imageinfo symbol.
+      jitlink::Symbol *ObjCImageInfoSym = nullptr;
+      for (auto *Sym : G.external_symbols())
+        if (Sym->getName() == ObjCImageInfoSymbolName) {
+          ObjCImageInfoSym = Sym;
+          break;
+        }
+      if (!ObjCImageInfoSym)
+        for (auto *Sym : G.absolute_symbols())
+          if (Sym->getName() == ObjCImageInfoSymbolName) {
+            ObjCImageInfoSym = Sym;
+            break;
+          }
+      if (!ObjCImageInfoSym)
+        for (auto *Sym : G.defined_symbols())
+          if (Sym->hasName() && Sym->getName() == ObjCImageInfoSymbolName) {
+            ObjCImageInfoSym = Sym;
+            break;
+          }
+      if (!ObjCImageInfoSym)
+        ObjCImageInfoSym =
+            &G.addExternalSymbol(ObjCImageInfoSymbolName, 8, false);
+
+      SecBlock.addEdge(PointerEdge,
+                       RecordOffset + ((char *)&SD.Sec.addr - (char *)&SD.Sec),
+                       *ObjCImageInfoSym, -SecBlock.getAddress().getValue());
+    };
   }
 
   for (auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsData) {
@@ -1355,6 +1416,11 @@ Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
     }
   }
 
+  assert(ObjCRuntimeObjectSec->blocks_size() == 1 &&
+         "Unexpected number of blocks in runtime sections object");
+
+  // Build the header struct up-front. This also gives us a chance to check
+  // that the triple is supported, which we'll assume below.
   MachO::mach_header_64 Hdr;
   Hdr.magic = MachO::MH_MAGIC_64;
   switch (G.getTargetTriple().getArch()) {
@@ -1367,9 +1433,7 @@ Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
     Hdr.cpusubtype = MachO::CPU_SUBTYPE_X86_64_ALL;
     break;
   default:
-    return make_error<StringError>("Unrecognized MachO arch in triple " +
-                                       G.getTargetTriple().str(),
-                                   inconvertibleErrorCode());
+    llvm_unreachable("Unsupported architecture");
   }
 
   Hdr.filetype = MachO::MH_DYLIB;
@@ -1380,10 +1444,7 @@ Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
   Hdr.flags = 0;
   Hdr.reserved = 0;
 
-  assert(ObjCRuntimeObjectSec->blocks_size() == 1 &&
-         "Unexpected number of blocks in runtime sections object");
   auto SecContent = SecBlock.getAlreadyMutableContent();
-
   char *P = SecContent.data();
   auto WriteMachOStruct = [&](auto S) {
     if (G.getEndianness() != support::endian::system_endianness())
@@ -1392,8 +1453,7 @@ Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
     P += sizeof(S);
   };
 
-  auto WriteSegment = [&](StringRef Name,
-                          const std::vector<MachO::section_64> &Secs) {
+  auto WriteSegment = [&](StringRef Name, std::vector<SecDesc> &Secs) {
     MachO::segment_command_64 SegLC;
     memset(&SegLC, 0, sizeof(SegLC));
     memcpy(SegLC.segname, Name.data(), Name.size());
@@ -1402,8 +1462,11 @@ Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
                     Secs.size() * sizeof(MachO::section_64);
     SegLC.nsects = Secs.size();
     WriteMachOStruct(SegLC);
-    for (auto &Sec : Secs)
-      WriteMachOStruct(Sec);
+    for (auto &SD : Secs) {
+      if (SD.AddFixups)
+        SD.AddFixups(P - SecContent.data());
+      WriteMachOStruct(SD.Sec);
+    }
   };
 
   WriteMachOStruct(Hdr);


        


More information about the llvm-commits mailing list