forked from OSchip/llvm-project
[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
This commit is contained in:
parent
78206c3576
commit
1cc4fb76da
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -142,6 +142,17 @@ int64_t ArchHandler::readS64(bool swap, const uint8_t *addr) {
|
|||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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<uint8_t*>
|
||||
(§ionContent[ai.offsetInSection]);
|
||||
_archHandler.generateAtomContent(*ai.atom, r, addrForAtom,
|
||||
sectionAddrForAtom,
|
||||
_context.baseAddress(), atomContent);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<const uint64_t *>(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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue