[lld] 98164d4 - Revert "[ELF] -r: Synthesize R_RISCV_ALIGN at input section start" (#151639)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 12 22:18:21 PDT 2025


Author: Fangrui Song
Date: 2025-08-12T22:18:15-07:00
New Revision: 98164d4706115b3ed850be84bb4647c56d2b2eaf

URL: https://github.com/llvm/llvm-project/commit/98164d4706115b3ed850be84bb4647c56d2b2eaf
DIFF: https://github.com/llvm/llvm-project/commit/98164d4706115b3ed850be84bb4647c56d2b2eaf.diff

LOG: Revert "[ELF] -r: Synthesize R_RISCV_ALIGN at input section start" (#151639)

This reverts commit 6f53f1c8d2bdd13e30da7d1b85ed6a3ae4c4a856.

synthesiedAligns is not cleared, leading to stray relocations for
unrelated sections. Revert for now.

Added: 
    

Modified: 
    lld/ELF/Arch/RISCV.cpp
    lld/ELF/LinkerScript.cpp
    lld/ELF/OutputSections.cpp
    lld/ELF/Target.h

Removed: 
    lld/test/ELF/riscv-relocatable-align.s


################################################################################
diff  --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 71201b0e16042..ba0584bb1799b 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -45,21 +45,7 @@ class RISCV final : public TargetInfo {
                 uint64_t val) const override;
   void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
   bool relaxOnce(int pass) const override;
-  template <class ELFT, class RelTy>
-  bool synthesizeAlignForInput(uint64_t &dot, InputSection *sec,
-                               Relocs<RelTy> rels);
-  template <class ELFT, class RelTy>
-  void finalizeSynthesizeAligns(uint64_t &dot, InputSection *sec,
-                                Relocs<RelTy> rels);
-  template <class ELFT>
-  bool synthesizeAlignAux(uint64_t &dot, InputSection *sec);
-  bool synthesizeAlign(uint64_t &dot, InputSection *sec) override;
   void finalizeRelax(int passes) const override;
-
-  // The following two variables are used by synthesized ALIGN relocations.
-  InputSection *baseSec = nullptr;
-  // r_offset and r_addend pairs.
-  SmallVector<std::pair<uint64_t, uint64_t>, 0> synthesizedAligns;
 };
 
 } // end anonymous namespace
@@ -970,116 +956,6 @@ bool RISCV::relaxOnce(int pass) const {
   return changed;
 }
 
