[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:
Lang Hames
2021-03-25 17:52:27 -07:00
parent 594e0ba969
commit 19e402d2b3
7 changed files with 61 additions and 40 deletions

View File

@@ -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();
};

View File

@@ -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";
});

View File

@@ -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()))

View File

@@ -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();

View File

@@ -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(

View File

@@ -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:

View File

@@ -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: