diff options
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r-- | lld/ELF/InputSection.cpp | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index d45ab94..06d6e46 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -160,11 +160,15 @@ uint64_t SectionBase::getOffset(uint64_t offset) const { case Regular: case Synthetic: return cast<InputSection>(this)->outSecOff + offset; - case EHFrame: + case EHFrame: { // The file crtbeginT.o has relocations pointing to the start of an empty // .eh_frame that is known to be the first in the link. It does that to // identify the start of the output .eh_frame. - return offset; + const EhInputSection *es = cast<EhInputSection>(this); + if (InputSection *isec = es->getParent()) + return isec->outSecOff + es->getParentOffset(offset); + return es->getParentOffset(offset); + } case Merge: const MergeInputSection *ms = cast<MergeInputSection>(this); if (InputSection *isec = ms->getParent()) @@ -1334,6 +1338,21 @@ void EhInputSection::split(ArrayRef<RelTy> rels) { getObjMsg(d.data() - rawData.data())); } +const EhSectionPiece &EhInputSection::getSectionPiece(uint64_t offset) const { + if (this->data().size() < offset) + fatal(toString(this) + ": offset is outside the section"); + return partition_point( + pieces, [=](EhSectionPiece p) { return p.inputOff <= offset; })[-1]; +} + +// Return the offset in an output section for a given input offset. +uint64_t EhInputSection::getParentOffset(uint64_t offset) const { + const EhSectionPiece &piece = getSectionPiece(offset); + if (piece.outputOff == -1) // invalid piece + return offset - piece.inputOff; + return piece.outputOff + (offset - piece.inputOff); +} + static size_t findNull(StringRef s, size_t entSize) { for (unsigned i = 0, n = s.size(); i != n; i += entSize) { const char *b = s.begin() + i; |