-// If the section alignment is >= 4, advance `dot` to insert NOPs and synthesize
-// an ALIGN relocation. Otherwise, return false to use default handling.
-template <class ELFT, class RelTy>
-bool RISCV::synthesizeAlignForInput(uint64_t &dot, InputSection *sec,
-                                    Relocs<RelTy> rels) {
-  if (!baseSec) {
-    // Record the first input section with RELAX relocations. We will synthesize
-    // ALIGN relocations here.
-    for (auto rel : rels) {
-      if (rel.getType(false) == R_RISCV_RELAX) {
-        baseSec = sec;
-        break;
-      }
-    }
-  } else if (sec->addralign >= 4) {
-    // If the alignment is >= 4 and the section does not start with an ALIGN
-    // relocation, synthesize one.
-    bool hasAlignRel = llvm::any_of(rels, [](const RelTy &rel) {
-      return rel.r_offset == 0 && rel.getType(false) == R_RISCV_ALIGN;
-    });
-    if (!hasAlignRel) {
-      synthesizedAligns.emplace_back(dot - baseSec->getVA(),
-                                     sec->addralign - 2);
-      dot += sec->addralign - 2;
-      return true;
-    }
-  }
-  return false;
-}
-
-// Finalize the relocation section by appending synthesized ALIGN relocations
-// after processing all input sections.
-template <class ELFT, class RelTy>
-void RISCV::finalizeSynthesizeAligns(uint64_t &dot, InputSection *sec,
-                                     Relocs<RelTy> rels) {
-  auto *f = cast<ObjFile<ELFT>>(baseSec->file);
-  auto shdr = f->template getELFShdrs<ELFT>()[baseSec->relSecIdx];
-  // Create a copy of InputSection.
-  sec = make<InputSection>(*f, shdr, baseSec->name);
-  auto *baseRelSec = cast<InputSection>(f->getSections()[baseSec->relSecIdx]);
-  *sec = *baseRelSec;
-  baseSec = nullptr;
-
-  // Allocate buffer for original and synthesized relocations in RELA format.
-  // If CREL is used, OutputSection::finalizeNonAllocCrel will convert RELA to
-  // CREL.
-  auto newSize = rels.size() + synthesizedAligns.size();
-  auto *relas = makeThreadLocalN<typename ELFT::Rela>(newSize);
-  sec->size = newSize * sizeof(typename ELFT::Rela);
-  sec->content_ = reinterpret_cast<uint8_t *>(relas);
-  sec->type = SHT_RELA;
-  // Copy original relocations to the new buffer, potentially converting CREL to
-  // RELA.
-  for (auto [i, r] : llvm::enumerate(rels)) {
-    relas[i].r_offset = r.r_offset;
-    relas[i].setSymbolAndType(r.getSymbol(0), r.getType(0), false);
-    if constexpr (RelTy::HasAddend)
-      relas[i].r_addend = r.r_addend;
-  }
-  // Append synthesized ALIGN relocations to the buffer.
-  for (auto [i, r] : llvm::enumerate(synthesizedAligns)) {
-    auto &rela = relas[rels.size() + i];
-    rela.r_offset = r.first;
-    rela.setSymbolAndType(0, R_RISCV_ALIGN, false);
-    rela.r_addend = r.second;
-  }
-  // Replace the old relocation section with the new one in the output section.
-  // addOrphanSections ensures that the output relocation section is processed
-  // after osec.
-  for (SectionCommand *cmd : sec->getParent()->commands) {
-    auto *isd = dyn_cast<InputSectionDescription>(cmd);
-    if (!isd)
-      continue;
-    for (auto *&isec : isd->sections)
-      if (isec == baseRelSec)
-        isec = sec;
-  }
-}
-
-template <class ELFT>
-bool RISCV::synthesizeAlignAux(uint64_t &dot, InputSection *sec) {
-  bool ret = false;
-  if (sec) {
-    invokeOnRelocs(*sec, ret = synthesizeAlignForInput<ELFT>, dot, sec);
-  } else if (baseSec) {
-    invokeOnRelocs(*baseSec, finalizeSynthesizeAligns<ELFT>, dot, sec);
-  }
-  return ret;
-}
-
-// Without linker relaxation enabled for a particular relocatable file or
-// section, the assembler will not generate R_RISCV_ALIGN relocations for
-// alignment directives. This becomes problematic in a two-stage linking
-// process: ld -r a.o b.o -o ab.o; ld ab.o -o ab. This function synthesizes an
-// R_RISCV_ALIGN relocation at section start when needed.
-//
-// When called with an input section (`sec` is not null): If the section
-// alignment is >= 4, advance `dot` to insert NOPs and synthesize an ALIGN
-// relocation.
-//
-// When called after all input sections are processed (`sec` is null): The
-// output relocation section is updated with all the newly synthesized ALIGN
-// relocations.
-bool RISCV::synthesizeAlign(uint64_t &dot, InputSection *sec) {
-  assert(ctx.arg.relocatable);
-  if (ctx.arg.is64)
-    return synthesizeAlignAux<ELF64LE>(dot, sec);
-  return synthesizeAlignAux<ELF32LE>(dot, sec);
-}
-
 void RISCV::finalizeRelax(int passes) const {
   llvm::TimeTraceScope timeScope("Finalize RISC-V relaxation");
   Log(ctx) << "relaxation passes: " << passes;

diff  --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index e9ce4e26f3ed9..a5d08f4979dab 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -1230,9 +1230,6 @@ bool LinkerScript::assignOffsets(OutputSection *sec) {
   if (sec->firstInOverlay)
     state->overlaySize = 0;
 
-  bool synthesizeAlign = ctx.arg.relocatable && ctx.arg.relax &&
-                         (sec->flags & SHF_EXECINSTR) &&
-                         ctx.arg.emachine == EM_RISCV;
   // We visited SectionsCommands from processSectionCommands to
   // layout sections. Now, we visit SectionsCommands again to fix
   // section offsets.
@@ -1263,10 +1260,7 @@ bool LinkerScript::assignOffsets(OutputSection *sec) {
       if (isa<PotentialSpillSection>(isec))
         continue;
       const uint64_t pos = dot;
-      // If synthesized ALIGN may be needed, call maybeSynthesizeAlign and
-      // disable the default handling if the return value is true.
-      if (!(synthesizeAlign && ctx.target->synthesizeAlign(dot, isec)))
-        dot = alignToPowerOf2(dot, isec->addralign);
+      dot = alignToPowerOf2(dot, isec->addralign);
       isec->outSecOff = dot - sec->addr;
       dot += isec->getSize();
 
@@ -1282,12 +1276,6 @@ bool LinkerScript::assignOffsets(OutputSection *sec) {
   if (ctx.in.relroPadding && sec == ctx.in.relroPadding->getParent())
     expandOutputSection(alignToPowerOf2(dot, ctx.arg.commonPageSize) - dot);
 
-  if (synthesizeAlign) {
-    const uint64_t pos = dot;
-    ctx.target->synthesizeAlign(dot, nullptr);
-    expandOutputSection(dot - pos);
-  }
-
   // Non-SHF_ALLOC sections do not affect the addresses of other OutputSections
   // as they are not part of the process image.
   if (!(sec->flags & SHF_ALLOC)) {

diff  --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 0b50f6d68ce5d..1020dd9f2569e 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -889,17 +889,9 @@ void OutputSection::sortInitFini() {
 std::array<uint8_t, 4> OutputSection::getFiller(Ctx &ctx) {
   if (filler)
     return *filler;
-  if (!(flags & SHF_EXECINSTR))
-    return {0, 0, 0, 0};
-  if (ctx.arg.relocatable && ctx.arg.emachine == EM_RISCV) {
-    // See RISCV::maybeSynthesizeAlign: Synthesized NOP bytes and ALIGN
-    // relocations might be needed between two input sections. Use a NOP for the
-    // filler.
-    if (ctx.arg.eflags & EF_RISCV_RVC)
-      return {1, 0, 1, 0};
-    return {0x13, 0, 0, 0};
-  }
-  return ctx.target->trapInstr;
+  if (flags & SHF_EXECINSTR)
+    return ctx.target->trapInstr;
+  return {0, 0, 0, 0};
 }
 
 void OutputSection::checkDynRelAddends(Ctx &ctx) {

diff  --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index e121fa1183e9e..fdc0c20f9cd02 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -96,9 +96,6 @@ class TargetInfo {
 
   // Do a linker relaxation pass and return true if we changed something.
   virtual bool relaxOnce(int pass) const { return false; }
-  virtual bool synthesizeAlign(uint64_t &dot, InputSection *sec) {
-    return false;
-  }
   // Do finalize relaxation after collecting relaxation infos.
   virtual void finalizeRelax(int passes) const {}
 

diff  --git a/lld/test/ELF/riscv-relocatable-align.s b/lld/test/ELF/riscv-relocatable-align.s
deleted file mode 100644
index 9a782ed47850a..0000000000000
--- a/lld/test/ELF/riscv-relocatable-align.s
+++ /dev/null
@@ -1,130 +0,0 @@
-# RUN: rm -rf %t && split-file %s %t && cd %t
-# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+c,+relax a.s -o ac.o
-# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+c,+relax b.s -o bc.o
-# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+c,+relax b1.s -o b1c.o
-# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+c,+relax c.s -o cc.o
-# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+c d.s -o dc.o
-
-## No RELAX. Don't synthesize ALIGN.
-# RUN: ld.lld -r bc.o dc.o -o bd.ro
-# RUN: llvm-readelf -r bd.ro | FileCheck %s --check-prefix=NOREL
-
-# NOREL: no relocations
-
-# RUN: ld.lld -r bc.o bc.o ac.o bc.o b1c.o cc.o dc.o -o out.ro
-# RUN: llvm-objdump -dr -M no-aliases out.ro | FileCheck %s
-
-# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+relax a.s -o a.o
-# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+relax b.s -o b.o
-# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+relax d.s -o d.o
-# RUN: ld.lld -r a.o b.o d.o -o out0.ro
-# RUN: ld.lld -Ttext=0x10000 out0.ro -o out0
-# RUN: llvm-objdump -dr -M no-aliases out0 | FileCheck %s --check-prefix=CHECK1
-
-# CHECK:      <b0>:
-# CHECK-NEXT:   0: 00158513             addi    a0, a1, 0x1
-# CHECK-NEXT:   4: 0001                 c.nop
-# CHECK-NEXT:   6: 0001                 c.nop
-# CHECK-EMPTY:
-# CHECK-NEXT: <b0>:
-# CHECK-NEXT:   8: 00158513             addi    a0, a1, 0x1
-# CHECK-EMPTY:
-# CHECK-NEXT: <_start>:
-# CHECK-NEXT:   c: 00000097             auipc   ra, 0x0
-# CHECK-NEXT:           000000000000000c:  R_RISCV_CALL_PLT     foo
-# CHECK-NEXT:           000000000000000c:  R_RISCV_RELAX        *ABS*
-# CHECK-NEXT:  10: 000080e7             jalr    ra, 0x0(ra) <_start>
-# CHECK-NEXT:  14: 0001                 c.nop
-# CHECK-NEXT:           0000000000000014:  R_RISCV_ALIGN        *ABS*+0x6
-# CHECK-NEXT:  16: 0001                 c.nop
-# CHECK-NEXT:  18: 0001                 c.nop
-# CHECK-EMPTY:
-# CHECK-NEXT: <b0>:
-# CHECK-NEXT:  1a: 00158513             addi    a0, a1, 0x1
-# CHECK-NEXT:  1e: 0001                 c.nop
-# CHECK-NEXT:  20: 0001                 c.nop
-# CHECK-NEXT:           0000000000000020:  R_RISCV_ALIGN        *ABS*+0x6
-# CHECK-NEXT:  22: 0001                 c.nop
-# CHECK-NEXT:  24: 00000013             addi    zero, zero, 0x0
-# CHECK-EMPTY:
-# CHECK-NEXT: <b0>:
-# CHECK-NEXT:  28: 00158513             addi    a0, a1, 0x1
-# CHECK-EMPTY:
-# CHECK-NEXT: <c0>:
-# CHECK-NEXT:  2c: 00000097             auipc   ra, 0x0
-# CHECK-NEXT:           000000000000002c:  R_RISCV_CALL_PLT     foo
-# CHECK-NEXT:           000000000000002c:  R_RISCV_RELAX        *ABS*
-# CHECK-NEXT:  30: 000080e7             jalr    ra, 0x0(ra) <c0>
-# CHECK-NEXT:  34: 0001                 c.nop
-# CHECK-NEXT:           0000000000000034:  R_RISCV_ALIGN        *ABS*+0x2
-# CHECK-EMPTY:
-# CHECK-NEXT: <d0>:
-# CHECK-NEXT:  36: 00258513             addi    a0, a1, 0x2
-
-# CHECK1:      <_start>:
-# CHECK1-NEXT:    010000ef      jal     ra, 0x10010 <foo>
-# CHECK1-NEXT:    00000013      addi zero, zero, 0x0
-# CHECK1-EMPTY:
-# CHECK1-NEXT: <b0>:
-# CHECK1-NEXT:    00158513      addi    a0, a1, 0x1
-# CHECK1-EMPTY:
-# CHECK1-NEXT: <d0>:
-# CHECK1-NEXT:    00258513      addi    a0, a1, 0x2
-
-## Test CREL.
-# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+c,+relax --crel a.s -o acrel.o
-# RUN: ld.lld -r acrel.o bc.o -o out1.ro
-# RUN: llvm-objdump -dr -M no-aliases out1.ro | FileCheck %s --check-prefix=CHECK2
-
-# CHECK2:      <_start>:
-# CHECK2-NEXT:   0: 00000097             auipc   ra, 0x0
-# CHECK2-NEXT:           0000000000000000:  R_RISCV_CALL_PLT     foo
-# CHECK2-NEXT:           0000000000000000:  R_RISCV_RELAX        *ABS*
-# CHECK2-NEXT:   4: 000080e7             jalr    ra, 0x0(ra) <_start>
-# CHECK2-NEXT:   8: 0001                 c.nop
-# CHECK2-NEXT:           0000000000000008:  R_RISCV_ALIGN        *ABS*+0x6
-# CHECK2-NEXT:   a: 0001                 c.nop
-# CHECK2-NEXT:   c: 0001                 c.nop
-# CHECK2-EMPTY:
-# CHECK2-NEXT: <b0>:
-# CHECK2-NEXT:   e: 00158513             addi    a0, a1, 0x1
-
-#--- a.s
-.globl _start
-_start:
-  call foo
-
-.section .text1,"ax"
-.globl foo
-foo:
-
-#--- b.s
-## Needs synthesized ALIGN
-.option push
-.option norelax
-.balign 8
-b0:
-  addi a0, a1, 1
-.option pop
-
-#--- b1.s
-.option push
-.option norelax
-  .reloc ., R_RISCV_ALIGN, 6
-  addi x0, x0, 0
-  c.nop
-.balign 8
-b0:
-  addi a0, a1, 1
-.option pop
-
-#--- c.s
-.balign 2
-c0:
-  call foo
-
-#--- d.s
-## Needs synthesized ALIGN
-.balign 4
-d0:
-  addi a0, a1, 2


        


More information about the llvm-commits mailing list