[lld] e973c13 - [ELF] Move the outSecOff addend from relocAlloc/relocNonAlloc/... to InputSectionBase::relocate
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 11 08:07:41 PDT 2020
Author: Fangrui Song
Date: 2020-08-11T08:06:38-07:00
New Revision: e973c1375ed04b1d71fa86f1519d5067d8a6fc1f
URL: https://github.com/llvm/llvm-project/commit/e973c1375ed04b1d71fa86f1519d5067d8a6fc1f
DIFF: https://github.com/llvm/llvm-project/commit/e973c1375ed04b1d71fa86f1519d5067d8a6fc1f.diff
LOG: [ELF] Move the outSecOff addend from relocAlloc/relocNonAlloc/... to InputSectionBase::relocate
For an InputSection, the `buf` argument of `InputSectionBase::relocate` points
to the content of the containing OutputSection, instead of the content of the
InputSection itself, so `outSecOff` needs to be added in its callees. This is
counter-intuitive and leads to many `- outSecOff` and `+ outSecOff`.
This patch makes `InputSection::writeTo` call `InputSectionBase::relocate` with
`outSecOff` added. relocAlloc/relocNonAlloc/relocateNonAllocForRelocatable can
thus be simplified now.
Updated test:
* non-abs-reloc.s: A minor offset bug is fixed for a diagnostic in `relocateNonAlloc`
Reviewed By: grimar
Differential Revision: https://reviews.llvm.org/D85618
Added:
Modified:
lld/ELF/AArch64ErrataFix.cpp
lld/ELF/ARMErrataFix.cpp
lld/ELF/InputSection.cpp
lld/ELF/SyntheticSections.cpp
lld/test/ELF/non-abs-reloc.s
Removed:
################################################################################
diff --git a/lld/ELF/AArch64ErrataFix.cpp b/lld/ELF/AArch64ErrataFix.cpp
index 724d668449b7..b9fd4cdbad69 100644
--- a/lld/ELF/AArch64ErrataFix.cpp
+++ b/lld/ELF/AArch64ErrataFix.cpp
@@ -413,9 +413,7 @@ void Patch843419Section::writeTo(uint8_t *buf) {
write32le(buf, read32le(patchee->data().begin() + patcheeOffset));
// Apply any relocation transferred from the original patchee section.
- // For a SyntheticSection Buf already has outSecOff added, but relocateAlloc
- // also adds outSecOff so we need to subtract to avoid double counting.
- this->relocateAlloc(buf - outSecOff, buf - outSecOff + getSize());
+ relocateAlloc(buf, buf + getSize());
// Return address is the next instruction after the one we have just copied.
uint64_t s = getLDSTAddr() + 4;
diff --git a/lld/ELF/ARMErrataFix.cpp b/lld/ELF/ARMErrataFix.cpp
index bd6f689b5844..86b822f02fd5 100644
--- a/lld/ELF/ARMErrataFix.cpp
+++ b/lld/ELF/ARMErrataFix.cpp
@@ -173,11 +173,9 @@ void Patch657417Section::writeTo(uint8_t *buf) {
write32le(buf, 0xea000000);
else
write32le(buf, 0x9000f000);
- // If we have a relocation then apply it. For a SyntheticSection buf already
- // has outSecOff added, but relocateAlloc also adds outSecOff so we need to
- // subtract to avoid double counting.
+ // If we have a relocation then apply it.
if (!relocations.empty()) {
- relocateAlloc(buf - outSecOff, buf - outSecOff + getSize());
+ relocateAlloc(buf, buf + getSize());
return;
}
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 17c77f66d08f..6440e8791e3a 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -881,7 +881,7 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
if (config->emachine == EM_386 && type == R_386_GOTPC)
continue;
- uint64_t offset = getOffset(rel.r_offset);
+ uint64_t offset = rel.r_offset;
uint8_t *bufLoc = buf + offset;
int64_t addend = getAddend<ELFT>(rel);
if (!RelTy::IsRela)
@@ -915,8 +915,9 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
// address 0. For bug-compatibilty, we accept them with warnings. We
// know Steel Bank Common Lisp as of 2018 have this bug.
warn(msg);
- target->relocateNoSym(bufLoc, type,
- SignExtend64<bits>(sym.getVA(addend - offset)));
+ target->relocateNoSym(
+ bufLoc, type,
+ SignExtend64<bits>(sym.getVA(addend - offset - outSecOff)));
continue;
}
@@ -975,7 +976,7 @@ static void relocateNonAllocForRelocatable(InputSection *sec, uint8_t *buf) {
for (const Relocation &rel : sec->relocations) {
// InputSection::copyRelocations() adds only R_ABS relocations.
assert(rel.expr == R_ABS);
- uint8_t *bufLoc = buf + rel.offset + sec->outSecOff;
+ uint8_t *bufLoc = buf + rel.offset;
uint64_t targetVA = SignExtend64(rel.sym->getVA(rel.addend), bits);
target->relocate(bufLoc, rel, targetVA);
}
@@ -1008,12 +1009,12 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
if (rel.expr == R_NONE)
continue;
uint64_t offset = rel.offset;
- if (auto *sec = dyn_cast<InputSection>(this))
- offset += sec->outSecOff;
uint8_t *bufLoc = buf + offset;
RelType type = rel.type;
uint64_t addrLoc = getOutputSection()->addr + offset;
+ if (auto *sec = dyn_cast<InputSection>(this))
+ addrLoc += sec->outSecOff;
RelExpr expr = rel.expr;
uint64_t targetVA = SignExtend64(
getRelocTargetVA(file, type, rel.addend, addrLoc, *rel.sym, expr),
@@ -1089,7 +1090,7 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
// basic block sections.
if (auto *sec = dyn_cast<InputSection>(this)) {
for (const JumpInstrMod &jumpMod : jumpInstrMods) {
- uint64_t offset = jumpMod.offset + sec->outSecOff;
+ uint64_t offset = jumpMod.offset;
uint8_t *bufLoc = buf + offset;
target->applyJumpInstrMod(bufLoc, jumpMod.original, jumpMod.size);
}
@@ -1187,8 +1188,8 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf,
if (Defined *f = getEnclosingFunction<ELFT>(rel.offset)) {
prologues.insert(f);
- if (target->adjustPrologueForCrossSplitStack(buf + getOffset(f->value),
- end, f->stOther))
+ if (target->adjustPrologueForCrossSplitStack(buf + f->value, end,
+ f->stOther))
continue;
if (!getFile<ELFT>()->someNoSplitStack)
error(lld::toString(this) + ": " + f->getName() +
@@ -1236,7 +1237,7 @@ template <class ELFT> void InputSection::writeTo(uint8_t *buf) {
fatal(toString(this) +
": uncompress failed: " + llvm::toString(std::move(e)));
uint8_t *bufEnd = buf + outSecOff + size;
- relocate<ELFT>(buf, bufEnd);
+ relocate<ELFT>(buf + outSecOff, bufEnd);
return;
}
@@ -1244,7 +1245,7 @@ template <class ELFT> void InputSection::writeTo(uint8_t *buf) {
// and then apply relocations.
memcpy(buf + outSecOff, data().data(), data().size());
uint8_t *bufEnd = buf + outSecOff + data().size();
- relocate<ELFT>(buf, bufEnd);
+ relocate<ELFT>(buf + outSecOff, bufEnd);
}
void InputSection::replace(InputSection *other) {
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index e453c3b6bec3..09c50c22b10c 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -696,11 +696,8 @@ bool GotSection::isNeeded() const {
}
void GotSection::writeTo(uint8_t *buf) {
- // Buf points to the start of this section's buffer,
- // whereas InputSectionBase::relocateAlloc() expects its argument
- // to point to the start of the output section.
target->writeGotHeader(buf);
- relocateAlloc(buf - outSecOff, buf - outSecOff + size);
+ relocateAlloc(buf, buf + size);
}
static uint64_t getMipsPageAddr(uint64_t addr) {
@@ -3497,7 +3494,7 @@ void ARMExidxSyntheticSection::writeTo(uint8_t *buf) {
assert(isec->getParent() != nullptr);
if (InputSection *d = findExidxSection(isec)) {
memcpy(buf + offset, d->data().data(), d->data().size());
- d->relocateAlloc(buf, buf + d->getSize());
+ d->relocateAlloc(buf + d->outSecOff, buf + d->outSecOff + d->getSize());
offset += d->getSize();
} else {
// A Linker generated CANTUNWIND section.
diff --git a/lld/test/ELF/non-abs-reloc.s b/lld/test/ELF/non-abs-reloc.s
index f58301b0a0a6..72a65424ed1f 100644
--- a/lld/test/ELF/non-abs-reloc.s
+++ b/lld/test/ELF/non-abs-reloc.s
@@ -2,8 +2,8 @@
// RUN: split-file %s %t
// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/asm -o %t.o
// RUN: ld.lld -T %t/lds %t.o -o %t.exe 2>&1 | FileCheck %s
-// CHECK: warning: {{.*}}.o:(.nonalloc1+0x2): has non-ABS relocation R_X86_64_PC32 against symbol '_start'
-// CHECK-NEXT: warning: {{.*}}.o:(.nonalloc1+0x7): has non-ABS relocation R_X86_64_PC32 against symbol '_start'
+// CHECK: warning: {{.*}}.o:(.nonalloc1+0x1): has non-ABS relocation R_X86_64_PC32 against symbol '_start'
+// CHECK-NEXT: warning: {{.*}}.o:(.nonalloc1+0x6): has non-ABS relocation R_X86_64_PC32 against symbol '_start'
// RUN: llvm-objdump -D --no-show-raw-insn %t.exe | FileCheck --check-prefix=DISASM %s
// DISASM: Disassembly of section .nonalloc:
More information about the llvm-commits
mailing list