llvm/llvm-project#113838 "[RISCV] ld.lld: error: relaxation not converged with openssl"
ld.lld @response.txt --noinhibit-exec -o out.30
S=1 ld.lld @response.txt --noinhibit-exec -o out.31llvm/llvm-project#113838 "[RISCV] ld.lld: error: relaxation not converged with openssl"
ld.lld @response.txt --noinhibit-exec -o out.30
S=1 ld.lld @response.txt --noinhibit-exec -o out.31| From 6371dfbb1cca000e81e8aeca4bf079bc875f382f Mon Sep 17 00:00:00 2001 | |
| From: Fangrui Song <hidden> | |
| Date: Tue, 3 Jun 2025 23:39:08 -0700 | |
| Subject: [PATCH] WIP hack add -Map during relaxation | |
| --- | |
| lld/ELF/Arch/RISCV.cpp | 29 +++++++++++++++++++++++++++++ | |
| lld/ELF/MapFile.cpp | 2 +- | |
| lld/ELF/MapFile.h | 2 ++ | |
| lld/ELF/Writer.cpp | 12 ++++++++++-- | |
| 4 files changed, 42 insertions(+), 3 deletions(-) | |
| diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp | |
| index abe8876668a4..6bed5ac73b45 100644 | |
| --- a/lld/ELF/Arch/RISCV.cpp | |
| +++ b/lld/ELF/Arch/RISCV.cpp | |
| @@ -7,6 +7,7 @@ | |
| //===----------------------------------------------------------------------===// | |
| #include "InputFiles.h" | |
| +#include "InputSection.h" | |
| #include "OutputSections.h" | |
| #include "Symbols.h" | |
| #include "SyntheticSections.h" | |
| @@ -729,6 +730,8 @@ void elf::initSymbolAnchors(Ctx &ctx) { | |
| } | |
| } | |
| +DenseMap<const InputSection *, SmallVector<int32_t, 0>> zrt0, zrt1, *zrt; | |
| + | |
| // Relax R_RISCV_CALL/R_RISCV_CALL_PLT auipc+jalr to c.j, c.jal, or jal. | |
| static void relaxCall(Ctx &ctx, const InputSection &sec, size_t i, uint64_t loc, | |
| Relocation &r, uint32_t &remove) { | |
| @@ -754,6 +757,7 @@ static void relaxCall(Ctx &ctx, const InputSection &sec, size_t i, uint64_t loc, | |
| sec.relaxAux->writes.push_back(0x6f | rd << 7); // jal | |
| remove = 4; | |
| } | |
| + (*zrt)[&sec][i] = remove; | |
| } | |
| // Relax local-exec TLS when hi20 is zero. | |
| @@ -839,6 +843,7 @@ static bool relax(Ctx &ctx, InputSection &sec) { | |
| std::fill_n(aux.relocTypes.get(), relocs.size(), R_RISCV_NONE); | |
| aux.writes.clear(); | |
| + (*zrt)[&sec].resize(relocs.size()); | |
| for (auto [i, r] : llvm::enumerate(relocs)) { | |
| const uint64_t loc = secAddr + r.offset - delta; | |
| uint32_t &cur = aux.relocDeltas[i], remove = 0; | |
| @@ -939,6 +944,11 @@ bool RISCV::relaxOnce(int pass) const { | |
| if (pass == 0) | |
| initSymbolAnchors(ctx); | |
| + if (!zrt || zrt == &zrt1) | |
| + zrt = &zrt0; | |
| + else | |
| + zrt = &zrt1; | |
| + | |
| SmallVector<InputSection *, 0> storage; | |
| bool changed = false; | |
| for (OutputSection *osec : ctx.outputSections) { | |
| @@ -954,6 +964,7 @@ void RISCV::finalizeRelax(int passes) const { | |
| llvm::TimeTraceScope timeScope("Finalize RISC-V relaxation"); | |
| Log(ctx) << "relaxation passes: " << passes; | |
| SmallVector<InputSection *, 0> storage; | |
| + | |
| for (OutputSection *osec : ctx.outputSections) { | |
| if (!(osec->flags & SHF_EXECINSTR)) | |
| continue; | |
| @@ -1054,6 +1065,24 @@ void RISCV::finalizeRelax(int passes) const { | |
| } | |
| } | |
| } | |
| + | |
| + for (auto &[sec, rt0] : zrt0) { | |
| + auto &rt1 = zrt1[sec]; | |
| + for (auto [i, xy] : enumerate(zip(rt0, rt1))) { | |
| + auto [x, y] = xy; | |
| + if (x != y) { | |
| + const Relocation &r = sec->relocs()[i]; | |
| + const Symbol &sym = *r.sym; | |
| + const uint64_t dest = | |
| + (r.expr == R_PLT_PC ? sym.getPltVA(ctx) : sym.getVA(ctx)) + | |
| + r.addend; | |
| + | |
| + lld::outs() << toStr(ctx, sec) | |
| + << format(" offset:%lx dest:%lx remove0:%x remove1:%x\n", | |
| + sec->getVA() + r.offset, dest, x, y); | |
| + } | |
| + } | |
| + } | |
| } | |
| namespace { | |
| diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp | |
| index 05ae25fc8efe..7a0590ee6286 100644 | |
| --- a/lld/ELF/MapFile.cpp | |
| +++ b/lld/ELF/MapFile.cpp | |
| @@ -147,7 +147,7 @@ static void printEhFrame(Ctx &ctx, raw_ostream &os, const EhFrameSection *sec) { | |
| } | |
| } | |
| -static void writeMapFile(Ctx &ctx, raw_fd_ostream &os) { | |
| +void elf::writeMapFile(Ctx &ctx, raw_fd_ostream &os) { | |
| // Collect symbol info that we want to print out. | |
| std::vector<Defined *> syms = getSymbols(ctx); | |
| SymbolMapTy sectionSyms = getSectionSyms(ctx, syms); | |
| diff --git a/lld/ELF/MapFile.h b/lld/ELF/MapFile.h | |
| index c4efd33a3095..d5b92648acd3 100644 | |
| --- a/lld/ELF/MapFile.h | |
| +++ b/lld/ELF/MapFile.h | |
| @@ -8,9 +8,11 @@ | |
| #ifndef LLD_ELF_MAPFILE_H | |
| #define LLD_ELF_MAPFILE_H | |
| +#include "llvm/Support/raw_ostream.h" | |
| namespace lld::elf { | |
| struct Ctx; | |
| +void writeMapFile(Ctx &ctx, llvm::raw_fd_ostream &os); | |
| void writeMapAndCref(Ctx &); | |
| } | |
| diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp | |
| index ec1f87a47479..0f0711171583 100644 | |
| --- a/lld/ELF/Writer.cpp | |
| +++ b/lld/ELF/Writer.cpp | |
| @@ -1521,6 +1521,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() { | |
| if (ctx.arg.randomizeSectionPadding) | |
| randomizeSectionPadding(ctx); | |
| + unsigned ps = getenv("S") ? 31 : 30; | |
| uint32_t pass = 0, assignPasses = 0; | |
| for (;;) { | |
| bool changed = ctx.target->needsThunks | |
| @@ -1532,10 +1533,17 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() { | |
| // With Thunk Size much smaller than branch range we expect to | |
| // converge quickly; if we get to 30 something has gone wrong. | |
| - if (changed && pass >= 30) { | |
| - Err(ctx) << "address assignment did not converge"; | |
| + if (changed && pass >= ps) { | |
| + Err(ctx) << "address assignment did not converge " << ps; | |
| break; | |
| } | |
| + if (pass >= 29) { | |
| + std::error_code ec; | |
| + using namespace llvm::sys::fs; | |
| + llvm::raw_fd_ostream os(("/t/" + Twine(pass) + ".map").str(), ec, | |
| + OF_None); | |
| + writeMapFile(ctx, os); | |
| + } | |
| if (ctx.arg.fixCortexA53Errata843419) { | |
| if (changed) | |
| -- | |
| 2.43.0 |