[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