Index: lib/ReaderWriter/MachO/ArchHandler_arm64.cpp =================================================================== --- lib/ReaderWriter/MachO/ArchHandler_arm64.cpp +++ lib/ReaderWriter/MachO/ArchHandler_arm64.cpp @@ -668,6 +668,7 @@ *loc64 = ref.addend(); return; case delta64: + case unwindFDEToFunction: *loc64 = ref.addend() + inAtomAddress - fixupAddress; return; case delta32: @@ -692,9 +693,6 @@ case unwindInfoToEhFrame: llvm_unreachable("fixup implies __unwind_info"); return; - case unwindFDEToFunction: - // Do nothing for now - return; case invalid: // Fall into llvm_unreachable(). break; Index: lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h =================================================================== --- lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h +++ lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h @@ -168,7 +168,8 @@ StringRef &segmentName, StringRef §ionName, SectionType §ionType, - SectionAttr §ionAttrs); + SectionAttr §ionAttrs, + bool &allRelocsCanBeImplicit); } // namespace normalized } // namespace mach_o Index: lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp =================================================================== --- lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -50,7 +50,8 @@ struct SectionInfo { SectionInfo(StringRef seg, StringRef sect, SectionType type, - const MachOLinkingContext &ctxt, uint32_t attr=0); + const MachOLinkingContext &ctxt, uint32_t attr, + bool allRelocsCanBeImplicit); StringRef segmentName; StringRef sectionName; @@ -59,15 +60,18 @@ uint64_t address; uint64_t size; uint16_t alignment; + bool allRelocsCanBeImplicit; std::vector 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 allRelocsCanBeImplicit) : segmentName(sg), sectionName(sct), type(t), attributes(attrs), address(0), size(0), alignment(1), + allRelocsCanBeImplicit(allRelocsCanBeImplicit), normalizedSectionIndex(0), finalSectionIndex(0) { uint16_t align = 1; if (ctxt.sectionAligned(segmentName, sectionName, align)) { @@ -193,10 +197,12 @@ StringRef sectionName; SectionType sectionType; SectionAttr sectionAttrs; + bool allRelocsCanBeImplicit; // Use same table used by when parsing .o files. relocatableSectionInfoForContentType(type, segmentName, sectionName, - sectionType, sectionAttrs); + sectionType, sectionAttrs, + allRelocsCanBeImplicit); // 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 +213,8 @@ } // Otherwise allocate new SectionInfo object. auto *sect = new (_allocator) - SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs); + SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs, + allRelocsCanBeImplicit); _sectionInfos.push_back(sect); _sectionMap[type] = sect; return sect; @@ -286,8 +293,10 @@ } } // Otherwise allocate new SectionInfo object. + bool allRelocsCanBeImplicit = false; auto *sect = new (_allocator) SectionInfo( - p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs); + p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs, + allRelocsCanBeImplicit); _sectionInfos.push_back(sect); _sectionMap[atomType] = sect; return sect; @@ -320,7 +329,8 @@ 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, false); _customSections.push_back(sect); _sectionInfos.push_back(sect); return sect; @@ -1035,6 +1045,10 @@ Section &normSect = file.sections[si->normalizedSectionIndex]; for (const AtomInfo &info : si->atomsAndOffsets) { const DefinedAtom *atom = info.atom; + // Skip emitting relocs for sections which are always able to be + // implicitly regenerated. + if (si->allRelocsCanBeImplicit) + continue; for (const Reference *ref : *atom) { _archHandler.appendSectionRelocations(*atom, info.offsetInSection, *ref, symIndexForAtom, Index: lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp =================================================================== --- lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -1034,7 +1034,8 @@ StringRef &segmentName, StringRef §ionName, SectionType §ionType, - SectionAttr §ionAttrs) { + SectionAttr §ionAttrs, + bool &allRelocsCanBeImplicit) { for (const MachORelocatableSectionToAtomType *p = sectsToAtomType ; p->atomType != DefinedAtom::typeUnknown; ++p) { @@ -1047,8 +1048,11 @@ sectionName = p->sectionName; sectionType = p->sectionType; sectionAttrs = 0; + allRelocsCanBeImplicit = false; if (atomType == DefinedAtom::typeCode) sectionAttrs = S_ATTR_PURE_INSTRUCTIONS; + if (atomType == DefinedAtom::typeCFI) + allRelocsCanBeImplicit = true; return; } llvm_unreachable("content type not yet supported"); Index: test/mach-o/arm64-reloc-negDelta32-fixup.yaml =================================================================== --- test/mach-o/arm64-reloc-negDelta32-fixup.yaml +++ test/mach-o/arm64-reloc-negDelta32-fixup.yaml @@ -7,7 +7,7 @@ # We don't emit these in to the binary as relocations, so we need to # make sure that the offset in the FDE to the CIE is the correct value. # CHECK: 0010 10000000 00000000 017a5200 01781e01 -# CHECK: 0020 100c1f00 20000000 18000000 e4ffffff +# CHECK: 0020 100c1f00 20000000 18000000 f8ffffff # Note, this one that matters ^~~~~~~~ # It needs to be 0x18 as that is the offset back to 0 where the CIE is. # CHECK: 0030 ffffffff 20000000 00000000 00480e10 Index: test/mach-o/do-not-emit-unwind-fde-arm64.yaml =================================================================== --- /dev/null +++ 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