return read32(swap, *(uint32_t *)(atom->rawContent().data() + idOffset)) == 0;
}
+const Atom *ArchHandler::fdeTargetFunction(const DefinedAtom *fde) {
+ for (auto ref : *fde) {
+ if (ref->kindNamespace() == Reference::KindNamespace::mach_o &&
+ ref->kindValue() == unwindRefToFunctionKind()) {
+ assert(ref->kindArch() == kindArch() && "unexpected Reference arch");
+ return ref->target();
+ }
+ }
+
+ return nullptr;
+}
+
} // namespace mach_o
} // namespace lld
/// __eh_frame.
virtual Reference::KindValue unwindRefToEhFrameKind() = 0;
+ virtual const Atom *fdeTargetFunction(const DefinedAtom *fde);
+
/// Used by normalizedFromAtoms() to know where to generated rebasing and
/// binding info in final executables.
virtual bool isPointer(const Reference &) = 0;
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))
+ if (ehFrameAtom->contentType() != DefinedAtom::typeCFI)
+ continue;
+ if (ArchHandler::isDwarfCIE(_swap, ehFrameAtom))
continue;
- DefinedAtom::reference_iterator ref = ehFrameAtom->begin();
- for (; ref != ehFrameAtom->end(); ++ref)
- if (ref->kindNamespace() == Reference::KindNamespace::mach_o &&
- ref->kindArch() == _archHandler.kindArch() &&
- ref->kindValue() == _archHandler.unwindRefToFunctionKind()) {
- dwarfFrames.insert(std::make_pair(ref->target(), ehFrameAtom));
- break;
- }
+ if (const Atom *function = _archHandler.fdeTargetFunction(ehFrameAtom))
+ dwarfFrames[function] = ehFrameAtom;
}
}
addend, handler.kindArch());
// Linker needs to fixup reference from the FDE to the function it's
- // describing.
+ // describing. FIXME: there are actually different ways to do this, and the
+ // particular method used is specified in the CIE's augmentation fields
+ // (hopefully)
uint64_t rangeFieldInFDE = cieFieldInFDE + sizeof(uint32_t);
int64_t functionFromFDE = readSPtr(is64, swap, frameData + rangeFieldInFDE);