[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