summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h3
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp33
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp6
-rw-r--r--lld/test/mach-o/do-not-emit-unwind-fde-arm64.yaml175
4 files changed, 209 insertions, 8 deletions
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
index 613c1b2f251..1226860b021 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
@@ -168,7 +168,8 @@ void relocatableSectionInfoForContentType(DefinedAtom::ContentType atomType,
StringRef &segmentName,
StringRef &sectionName,
SectionType &sectionType,
- SectionAttr &sectionAttrs);
+ SectionAttr &sectionAttrs,
+ bool &relocsToDefinedCanBeImplicit);
} // namespace normalized
} // namespace mach_o
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
index e830db9fcc7..575bc1a2b3a 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
@@ -50,7 +50,8 @@ struct AtomInfo {
struct SectionInfo {
SectionInfo(StringRef seg, StringRef sect, SectionType type,
- const MachOLinkingContext &ctxt, uint32_t attr=0);
+ const MachOLinkingContext &ctxt, uint32_t attr,
+ bool relocsToDefinedCanBeImplicit);
StringRef segmentName;
StringRef sectionName;
@@ -59,15 +60,25 @@ struct SectionInfo {
uint64_t address;
uint64_t size;
uint16_t alignment;
+
+ /// If this is set, the any relocs in this section which point to defined
+ /// addresses can be implicitly generated. This is the case for the
+ /// __eh_frame section where references to the function can be implicit if the
+ /// function is defined.
+ bool relocsToDefinedCanBeImplicit;
+
+
std::vector<AtomInfo> atomsAndOffsets;
uint32_t normalizedSectionIndex;
uint32_t finalSectionIndex;
};
SectionInfo::SectionInfo(StringRef sg, StringRef sct, SectionType t,
- const MachOLinkingContext &ctxt, uint32_t attrs)
+ const MachOLinkingContext &ctxt, uint32_t attrs,
+ bool relocsToDefinedCanBeImplicit)
: segmentName(sg), sectionName(sct), type(t), attributes(attrs),
address(0), size(0), alignment(1),
+ relocsToDefinedCanBeImplicit(relocsToDefinedCanBeImplicit),
normalizedSectionIndex(0), finalSectionIndex(0) {
uint16_t align = 1;
if (ctxt.sectionAligned(segmentName, sectionName, align)) {
@@ -193,10 +204,12 @@ SectionInfo *Util::getRelocatableSection(DefinedAtom::ContentType type) {
StringRef sectionName;
SectionType sectionType;
SectionAttr sectionAttrs;
+ bool relocsToDefinedCanBeImplicit;
// Use same table used by when parsing .o files.
relocatableSectionInfoForContentType(type, segmentName, sectionName,
- sectionType, sectionAttrs);
+ sectionType, sectionAttrs,
+ relocsToDefinedCanBeImplicit);
// If we already have a SectionInfo with this name, re-use it.
// This can happen if two ContentType map to the same mach-o section.
for (auto sect : _sectionMap) {
@@ -207,7 +220,8 @@ SectionInfo *Util::getRelocatableSection(DefinedAtom::ContentType type) {
}
// Otherwise allocate new SectionInfo object.
auto *sect = new (_allocator)
- SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs);
+ SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs,
+ relocsToDefinedCanBeImplicit);
_sectionInfos.push_back(sect);
_sectionMap[type] = sect;
return sect;
@@ -287,7 +301,8 @@ SectionInfo *Util::getFinalSection(DefinedAtom::ContentType atomType) {
}
// Otherwise allocate new SectionInfo object.
auto *sect = new (_allocator) SectionInfo(
- p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs);
+ p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs,
+ /* relocsToDefinedCanBeImplicit */ false);
_sectionInfos.push_back(sect);
_sectionMap[atomType] = sect;
return sect;
@@ -320,7 +335,8 @@ SectionInfo *Util::sectionForAtom(const DefinedAtom *atom) {
StringRef segName = customName.slice(0, seperatorIndex);
StringRef sectName = customName.drop_front(seperatorIndex + 1);
auto *sect =
- new (_allocator) SectionInfo(segName, sectName, S_REGULAR, _ctx);
+ new (_allocator) SectionInfo(segName, sectName, S_REGULAR, _ctx,
+ 0, /* relocsToDefinedCanBeImplicit */ false);
_customSections.push_back(sect);
_sectionInfos.push_back(sect);
return sect;
@@ -1024,6 +1040,11 @@ void Util::addSectionRelocs(const lld::File &, NormalizedFile &file) {
for (const AtomInfo &info : si->atomsAndOffsets) {
const DefinedAtom *atom = info.atom;
for (const Reference *ref : *atom) {
+ // Skip emitting relocs for sections which are always able to be
+ // implicitly regenerated and where the relocation targets an address
+ // which is defined.
+ if (si->relocsToDefinedCanBeImplicit && isa<DefinedAtom>(ref->target()))
+ continue;
_archHandler.appendSectionRelocations(*atom, info.offsetInSection, *ref,
symIndexForAtom,
sectIndexForAtom,
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
index 1c4bb1d4f6a..f9499b60321 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
@@ -1034,7 +1034,8 @@ void relocatableSectionInfoForContentType(DefinedAtom::ContentType atomType,
StringRef &segmentName,
StringRef &sectionName,
SectionType &sectionType,
- SectionAttr &sectionAttrs) {
+ SectionAttr &sectionAttrs,
+ bool &relocsToDefinedCanBeImplicit) {
for (const MachORelocatableSectionToAtomType *p = sectsToAtomType ;
p->atomType != DefinedAtom::typeUnknown; ++p) {
@@ -1047,8 +1048,11 @@ void relocatableSectionInfoForContentType(DefinedAtom::ContentType atomType,
sectionName = p->sectionName;
sectionType = p->sectionType;
sectionAttrs = 0;
+ relocsToDefinedCanBeImplicit = false;
if (atomType == DefinedAtom::typeCode)
sectionAttrs = S_ATTR_PURE_INSTRUCTIONS;
+ if (atomType == DefinedAtom::typeCFI)
+ relocsToDefinedCanBeImplicit = true;
return;
}
llvm_unreachable("content type not yet supported");
diff --git a/lld/test/mach-o/do-not-emit-unwind-fde-arm64.yaml b/lld/test/mach-o/do-not-emit-unwind-fde-arm64.yaml
new file mode 100644
index 00000000000..4a121252fc6
--- /dev/null
+++ b/lld/test/mach-o/do-not-emit-unwind-fde-arm64.yaml
@@ -0,0 +1,175 @@
+# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s
+# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s
+# RUN: llvm-objdump -r -macho %t | FileCheck -check-prefix=CODE %s
+# RUN: llvm-objdump -r -macho %t2 | FileCheck -check-prefix=CODE %s
+
+
+--- !mach-o
+arch: arm64
+file-type: MH_OBJECT
+flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+compat-version: 0.0
+current-version: 0.0
+has-UUID: false
+OS: unknown
+sections:
+ - segment: __TEXT
+ section: __text
+ type: S_REGULAR
+ attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+ alignment: 4
+ address: 0x0000000000000000
+ content: [ 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
+ 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x91,
+ 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x80, 0x52,
+ 0xFD, 0x7B, 0xC1, 0xA8, 0xC0, 0x03, 0x5F, 0xD6 ]
+ relocations:
+ - offset: 0x00000010
+ type: ARM64_RELOC_BRANCH26
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 9
+ - offset: 0x0000000C
+ type: ARM64_RELOC_PAGEOFF12
+ length: 2
+ pc-rel: false
+ extern: true
+ symbol: 1
+ - offset: 0x00000008
+ type: ARM64_RELOC_PAGE21
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 1
+ - segment: __TEXT
+ section: __cstring
+ type: S_CSTRING_LITERALS
+ attributes: [ ]
+ address: 0x0000000000000020
+ content: [ 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F,
+ 0x72, 0x6C, 0x64, 0x00 ]
+ - segment: __LD
+ section: __compact_unwind
+ type: S_REGULAR
+ attributes: [ ]
+ alignment: 8
+ address: 0x0000000000000030
+ content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
+ relocations:
+ - offset: 0x00000000
+ type: ARM64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - segment: __TEXT
+ section: __eh_frame
+ type: S_COALESCED
+ attributes: [ ]
+ alignment: 8
+ address: 0x0000000000000050
+ content: [ 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x7A, 0x50, 0x4C, 0x52, 0x00, 0x01, 0x78,
+ 0x1E, 0x0B, 0x00, 0xED, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0x0C, 0x1F, 0x00,
+ 0x24, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x48, 0x0E, 0x10, 0x9E, 0x01, 0x9D, 0x02 ]
+local-symbols:
+ - name: ltmp0
+ type: N_SECT
+ sect: 1
+ value: 0x0000000000000000
+ - name: L_str
+ type: N_SECT
+ sect: 2
+ value: 0x0000000000000020
+ - name: ltmp1
+ type: N_SECT
+ sect: 2
+ value: 0x0000000000000020
+ - name: ltmp2
+ type: N_SECT
+ sect: 3
+ value: 0x0000000000000030
+ - name: ltmp3
+ type: N_SECT
+ sect: 4
+ value: 0x0000000000000050
+ - name: ltmp4
+ type: N_SECT
+ sect: 4
+ value: 0x0000000000000070
+global-symbols:
+ - name: __Z3fooi
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000000
+undefined-symbols:
+ - name: __gxx_personality_v0
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: _bar
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: _puts
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+page-size: 0x00000000
+
+# CHECK: defined-atoms:
+# CHECK: - ref-name: L{{[0-9]*}}
+# CHECK: scope: hidden
+# CHECK: type: c-string
+# CHECK: content: [ 48, 65, 6C, 6C, 6F, 20, 77, 6F, 72, 6C, 64, 00 ]
+# CHECK: merge: by-content
+# CHECK: type: unwind-cfi
+# CHECK: content: [ 1C, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 50, 4C,
+# CHECK: 52, 00, 01, 78, 1E, 0B, 00, ED, FF, FF, FF, FF,
+# CHECK: FF, FF, FF, 00, 10, 0C, 1F, 00 ]
+# CHECK: alignment: 8
+# CHECK: - ref-name: L{{[0-9]*}}
+# CHECK: type: unwind-cfi
+# CHECK: content: [ 24, 00, 00, 00, 24, 00, 00, 00, 00, 00, 00, 00,
+# CHECK: 00, 00, 00, 00, 20, 00, 00, 00, 00, 00, 00, 00,
+# CHECK: 08, 00, 00, 00, 00, 00, 00, 00, 00, 48, 0E, 10,
+# CHECK: 9E, 01, 9D, 02 ]
+# CHECK: alignment: 8
+# CHECK: - type: compact-unwind
+# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00, 20, 00, 00, 00,
+# CHECK: 00, 00, 00, 03, 00, 00, 00, 00, 00, 00, 00, 00,
+# CHECK: 00, 00, 00, 00, 00, 00, 00, 00 ]
+# CHECK: alignment: 8
+# CHECK: references:
+# CHECK: - kind: pointer64
+# CHECK: offset: 0
+# CHECK: target: __Z3fooi
+# CHECK: - name: __Z3fooi
+# CHECK: scope: global
+# CHECK: content: [ FD, 7B, BF, A9, FD, 03, 00, 91, 00, 00, 00, 90,
+# CHECK: 00, 00, 00, 91, 00, 00, 00, 94, 00, 00, 80, 52,
+# CHECK: FD, 7B, C1, A8, C0, 03, 5F, D6 ]
+# CHECK: alignment: 4
+# CHECK: references:
+# CHECK: - kind: page21
+# CHECK: offset: 8
+# CHECK: target: L{{[0-9]*}}
+# CHECK: - kind: offset12
+# CHECK: offset: 12
+# CHECK: target: L{{[0-9]*}}
+# CHECK: - kind: branch26
+# CHECK: offset: 16
+# CHECK: target: _puts
+
+# Make sure we don't have any relocations in the __eh_frame section
+# CODE-NOT: __eh_frame \ No newline at end of file
OpenPOWER on IntegriCloud