aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/InputSection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r--lld/ELF/InputSection.cpp23
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;