From: Tim Northover Date: Wed, 15 Oct 2014 19:32:21 +0000 (+0000) Subject: [mach-o] make __unwind_info defer to __eh_frame when necessary. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1cc4fb76dab305da4e6e1aa8acd25c00ba4c06ad;p=platform%2Fupstream%2Fllvm.git [mach-o] make __unwind_info defer to __eh_frame when necessary. Not all situations are representable in the compressed __unwind_info format, and when this happens the entry needs to point to the more general __eh_frame description. Just x86_64 implementation for now. rdar://problem/18208653 llvm-svn: 219836 --- diff --git a/lld/include/lld/Core/Simple.h b/lld/include/lld/Core/Simple.h index 307f454..ee29f5b 100644 --- a/lld/include/lld/Core/Simple.h +++ b/lld/include/lld/Core/Simple.h @@ -168,6 +168,7 @@ public: void addReference(Reference::KindNamespace ns, Reference::KindArch arch, Reference::KindValue kindValue, uint64_t off, const Atom *target, Reference::Addend a) { + assert(target && "trying to create reference to nothing"); _references.push_back(SimpleReference(ns, arch, kindValue, off, target, a)); } diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler.cpp index 8fd77d1..3fa1fb3 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler.cpp @@ -142,6 +142,17 @@ int64_t ArchHandler::readS64(bool swap, const uint8_t *addr) { return read64(swap, *reinterpret_cast(addr)); } +bool ArchHandler::isDwarfCIE(bool swap, const DefinedAtom *atom) { + assert(atom->contentType() == DefinedAtom::typeCFI); + uint32_t size = read32(swap, *(uint32_t *)atom->rawContent().data()); + + uint32_t idOffset = sizeof(uint32_t); + if (size == 0xffffffffU) + idOffset += sizeof(uint64_t); + + return read32(swap, *(uint32_t *)(atom->rawContent().data() + idOffset)) == 0; +} + } // namespace mach_o } // namespace lld diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler.h b/lld/lib/ReaderWriter/MachO/ArchHandler.h index 51994b5..9c994b7 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler.h +++ b/lld/lib/ReaderWriter/MachO/ArchHandler.h @@ -70,11 +70,21 @@ public: /// section. virtual Reference::KindValue imageOffsetKindIndirect() = 0; + /// Architecture specific compact unwind type that signals __eh_frame should + /// actually be used. + virtual uint32_t dwarfCompactUnwindType() = 0; + /// Reference from an __eh_frame FDE atom to the function it's /// describing. Usually pointer-sized and PC-relative, but differs in whether /// it needs to be in relocatable objects. virtual Reference::KindValue unwindRefToFunctionKind() = 0; + /// Reference from an __unwind_info entry of dwarfCompactUnwindType to the + /// required __eh_frame entry. On current architectures, the low 24 bits + /// represent the offset of the function's FDE entry from the start of + /// __eh_frame. + virtual Reference::KindValue unwindRefToEhFrameKind() = 0; + /// Used by normalizedFromAtoms() to know where to generated rebasing and /// binding info in final executables. virtual bool isPointer(const Reference &) = 0; @@ -148,6 +158,7 @@ public: /// Copy raw content then apply all fixup References on an Atom. virtual void generateAtomContent(const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress, + FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress, uint8_t *atomContentBuffer) = 0; @@ -196,6 +207,9 @@ public: llvm_unreachable("shims only support on arm"); } + /// Does a given unwind-cfi atom represent a CIE (as opposed to an FDE). + static bool isDwarfCIE(bool swap, const DefinedAtom *atom); + struct ReferenceInfo { Reference::KindArch arch; uint16_t kind; diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp index 163421a..147d921 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp @@ -52,6 +52,15 @@ public: return invalid; } + Reference::KindValue unwindRefToEhFrameKind() override { + return invalid; + } + + uint32_t dwarfCompactUnwindType() override { + // FIXME + return -1; + } + std::error_code getReferenceInfo(const normalized::Relocation &reloc, const DefinedAtom *inAtom, uint32_t offsetInAtom, @@ -75,6 +84,7 @@ public: void generateAtomContent(const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress, + FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress, uint8_t *atomContentBuffer) override; @@ -994,6 +1004,7 @@ void ArchHandler_arm::applyFixupFinal(const Reference &ref, uint8_t *location, void ArchHandler_arm::generateAtomContent(const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress, + FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress, uint8_t *atomContentBuffer) { // Copy raw bytes. diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp index eb6a460..099c553 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp @@ -95,6 +95,15 @@ public: return invalid; } + Reference::KindValue unwindRefToEhFrameKind() override { + return invalid; + } + + uint32_t dwarfCompactUnwindType() override { + // FIXME + return -1; + } + std::error_code getReferenceInfo(const normalized::Relocation &reloc, const DefinedAtom *inAtom, uint32_t offsetInAtom, @@ -122,6 +131,7 @@ public: void generateAtomContent(const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress, + FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress, uint8_t *atomContentBuffer) override; @@ -457,11 +467,10 @@ std::error_code ArchHandler_arm64::getPairReferenceInfo( } } -void ArchHandler_arm64::generateAtomContent(const DefinedAtom &atom, - bool relocatable, - FindAddressForAtom findAddress, - uint64_t imageBaseAddress, - uint8_t *atomContentBuffer) { +void ArchHandler_arm64::generateAtomContent( + const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress, + FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress, + uint8_t *atomContentBuffer) { // Copy raw bytes. memcpy(atomContentBuffer, atom.rawContent().data(), atom.size()); // Apply fix-ups. diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp index bd086f2..7576662 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp @@ -55,6 +55,15 @@ public: return delta32; } + Reference::KindValue unwindRefToEhFrameKind() override { + return invalid; + } + + + uint32_t dwarfCompactUnwindType() override { + return 0x04000000U; + } + std::error_code getReferenceInfo(const normalized::Relocation &reloc, const DefinedAtom *inAtom, uint32_t offsetInAtom, @@ -78,6 +87,7 @@ public: void generateAtomContent(const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress, + FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress, uint8_t *atomContentBuffer) override; @@ -386,6 +396,7 @@ ArchHandler_x86::getPairReferenceInfo(const normalized::Relocation &reloc1, void ArchHandler_x86::generateAtomContent(const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress, + FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress, uint8_t *atomContentBuffer) { // Copy raw bytes. diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp index 315aba3..c464087 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp @@ -88,6 +88,13 @@ public: return unwindFDEToFunction; } + Reference::KindValue unwindRefToEhFrameKind() override { + return unwindInfoToEhFrame; + } + + uint32_t dwarfCompactUnwindType() override { + return 0x04000000U; + } const StubInfo &stubInfo() override { return _sStubInfo; } @@ -126,6 +133,7 @@ public: void generateAtomContent(const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress, + FindAddressForAtom findSectionAddress, uint64_t imageBase, uint8_t *atomContentBuffer) override; @@ -172,7 +180,8 @@ private: /// final image (typically personality function). unwindFDEToFunction, /// Nearly delta64, but cannot be rematerialized in /// relocatable object (yay for implicit contracts!). - + unwindInfoToEhFrame, /// Fix low 24 bits of compact unwind encoding to + /// refer to __eh_frame entry. }; Reference::KindValue kindFromReloc(const normalized::Relocation &reloc); @@ -181,7 +190,8 @@ private: void applyFixupFinal(const Reference &ref, uint8_t *location, uint64_t fixupAddress, uint64_t targetAddress, - uint64_t inAtomAddress, uint64_t imageBaseAddress); + uint64_t inAtomAddress, uint64_t imageBaseAddress, + FindAddressForAtom findSectionAddress); void applyFixupRelocatable(const Reference &ref, uint8_t *location, uint64_t fixupAddress, @@ -210,6 +220,7 @@ const Registry::KindStrings ArchHandler_x86_64::_sKindStrings[] = { LLD_KIND_STRING_ENTRY(delta32Anon), LLD_KIND_STRING_ENTRY(delta64Anon), LLD_KIND_STRING_ENTRY(imageOffset), LLD_KIND_STRING_ENTRY(imageOffsetGot), LLD_KIND_STRING_ENTRY(unwindFDEToFunction), + LLD_KIND_STRING_ENTRY(unwindInfoToEhFrame), LLD_KIND_STRING_END }; @@ -424,11 +435,10 @@ ArchHandler_x86_64::getPairReferenceInfo(const normalized::Relocation &reloc1, } } -void ArchHandler_x86_64::generateAtomContent(const DefinedAtom &atom, - bool relocatable, - FindAddressForAtom findAddress, - uint64_t imageBaseAddress, - uint8_t *atomContentBuffer) { +void ArchHandler_x86_64::generateAtomContent( + const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress, + FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress, + uint8_t *atomContentBuffer) { // Copy raw bytes. memcpy(atomContentBuffer, atom.rawContent().data(), atom.size()); // Apply fix-ups. @@ -447,17 +457,15 @@ void ArchHandler_x86_64::generateAtomContent(const DefinedAtom &atom, } else { applyFixupFinal(*ref, &atomContentBuffer[offset], fixupAddress, targetAddress, - atomAddress, imageBaseAddress); + atomAddress, imageBaseAddress, findSectionAddress); } } } -void ArchHandler_x86_64::applyFixupFinal(const Reference &ref, - uint8_t *location, - uint64_t fixupAddress, - uint64_t targetAddress, - uint64_t inAtomAddress, - uint64_t imageBaseAddress) { +void ArchHandler_x86_64::applyFixupFinal( + const Reference &ref, uint8_t *location, uint64_t fixupAddress, + uint64_t targetAddress, uint64_t inAtomAddress, uint64_t imageBaseAddress, + FindAddressForAtom findSectionAddress) { if (ref.kindNamespace() != Reference::KindNamespace::mach_o) return; assert(ref.kindArch() == Reference::KindArch::x86_64); @@ -507,6 +515,13 @@ void ArchHandler_x86_64::applyFixupFinal(const Reference &ref, case imageOffsetGot: write32(*loc32, _swap, (targetAddress - imageBaseAddress) + ref.addend()); return; + case unwindInfoToEhFrame: { + uint64_t val = targetAddress - findSectionAddress(*ref.target()) + ref.addend(); + assert(val < 0xffffffU && "offset in __eh_frame too large"); + uint32_t encoding = read32(_swap, *loc32) & 0xff000000U; + write32(*loc32, _swap, encoding | val); + return; + } case invalid: // Fall into llvm_unreachable(). break; @@ -568,7 +583,8 @@ void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, return; case imageOffset: case imageOffsetGot: - llvm_unreachable("image offset implies __unwind_info"); + case unwindInfoToEhFrame: + llvm_unreachable("fixup implies __unwind_info"); return; case unwindFDEToFunction: // Do nothing for now @@ -658,6 +674,7 @@ void ArchHandler_x86_64::appendSectionRelocations( X86_64_RELOC_UNSIGNED | rLength8 ); return; case unwindFDEToFunction: + case unwindInfoToEhFrame: return; case ripRel32GotLoadNowLea: llvm_unreachable("ripRel32GotLoadNowLea implies GOT pass was run"); diff --git a/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp b/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp index 5eedb5c..4b38212 100644 --- a/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp +++ b/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp @@ -39,9 +39,26 @@ struct CompactUnwindEntry { const Atom *rangeStart; const Atom *personalityFunction; const Atom *lsdaLocation; + const Atom *ehFrame; uint32_t rangeLength; + + // There are 3 types of compact unwind entry, distinguished by the encoding + // value: 0 indicates a function with no unwind info; + // _archHandler.dwarfCompactUnwindType() indicates that the entry defers to + // __eh_frame, and that the ehFrame entry will be valid; any other value is a + // real compact unwind entry -- personalityFunction will be set and + // lsdaLocation may be. uint32_t encoding; + + CompactUnwindEntry(const DefinedAtom *function) + : rangeStart(function), personalityFunction(nullptr), + lsdaLocation(nullptr), ehFrame(nullptr), rangeLength(function->size()), + encoding(0) {} + + CompactUnwindEntry() + : rangeStart(nullptr), personalityFunction(nullptr), + lsdaLocation(nullptr), ehFrame(nullptr), rangeLength(0), encoding(0) {} }; struct UnwindInfoPage { @@ -212,12 +229,23 @@ public: uint32_t pagePos = curPageOffset + headerSize; for (auto &entry : page.entries) { addImageReference(pagePos, entry.rangeStart); + write32(reinterpret_cast(_contents.data() + pagePos)[1], _swap, entry.encoding); + if ((entry.encoding & 0x0f000000U) == + _archHandler.dwarfCompactUnwindType()) + addEhFrameReference(pagePos + sizeof(uint32_t), entry.ehFrame); + pagePos += 2 * sizeof(uint32_t); } } + void addEhFrameReference(uint32_t offset, const Atom *dest, + Reference::Addend addend = 0) { + addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(), + _archHandler.unwindRefToEhFrameKind(), offset, dest, addend); + } + void addImageReference(uint32_t offset, const Atom *dest, Reference::Addend addend = 0) { addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(), @@ -253,15 +281,18 @@ private: void perform(std::unique_ptr &mergedFile) override { DEBUG(llvm::dbgs() << "MachO Compact Unwind pass\n"); - // First collect all __compact_unwind entries, addressable by the function - // it's referring to. std::map unwindLocs; + std::map dwarfFrames; std::vector personalities; uint32_t numLSDAs = 0; + // First collect all __compact_unwind and __eh_frame entries, addressable by + // the function referred to. collectCompactUnwindEntries(mergedFile, unwindLocs, personalities, numLSDAs); + collectDwarfFrameEntries(mergedFile, dwarfFrames); + // FIXME: if there are more than 4 personality functions then we need to // defer to DWARF info for the ones we don't put in the list. They should // also probably be sorted by frequency. @@ -270,8 +301,8 @@ private: // Now sort the entries by final address and fixup the compact encoding to // its final form (i.e. set personality function bits & create DWARF // references where needed). - std::vector unwindInfos = - createUnwindInfoEntries(mergedFile, unwindLocs, personalities); + std::vector unwindInfos = createUnwindInfoEntries( + mergedFile, unwindLocs, personalities, dwarfFrames); // Finally, we can start creating pages based on these entries. @@ -348,7 +379,7 @@ private: } CompactUnwindEntry extractCompactUnwindEntry(const DefinedAtom *atom) { - CompactUnwindEntry entry = {nullptr, nullptr, nullptr, 0, 0}; + CompactUnwindEntry entry; for (const Reference *ref : *atom) { switch (ref->offsetInAtom()) { @@ -376,6 +407,28 @@ private: return entry; } + void + collectDwarfFrameEntries(std::unique_ptr &mergedFile, + std::map &dwarfFrames) { + for (const DefinedAtom *ehFrameAtom : mergedFile->defined()) { + if (ehFrameAtom->contentType() != DefinedAtom::typeCFI || + ArchHandler::isDwarfCIE(_swap, ehFrameAtom)) + continue; + + auto functionRef = std::find_if(ehFrameAtom->begin(), ehFrameAtom->end(), + [&](const Reference *ref) { + return ref->kindNamespace() == Reference::KindNamespace::mach_o && + ref->kindArch() == _archHandler.kindArch() && + ref->kindValue() == _archHandler.unwindRefToFunctionKind(); + }); + + if (functionRef != ehFrameAtom->end()) { + const Atom *functionAtom = functionRef->target(); + dwarfFrames.insert(std::make_pair(functionAtom, ehFrameAtom)); + } + } + } + /// Every atom defined in __TEXT,__text needs an entry in the final /// __unwind_info section (in order). These comes from two sources: /// + Input __compact_unwind sections where possible (after adding the @@ -385,7 +438,8 @@ private: std::vector createUnwindInfoEntries( const std::unique_ptr &mergedFile, const std::map &unwindLocs, - const std::vector &personalities) { + const std::vector &personalities, + const std::map &dwarfFrames) { std::vector unwindInfos; DEBUG(llvm::dbgs() << " Creating __unwind_info entries\n"); @@ -396,8 +450,8 @@ private: if (atom->contentType() != DefinedAtom::typeCode) continue; - unwindInfos.push_back( - finalizeUnwindInfoEntryForAtom(atom, unwindLocs, personalities)); + unwindInfos.push_back(finalizeUnwindInfoEntryForAtom( + atom, unwindLocs, personalities, dwarfFrames)); DEBUG(llvm::dbgs() << " Entry for " << atom->name() << ", final encoding=" @@ -411,20 +465,32 @@ private: CompactUnwindEntry finalizeUnwindInfoEntryForAtom( const DefinedAtom *function, const std::map &unwindLocs, - const std::vector &personalities) { + const std::vector &personalities, + const std::map &dwarfFrames) { auto unwindLoc = unwindLocs.find(function); - // FIXME: we should synthesize a DWARF compact unwind entry before claiming - // there's no unwind if a __compact_unwind atom doesn't exist. + CompactUnwindEntry entry; if (unwindLoc == unwindLocs.end()) { - CompactUnwindEntry entry; - memset(&entry, 0, sizeof(CompactUnwindEntry)); + // Default entry has correct encoding (0 => no unwind), but we need to + // synthesise the function. entry.rangeStart = function; entry.rangeLength = function->size(); - return entry; + } else + entry = unwindLoc->second; + + + // If there's no __compact_unwind entry, or it explicitly says to use + // __eh_frame, we need to try and fill in the correct DWARF atom. + if (entry.encoding == _archHandler.dwarfCompactUnwindType() || + entry.encoding == 0) { + auto dwarfFrame = dwarfFrames.find(function); + if (dwarfFrame != dwarfFrames.end()) { + entry.encoding = _archHandler.dwarfCompactUnwindType(); + entry.ehFrame = dwarfFrame->second; + } } - CompactUnwindEntry entry = unwindLoc->second; + auto personality = std::find(personalities.begin(), personalities.end(), entry.personalityFunction); uint32_t personalityIdx = personality == personalities.end() diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index 3967424..7147c12 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -556,6 +556,14 @@ void Util::copySectionContent(NormalizedFile &file) { return pos->second; }; + auto sectionAddrForAtom = [&] (const Atom &atom) -> uint64_t { + for (const SectionInfo *sectInfo : _sectionInfos) + for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets) + if (atomInfo.atom == &atom) + return sectInfo->address; + llvm_unreachable("atom not assigned to section"); + }; + for (SectionInfo *si : _sectionInfos) { if (si->type == llvm::MachO::S_ZEROFILL) continue; @@ -567,6 +575,7 @@ void Util::copySectionContent(NormalizedFile &file) { uint8_t *atomContent = reinterpret_cast (§ionContent[ai.offsetInSection]); _archHandler.generateAtomContent(*ai.atom, r, addrForAtom, + sectionAddrForAtom, _context.baseAddress(), atomContent); } } diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index a73a279..03fcf05 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -621,17 +621,6 @@ bool isDebugInfoSection(const Section §ion) { return section.segmentName.equals("__DWARF"); } -static bool isCIE(bool swap, const DefinedAtom *atom) { - assert(atom->contentType() == DefinedAtom::typeCFI); - uint32_t size = read32(swap, *(uint32_t *)atom->rawContent().data()); - - uint32_t idOffset = sizeof(uint32_t); - if (size == 0xffffffffU) - idOffset += sizeof(uint64_t); - - return read32(swap, *(uint32_t *)(atom->rawContent().data() + idOffset)) == 0; -} - static int64_t readSPtr(bool is64, bool swap, const uint8_t *addr) { if (is64) return read64(swap, *reinterpret_cast(addr)); @@ -662,7 +651,7 @@ std::error_code addEHFrameReferences(const NormalizedFile &normalizedFile, [&](MachODefinedAtom *atom, uint64_t offset) -> void { assert(atom->contentType() == DefinedAtom::typeCFI); - if (isCIE(swap, atom)) + if (ArchHandler::isDwarfCIE(swap, atom)) return; // Compiler wasn't lazy and actually told us what it meant. diff --git a/lld/test/mach-o/unwind-info-simple-x86_64.yaml b/lld/test/mach-o/unwind-info-simple-x86_64.yaml index e001df9..2c42ada 100644 --- a/lld/test/mach-o/unwind-info-simple-x86_64.yaml +++ b/lld/test/mach-o/unwind-info-simple-x86_64.yaml @@ -13,14 +13,17 @@ # CHECK: Personality functions: (count = 1) # CHECK: personality[1]: 0x00001000 # CHECK: Top level indices: (count = 2) -# CHECK: [0]: function offset=0x00000f7e, 2nd level page offset=0x00000040, LSDA offset=0x00000038 -# CHECK: [1]: function offset=0x00000f80, 2nd level page offset=0x00000000, LSDA offset=0x00000040 +# CHECK: [0]: function offset=0x00000efb, 2nd level page offset=0x00000040, LSDA offset=0x00000038 +# CHECK: [1]: function offset=0x00000f00, 2nd level page offset=0x00000000, LSDA offset=0x00000040 # CHECK: LSDA descriptors: -# CHECK: [0]: function offset=0x00000f7e, LSDA offset=0x00000f80 +# CHECK: [0]: function offset=0x00000efb, LSDA offset=0x00000f00 # CHECK: Second level indices: -# CHECK: Second level index[0]: offset in section=0x00000040, base function offset=0x00000f7e -# CHECK: [0]: function offset=0x00000f7e, encoding=0x51000000 -# CHECK: [1]: function offset=0x00000f7f, encoding=0x01000000 +# CHECK: Second level index[0]: offset in section=0x00000040, base function offset=0x00000efb +# CHECK: [0]: function offset=0x00000efb, encoding=0x51000000 +# CHECK: [1]: function offset=0x00000efc, encoding=0x01000000 +# CHECK: [2]: function offset=0x00000efd, encoding=0x04000018 +# CHECK: [3]: function offset=0x00000efe, encoding=0x04000040 +# CHECK: [4]: function offset=0x00000eff, encoding=0x00000000 --- !native path: '' @@ -53,6 +56,40 @@ defined-atoms: - kind: pointer64Anon offset: 0 target: _main + - type: compact-unwind + content: [ C1, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00, + 00, 00, 00, 04, 00, 00, 00, 00, 00, 00, 00, 00, + 00, 00, 00, 00, 00, 00, 00, 00 ] + references: + - kind: pointer64Anon + offset: 0 + target: _needsDwarfButNoCompactUnwind + +# Generic x86_64 CIE: + - type: unwind-cfi + content: [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00, + 01, 78, 10, 01, 10, 0C, 07, 08, 90, 01, 00, 00 ] + + - type: unwind-cfi + content: [ 24, 00, 00, 00, 1C, 00, 00, 00, C8, FE, FF, FF, + FF, FF, FF, FF, 01, 00, 00, 00, 00, 00, 00, 00, + 00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00, + 00, 00, 00, 00 ] + references: + - kind: unwindFDEToFunction + offset: 8 + target: _needsDwarfButNoCompactUnwind + + - type: unwind-cfi + content: [ 24, 00, 00, 00, 44, 00, 00, 00, C8, FE, FF, FF, + FF, FF, FF, FF, 01, 00, 00, 00, 00, 00, 00, 00, + 00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00, + 00, 00, 00, 00 ] + references: + - kind: unwindFDEToFunction + offset: 8 + target: _needsDwarfSaysCompactUnwind + - name: __Z3barv scope: global @@ -64,6 +101,15 @@ defined-atoms: - kind: branch32 offset: 9 target: __Z3barv + - name: _needsDwarfButNoCompactUnwind + scope: global + content: [ C3 ] + - name: _needsDwarfSaysCompactUnwind + scope: global + content: [ C3 ] + - name: _noUnwindData + scope: global + content: [ C3 ] shared-library-atoms: - name: ___gxx_personality_v0