[JITLink][MachO] Use full <segment>,<section> names for MachO jitlink::Sections.
JITLink now requires section names to be unique. In MachO section names are only guaranteed to be unique within their containing segment (e.g. a '__const' section in the '__DATA' segment does not clash with a '__const' section in the '__TEXT' segment), so we need to use the fully qualified <segment>,<section> section names (e.g. '__DATA,__const' or '__TEXT,__const') when constructing jitlink::Sections for MachO objects.
This commit is contained in:
@@ -774,7 +774,7 @@ createEHFrameRecorderPass(const Triple &TT,
|
||||
StoreFrameRangeFunction StoreRangeAddress) {
|
||||
const char *EHFrameSectionName = nullptr;
|
||||
if (TT.getObjectFormat() == Triple::MachO)
|
||||
EHFrameSectionName = "__eh_frame";
|
||||
EHFrameSectionName = "__TEXT,__eh_frame";
|
||||
else
|
||||
EHFrameSectionName = ".eh_frame";
|
||||
|
||||
@@ -791,8 +791,9 @@ createEHFrameRecorderPass(const Triple &TT,
|
||||
Size = R.getSize();
|
||||
}
|
||||
if (Addr == 0 && Size != 0)
|
||||
return make_error<JITLinkError>("__eh_frame section can not have zero "
|
||||
"address with non-zero size");
|
||||
return make_error<JITLinkError>(
|
||||
StringRef(EHFrameSectionName) +
|
||||
" section can not have zero address with non-zero size");
|
||||
StoreFrameRange(Addr, Size);
|
||||
return Error::success();
|
||||
};
|
||||
|
||||
@@ -116,10 +116,6 @@ Error MachOLinkGraphBuilder::createNormalizedSections() {
|
||||
|
||||
auto SecIndex = Obj.getSectionIndex(SecRef.getRawDataRefImpl());
|
||||
|
||||
auto Name = SecRef.getName();
|
||||
if (!Name)
|
||||
return Name.takeError();
|
||||
|
||||
if (Obj.is64Bit()) {
|
||||
const MachO::section_64 &Sec64 =
|
||||
Obj.getSection64(SecRef.getRawDataRefImpl());
|
||||
@@ -150,8 +146,9 @@ Error MachOLinkGraphBuilder::createNormalizedSections() {
|
||||
}
|
||||
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " " << *Name << ": " << formatv("{0:x16}", NSec.Address)
|
||||
<< " -- " << formatv("{0:x16}", NSec.Address + NSec.Size)
|
||||
dbgs() << " " << NSec.SegName << "," << NSec.SectName << ": "
|
||||
<< formatv("{0:x16}", NSec.Address) << " -- "
|
||||
<< formatv("{0:x16}", NSec.Address + NSec.Size)
|
||||
<< ", align: " << NSec.Alignment << ", index: " << SecIndex
|
||||
<< "\n";
|
||||
});
|
||||
@@ -182,10 +179,12 @@ Error MachOLinkGraphBuilder::createNormalizedSections() {
|
||||
sys::Memory::MF_WRITE);
|
||||
|
||||
if (!isDebugSection(NSec))
|
||||
NSec.GraphSection = &G->createSection(*Name, Prot);
|
||||
NSec.GraphSection = &G->createSection(
|
||||
G->allocateString(StringRef(NSec.SegName) + "," + NSec.SectName),
|
||||
Prot);
|
||||
else
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " " << *Name
|
||||
dbgs() << " " << NSec.SegName << "," << NSec.SectName
|
||||
<< " is a debug section: No graph section will be created.\n";
|
||||
});
|
||||
|
||||
|
||||
@@ -625,10 +625,11 @@ void link_MachO_x86_64(std::unique_ptr<LinkGraph> G,
|
||||
|
||||
if (Ctx->shouldAddDefaultTargetPasses(G->getTargetTriple())) {
|
||||
// Add eh-frame passses.
|
||||
Config.PrePrunePasses.push_back(EHFrameSplitter("__eh_frame"));
|
||||
StringRef EHFrameSectionName = "__TEXT,__eh_frame";
|
||||
Config.PrePrunePasses.push_back(EHFrameSplitter(EHFrameSectionName));
|
||||
Config.PrePrunePasses.push_back(
|
||||
EHFrameEdgeFixer("__eh_frame", G->getPointerSize(), x86_64::Delta64,
|
||||
x86_64::Delta32, x86_64::NegDelta32));
|
||||
EHFrameEdgeFixer(EHFrameSectionName, G->getPointerSize(),
|
||||
x86_64::Delta64, x86_64::Delta32, x86_64::NegDelta32));
|
||||
|
||||
// Add a mark-live pass.
|
||||
if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple()))
|
||||
|
||||
@@ -306,9 +306,12 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig(
|
||||
|
||||
Config.PrePrunePasses.push_back([this, &MR](jitlink::LinkGraph &G) -> Error {
|
||||
JITLinkSymbolVector InitSectionSymbols;
|
||||
preserveInitSectionIfPresent(InitSectionSymbols, G, "__mod_init_func");
|
||||
preserveInitSectionIfPresent(InitSectionSymbols, G, "__objc_selrefs");
|
||||
preserveInitSectionIfPresent(InitSectionSymbols, G, "__objc_classlist");
|
||||
preserveInitSectionIfPresent(InitSectionSymbols, G,
|
||||
"__DATA,__mod_init_func");
|
||||
preserveInitSectionIfPresent(InitSectionSymbols, G,
|
||||
"__DATA,__objc_selrefs");
|
||||
preserveInitSectionIfPresent(InitSectionSymbols, G,
|
||||
"__DATA,__objc_classlist");
|
||||
|
||||
if (!InitSectionSymbols.empty()) {
|
||||
std::lock_guard<std::mutex> Lock(InitScraperMutex);
|
||||
@@ -327,25 +330,27 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig(
|
||||
ObjCClassList;
|
||||
|
||||
JITTargetAddress ObjCImageInfoAddr = 0;
|
||||
if (auto *ObjCImageInfoSec = G.findSectionByName("__objc_image_info")) {
|
||||
if (auto *ObjCImageInfoSec =
|
||||
G.findSectionByName("__DATA,__objc_image_info")) {
|
||||
if (auto Addr = jitlink::SectionRange(*ObjCImageInfoSec).getStart())
|
||||
ObjCImageInfoAddr = Addr;
|
||||
}
|
||||
|
||||
// Record __mod_init_func.
|
||||
if (auto ModInitsOrErr = getSectionExtent(G, "__mod_init_func"))
|
||||
if (auto ModInitsOrErr = getSectionExtent(G, "__DATA,__mod_init_func"))
|
||||
ModInits = std::move(*ModInitsOrErr);
|
||||
else
|
||||
return ModInitsOrErr.takeError();
|
||||
|
||||
// Record __objc_selrefs.
|
||||
if (auto ObjCSelRefsOrErr = getSectionExtent(G, "__objc_selrefs"))
|
||||
if (auto ObjCSelRefsOrErr = getSectionExtent(G, "__DATA,__objc_selrefs"))
|
||||
ObjCSelRefs = std::move(*ObjCSelRefsOrErr);
|
||||
else
|
||||
return ObjCSelRefsOrErr.takeError();
|
||||
|
||||
// Record __objc_classlist.
|
||||
if (auto ObjCClassListOrErr = getSectionExtent(G, "__objc_classlist"))
|
||||
if (auto ObjCClassListOrErr =
|
||||
getSectionExtent(G, "__DATA,__objc_classlist"))
|
||||
ObjCClassList = std::move(*ObjCClassListOrErr);
|
||||
else
|
||||
return ObjCClassListOrErr.takeError();
|
||||
|
||||
@@ -381,7 +381,9 @@ private:
|
||||
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
||||
|
||||
StringRef SectionName;
|
||||
std::tie(SectionName, RemainingExpr) = parseSymbol(RemainingExpr);
|
||||
size_t CloseParensIdx = RemainingExpr.find(')');
|
||||
SectionName = RemainingExpr.substr(0, CloseParensIdx).rtrim();
|
||||
RemainingExpr = RemainingExpr.substr(CloseParensIdx).ltrim();
|
||||
|
||||
if (!RemainingExpr.startswith(")"))
|
||||
return std::make_pair(
|
||||
|
||||
@@ -147,13 +147,15 @@ Lanon_data:
|
||||
# anonymous.
|
||||
#
|
||||
# Note: +8 offset in expression below to accounts for sizeof(Lanon_data).
|
||||
# jitlink-check: *{8}(section_addr(macho_reloc.o, __data) + 8) = (section_addr(macho_reloc.o, __data) + 8) - named_data + 2
|
||||
# jitlink-check: *{8}(section_addr(macho_reloc.o, __DATA,__data) + 8) = \
|
||||
# jitlink-check: (section_addr(macho_reloc.o, __DATA,__data) + 8) - named_data + 2
|
||||
.p2align 3
|
||||
Lanon_minuend_quad:
|
||||
.quad Lanon_minuend_quad - named_data + 2
|
||||
|
||||
# Note: +16 offset in expression below to accounts for sizeof(Lanon_data) + sizeof(Lanon_minuend_long).
|
||||
# jitlink-check: *{4}(section_addr(macho_reloc.o, __data) + 16) = ((section_addr(macho_reloc.o, __data) + 16) - named_data + 2)[31:0]
|
||||
# jitlink-check: *{4}(section_addr(macho_reloc.o, __DATA,__data) + 16) = \
|
||||
# jitlink-check: ((section_addr(macho_reloc.o, __DATA,__data) + 16) - named_data + 2)[31:0]
|
||||
.p2align 2
|
||||
Lanon_minuend_long:
|
||||
.long Lanon_minuend_long - named_data + 2
|
||||
@@ -185,7 +187,8 @@ named_func_addr_quad:
|
||||
# Check ARM64_RELOC_UNSIGNED / quad / non-extern handling by putting the
|
||||
# address of a local anonymous function into a quad symbol.
|
||||
#
|
||||
# jitlink-check: *{8}anon_func_addr_quad = section_addr(macho_reloc.o, __text)
|
||||
# jitlink-check: *{8}anon_func_addr_quad = \
|
||||
# jitlink-check: section_addr(macho_reloc.o, __TEXT,__text)
|
||||
.globl anon_func_addr_quad
|
||||
.p2align 3
|
||||
anon_func_addr_quad:
|
||||
@@ -193,7 +196,8 @@ anon_func_addr_quad:
|
||||
|
||||
# ARM64_RELOC_SUBTRACTOR Quad/Long in named storage with anonymous minuend
|
||||
#
|
||||
# jitlink-check: *{8}anon_minuend_quad1 = section_addr(macho_reloc.o, __data) - anon_minuend_quad1 + 2
|
||||
# jitlink-check: *{8}anon_minuend_quad1 = \
|
||||
# jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - anon_minuend_quad1 + 2
|
||||
# Only the form "B: .quad LA - B + C" is tested. The form "B: .quad B - LA + C" is
|
||||
# invalid because the subtrahend can not be local.
|
||||
.globl anon_minuend_quad1
|
||||
@@ -201,7 +205,8 @@ anon_func_addr_quad:
|
||||
anon_minuend_quad1:
|
||||
.quad Lanon_data - anon_minuend_quad1 + 2
|
||||
|
||||
# jitlink-check: *{4}anon_minuend_long1 = (section_addr(macho_reloc.o, __data) - anon_minuend_long1 + 2)[31:0]
|
||||
# jitlink-check: *{4}anon_minuend_long1 = \
|
||||
# jitlink-check: (section_addr(macho_reloc.o, __DATA,__data) - anon_minuend_long1 + 2)[31:0]
|
||||
.globl anon_minuend_long1
|
||||
.p2align 2
|
||||
anon_minuend_long1:
|
||||
@@ -308,14 +313,14 @@ test_got:
|
||||
# ORC responsibility set, which is automatically marked live and would couse
|
||||
# spurious passes.
|
||||
#
|
||||
# jitlink-check: *{8}section_addr(macho_reloc.o, __nds_test_sect) = 0
|
||||
# jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_sect) = 0
|
||||
.section __DATA,__nds_test_sect,regular,no_dead_strip
|
||||
.quad 0
|
||||
|
||||
# Check that unreferenced local symbols that have been marked no-dead-strip are
|
||||
# not dead-striped.
|
||||
#
|
||||
# jitlink-check: *{8}section_addr(macho_reloc.o, __nds_test_nlst) = 0
|
||||
# jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_nlst) = 0
|
||||
.section __DATA,__nds_test_nlst,regular
|
||||
.no_dead_strip no_dead_strip_test_symbol
|
||||
no_dead_strip_test_symbol:
|
||||
|
||||
@@ -106,22 +106,26 @@ signed4:
|
||||
movl $0xAAAAAAAA, named_data(%rip)
|
||||
|
||||
.globl signedanon
|
||||
# jitlink-check: decode_operand(signedanon, 4) = section_addr(macho_reloc.o, __data) - next_pc(signedanon)
|
||||
# jitlink-check: decode_operand(signedanon, 4) = \
|
||||
# jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - next_pc(signedanon)
|
||||
signedanon:
|
||||
movq Lanon_data(%rip), %rax
|
||||
|
||||
.globl signed1anon
|
||||
# jitlink-check: decode_operand(signed1anon, 3) = section_addr(macho_reloc.o, __data) - next_pc(signed1anon)
|
||||
# jitlink-check: decode_operand(signed1anon, 3) = \
|
||||
# jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - next_pc(signed1anon)
|
||||
signed1anon:
|
||||
movb $0xAA, Lanon_data(%rip)
|
||||
|
||||
.globl signed2anon
|
||||
# jitlink-check: decode_operand(signed2anon, 3) = section_addr(macho_reloc.o, __data) - next_pc(signed2anon)
|
||||
# jitlink-check: decode_operand(signed2anon, 3) = \
|
||||
# jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - next_pc(signed2anon)
|
||||
signed2anon:
|
||||
movw $0xAAAA, Lanon_data(%rip)
|
||||
|
||||
.globl signed4anon
|
||||
# jitlink-check: decode_operand(signed4anon, 3) = section_addr(macho_reloc.o, __data) - next_pc(signed4anon)
|
||||
# jitlink-check: decode_operand(signed4anon, 3) = \
|
||||
# jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - next_pc(signed4anon)
|
||||
signed4anon:
|
||||
movl $0xAAAAAAAA, Lanon_data(%rip)
|
||||
|
||||
@@ -140,13 +144,15 @@ Lanon_data:
|
||||
# anonymous.
|
||||
#
|
||||
# Note: +8 offset in expression below to accounts for sizeof(Lanon_data).
|
||||
# jitlink-check: *{8}(section_addr(macho_reloc.o, __data) + 8) = (section_addr(macho_reloc.o, __data) + 8) - named_data - 2
|
||||
# jitlink-check: *{8}(section_addr(macho_reloc.o, __DATA,__data) + 8) = \
|
||||
# jitlink-check: (section_addr(macho_reloc.o, __DATA,__data) + 8) - named_data - 2
|
||||
.p2align 3
|
||||
Lanon_minuend_quad:
|
||||
.quad Lanon_minuend_quad - named_data - 2
|
||||
|
||||
# Note: +16 offset in expression below to accounts for sizeof(Lanon_data) + sizeof(Lanon_minuend_long).
|
||||
# jitlink-check: *{4}(section_addr(macho_reloc.o, __data) + 16) = ((section_addr(macho_reloc.o, __data) + 16) - named_data - 2)[31:0]
|
||||
# jitlink-check: *{4}(section_addr(macho_reloc.o, __DATA,__data) + 16) = \
|
||||
# jitlink-check: ((section_addr(macho_reloc.o, __DATA,__data) + 16) - named_data - 2)[31:0]
|
||||
.p2align 2
|
||||
Lanon_minuend_long:
|
||||
.long Lanon_minuend_long - named_data - 2
|
||||
@@ -185,7 +191,7 @@ named_func_addr_long:
|
||||
# Check X86_64_RELOC_UNSIGNED / quad / non-extern handling by putting the
|
||||
# address of a local anonymous function into a quad symbol.
|
||||
#
|
||||
# jitlink-check: *{8}anon_func_addr_quad = section_addr(macho_reloc.o, __text)
|
||||
# jitlink-check: *{8}anon_func_addr_quad = section_addr(macho_reloc.o, __TEXT,__text)
|
||||
.globl anon_func_addr_quad
|
||||
.p2align 3
|
||||
anon_func_addr_quad:
|
||||
@@ -193,7 +199,8 @@ anon_func_addr_quad:
|
||||
|
||||
# X86_64_RELOC_SUBTRACTOR Quad/Long in named storage with anonymous minuend
|
||||
#
|
||||
# jitlink-check: *{8}anon_minuend_quad1 = section_addr(macho_reloc.o, __data) - anon_minuend_quad1 - 2
|
||||
# jitlink-check: *{8}anon_minuend_quad1 = \
|
||||
# jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - anon_minuend_quad1 - 2
|
||||
# Only the form "B: .quad LA - B + C" is tested. The form "B: .quad B - LA + C" is
|
||||
# invalid because the subtrahend can not be local.
|
||||
.globl anon_minuend_quad1
|
||||
@@ -201,7 +208,8 @@ anon_func_addr_quad:
|
||||
anon_minuend_quad1:
|
||||
.quad Lanon_data - anon_minuend_quad1 - 2
|
||||
|
||||
# jitlink-check: *{4}anon_minuend_long1 = (section_addr(macho_reloc.o, __data) - anon_minuend_long1 - 2)[31:0]
|
||||
# jitlink-check: *{4}anon_minuend_long1 = \
|
||||
# jitlink-check: (section_addr(macho_reloc.o, __DATA,__data) - anon_minuend_long1 - 2)[31:0]
|
||||
.globl anon_minuend_long1
|
||||
.p2align 2
|
||||
anon_minuend_long1:
|
||||
@@ -311,14 +319,14 @@ test_got:
|
||||
# ORC responsibility set, which is automatically marked live and would couse
|
||||
# spurious passes.
|
||||
#
|
||||
# jitlink-check: *{8}section_addr(macho_reloc.o, __nds_test_sect) = 0
|
||||
# jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_sect) = 0
|
||||
.section __DATA,__nds_test_sect,regular,no_dead_strip
|
||||
.quad 0
|
||||
|
||||
# Check that unreferenced local symbols that have been marked no-dead-strip are
|
||||
# not dead-striped.
|
||||
#
|
||||
# jitlink-check: *{8}section_addr(macho_reloc.o, __nds_test_nlst) = 0
|
||||
# jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_nlst) = 0
|
||||
.section __DATA,__nds_test_nlst,regular
|
||||
.no_dead_strip no_dead_strip_test_symbol
|
||||
no_dead_strip_test_symbol:
|
||||
|
||||
Reference in New Issue
Block a user