[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