[lld] r219836 - [mach-o] make __unwind_info defer to __eh_frame when necessary.
Tim Northover
tnorthover at apple.com
Wed Oct 15 12:32:21 PDT 2014
Author: tnorthover
Date: Wed Oct 15 14:32:21 2014
New Revision: 219836
URL: http://llvm.org/viewvc/llvm-project?rev=219836&view=rev
Log:
[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
Modified:
lld/trunk/include/lld/Core/Simple.h
lld/trunk/lib/ReaderWriter/MachO/ArchHandler.cpp
lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml
Modified: lld/trunk/include/lld/Core/Simple.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Simple.h?rev=219836&r1=219835&r2=219836&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Simple.h (original)
+++ lld/trunk/include/lld/Core/Simple.h Wed Oct 15 14:32:21 2014
@@ -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));
}
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler.cpp?rev=219836&r1=219835&r2=219836&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler.cpp Wed Oct 15 14:32:21 2014
@@ -142,6 +142,17 @@ int64_t ArchHandler::readS64(bool swap,
return read64(swap, *reinterpret_cast<const uint64_t*>(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
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h?rev=219836&r1=219835&r2=219836&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h Wed Oct 15 14:32:21 2014
@@ -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;
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp?rev=219836&r1=219835&r2=219836&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp Wed Oct 15 14:32:21 2014
@@ -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(co
void ArchHandler_arm::generateAtomContent(const DefinedAtom &atom,
bool relocatable,
FindAddressForAtom findAddress,
+ FindAddressForAtom findSectionAddress,
uint64_t imageBaseAddress,
uint8_t *atomContentBuffer) {
// Copy raw bytes.
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp?rev=219836&r1=219835&r2=219836&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp Wed Oct 15 14:32:21 2014
@@ -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::getPa
}
}
-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.
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp?rev=219836&r1=219835&r2=219836&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp Wed Oct 15 14:32:21 2014
@@ -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(co
void ArchHandler_x86::generateAtomContent(const DefinedAtom &atom,
bool relocatable,
FindAddressForAtom findAddress,
+ FindAddressForAtom findSectionAddress,
uint64_t imageBaseAddress,
uint8_t *atomContentBuffer) {
// Copy raw bytes.
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp?rev=219836&r1=219835&r2=219836&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp Wed Oct 15 14:32:21 2014
@@ -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_
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
}
}
-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::generateAtomCon
} 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
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::applyFixupReloc
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::appendSectionRe
X86_64_RELOC_UNSIGNED | rLength8 );
return;
case unwindFDEToFunction:
+ case unwindInfoToEhFrame:
return;
case ripRel32GotLoadNowLea:
llvm_unreachable("ripRel32GotLoadNowLea implies GOT pass was run");
Modified: lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp?rev=219836&r1=219835&r2=219836&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp Wed Oct 15 14:32:21 2014
@@ -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<int32_t *>(_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<MutableFile> &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<const Atom *, CompactUnwindEntry> unwindLocs;
+ std::map<const Atom *, const Atom *> dwarfFrames;
std::vector<const Atom *> 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<CompactUnwindEntry> unwindInfos =
- createUnwindInfoEntries(mergedFile, unwindLocs, personalities);
+ std::vector<CompactUnwindEntry> 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<MutableFile> &mergedFile,
+ std::map<const Atom *, const Atom *> &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<CompactUnwindEntry> createUnwindInfoEntries(
const std::unique_ptr<MutableFile> &mergedFile,
const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
- const std::vector<const Atom *> &personalities) {
+ const std::vector<const Atom *> &personalities,
+ const std::map<const Atom *, const Atom *> &dwarfFrames) {
std::vector<CompactUnwindEntry> 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<const Atom *, CompactUnwindEntry> &unwindLocs,
- const std::vector<const Atom *> &personalities) {
+ const std::vector<const Atom *> &personalities,
+ const std::map<const Atom *, const Atom *> &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()
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=219836&r1=219835&r2=219836&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Wed Oct 15 14:32:21 2014
@@ -556,6 +556,14 @@ void Util::copySectionContent(Normalized
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(Normalized
uint8_t *atomContent = reinterpret_cast<uint8_t*>
(§ionContent[ai.offsetInSection]);
_archHandler.generateAtomContent(*ai.atom, r, addrForAtom,
+ sectionAddrForAtom,
_context.baseAddress(), atomContent);
}
}
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=219836&r1=219835&r2=219836&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Wed Oct 15 14:32:21 2014
@@ -621,17 +621,6 @@ bool isDebugInfoSection(const Section &s
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<const uint64_t *>(addr));
@@ -662,7 +651,7 @@ std::error_code addEHFrameReferences(con
[&](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.
Modified: lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml?rev=219836&r1=219835&r2=219836&view=diff
==============================================================================
--- lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml (original)
+++ lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml Wed Oct 15 14:32:21 2014
@@ -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: '<linker-internal>'
@@ -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
More information about the llvm-commits
mailing list