diff --git a/0002-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-6-relocation-type.patch b/0002-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-6-relocation-type.patch deleted file mode 100644 index d467aa2ade3f620e3fe94d877ccefcf7e1509e18..0000000000000000000000000000000000000000 --- a/0002-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-6-relocation-type.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 7f14e7c1b116fc865ddebb78e67816bfc5216178 Mon Sep 17 00:00:00 2001 -From: Jinyang He -Date: Wed, 15 Nov 2023 09:57:45 +0800 -Subject: [PATCH 01/14] [lld][LoongArch] Support the R_LARCH_{ADD,SUB}6 - relocation type (#72190) - -The R_LARCH_{ADD,SUB}6 relocation type are usually used by DwarfCFA to -calculate a tiny offset. They appear after binutils 2.41, with GAS -enabling relaxation by default. - -(cherry picked from commit 72accbfd0a1023b3182202276904120524ff9200) -Change-Id: Iad676e522f11c52e5dc381243f1df60edcef58f5 ---- - lld/ELF/Arch/LoongArch.cpp | 8 ++++++++ - lld/test/ELF/loongarch-add-sub.s | 6 +++++- - 2 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp -index 04ddb4682917..d3a538577a59 100644 ---- a/lld/ELF/Arch/LoongArch.cpp -+++ b/lld/ELF/Arch/LoongArch.cpp -@@ -444,10 +444,12 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, - case R_LARCH_TLS_LE64_LO20: - case R_LARCH_TLS_LE64_HI12: - return R_TPREL; -+ case R_LARCH_ADD6: - case R_LARCH_ADD8: - case R_LARCH_ADD16: - case R_LARCH_ADD32: - case R_LARCH_ADD64: -+ case R_LARCH_SUB6: - case R_LARCH_SUB8: - case R_LARCH_SUB16: - case R_LARCH_SUB32: -@@ -650,6 +652,9 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, - write32le(loc, setK12(read32le(loc), extractBits(val, 63, 52))); - return; - -+ case R_LARCH_ADD6: -+ *loc = (*loc & 0xc0) | ((*loc + val) & 0x3f); -+ return; - case R_LARCH_ADD8: - *loc += val; - return; -@@ -662,6 +667,9 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, - case R_LARCH_ADD64: - write64le(loc, read64le(loc) + val); - return; -+ case R_LARCH_SUB6: -+ *loc = (*loc & 0xc0) | ((*loc - val) & 0x3f); -+ return; - case R_LARCH_SUB8: - *loc -= val; - return; -diff --git a/lld/test/ELF/loongarch-add-sub.s b/lld/test/ELF/loongarch-add-sub.s -index 63a3f7de179e..35f8a053d69c 100644 ---- a/lld/test/ELF/loongarch-add-sub.s -+++ b/lld/test/ELF/loongarch-add-sub.s -@@ -6,7 +6,7 @@ - # RUN: llvm-readelf -x .rodata %t.la64 | FileCheck --check-prefix=CHECK %s - # CHECK: section '.rodata': - # CHECK-NEXT: 0x9876543210 10325476 98badcfe 804602be 79ffffff --# CHECK-NEXT: 0x9876543220 804602be 804680 -+# CHECK-NEXT: 0x9876543220 804602be 80468097 - - .text - .global _start -@@ -34,3 +34,7 @@ quux: - .byte 0 - .reloc quux, R_LARCH_ADD8, 1b - .reloc quux, R_LARCH_SUB8, 2b -+qux: -+ .byte 0b10000000 -+ .reloc qux, R_LARCH_ADD6, qux -+ .reloc qux, R_LARCH_SUB6, 2b --- -2.20.1 - diff --git a/0003-Backport-ELF-RISCV-Implement-emit-relocs-with-relaxation.patch b/0003-Backport-ELF-RISCV-Implement-emit-relocs-with-relaxation.patch deleted file mode 100644 index 16ed8746e43b0695fe8e606d279fbe0a1d493fe5..0000000000000000000000000000000000000000 --- a/0003-Backport-ELF-RISCV-Implement-emit-relocs-with-relaxation.patch +++ /dev/null @@ -1,239 +0,0 @@ -From d53182c7fcc371f575fd71fa74e28220db6e9b82 Mon Sep 17 00:00:00 2001 -From: Job Noorman -Date: Sat, 9 Sep 2023 10:24:16 +0200 -Subject: [PATCH 09/14] [ELF][RISCV] Implement --emit-relocs with relaxation - -Linker relaxation may change relocations (offsets and types). However, -when --emit-relocs is used, relocations are simply copied from the input -section causing a mismatch with the corresponding (relaxed) code -section. - -This patch fixes this as follows: for non-relocatable RISC-V binaries, -`InputSection::copyRelocations` reads relocations from the relocated -section's `relocations` array (since this gets updated by the relaxation -code). For all other cases, relocations are read from the input section -directly as before. - -In order to reuse as much code as possible, and to keep the diff small, -the original `InputSection::copyRelocations` is changed to accept the -relocations as a range of `Relocation` objects. This means that, in the -general case when reading from the input section, raw relocations need -to be converted to `Relocation`s first, which introduces quite a bit of -boiler plate. It also means there's a slight code size increase due to -the extra instantiations of `copyRelocations` (for both range types). - -Reviewed By: MaskRay - -Differential Revision: https://reviews.llvm.org/D159082 - -(cherry picked from commit 649cac3b627fa3d466b8807536c8be970cc8c32f) -Change-Id: I53aeeeed4bea0d74c5571bc90405bcbd363781b2 ---- - lld/ELF/InputSection.cpp | 56 ++++++++++++++++----- - lld/ELF/InputSection.h | 6 ++- - lld/test/ELF/riscv-relax-emit-relocs.s | 69 ++++++++++++++++++++++++++ - 3 files changed, 117 insertions(+), 14 deletions(-) - create mode 100644 lld/test/ELF/riscv-relax-emit-relocs.s - -diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp -index 2edaa2b40493..1aff6b968d86 100644 ---- a/lld/ELF/InputSection.cpp -+++ b/lld/ELF/InputSection.cpp -@@ -349,29 +349,61 @@ InputSectionBase *InputSection::getRelocatedSection() const { - return sections[info]; - } - -+template -+void InputSection::copyRelocations(uint8_t *buf) { -+ if (config->relax && !config->relocatable && config->emachine == EM_RISCV) { -+ // On RISC-V, relaxation might change relocations: copy from -+ // internal ones that are updated by relaxation. -+ InputSectionBase *sec = getRelocatedSection(); -+ copyRelocations(buf, llvm::make_range(sec->relocations.begin(), -+ sec->relocations.end())); -+ } else { -+ // Convert the raw relocations in the input section into Relocation objects -+ // suitable to be used by copyRelocations below. -+ struct MapRel { -+ const ObjFile &file; -+ Relocation operator()(const RelTy &rel) const { -+ // RelExpr is not used so set to a dummy value. -+ return Relocation{R_NONE, rel.getType(config->isMips64EL), rel.r_offset, -+ getAddend(rel), &file.getRelocTargetSym(rel)}; -+ } -+ }; -+ -+ using RawRels = ArrayRef; -+ using MapRelIter = -+ llvm::mapped_iterator; -+ auto mapRel = MapRel{*getFile()}; -+ RawRels rawRels = getDataAs(); -+ auto rels = llvm::make_range(MapRelIter(rawRels.begin(), mapRel), -+ MapRelIter(rawRels.end(), mapRel)); -+ copyRelocations(buf, rels); -+ } -+} -+ - // This is used for -r and --emit-relocs. We can't use memcpy to copy - // relocations because we need to update symbol table offset and section index - // for each relocation. So we copy relocations one by one. --template --void InputSection::copyRelocations(uint8_t *buf, ArrayRef rels) { -+template -+void InputSection::copyRelocations(uint8_t *buf, -+ llvm::iterator_range rels) { - const TargetInfo &target = *elf::target; - InputSectionBase *sec = getRelocatedSection(); - (void)sec->contentMaybeDecompress(); // uncompress if needed - -- for (const RelTy &rel : rels) { -- RelType type = rel.getType(config->isMips64EL); -+ for (const Relocation &rel : rels) { -+ RelType type = rel.type; - const ObjFile *file = getFile(); -- Symbol &sym = file->getRelocTargetSym(rel); -+ Symbol &sym = *rel.sym; - - auto *p = reinterpret_cast(buf); - buf += sizeof(RelTy); - - if (RelTy::IsRela) -- p->r_addend = getAddend(rel); -+ p->r_addend = rel.addend; - - // Output section VA is zero for -r, so r_offset is an offset within the - // section, but for --emit-relocs it is a virtual address. -- p->r_offset = sec->getVA(rel.r_offset); -+ p->r_offset = sec->getVA(rel.offset); - p->setSymbolAndType(in.symTab->getSymbolIndex(&sym), type, - config->isMips64EL); - -@@ -408,8 +440,8 @@ void InputSection::copyRelocations(uint8_t *buf, ArrayRef rels) { - continue; - } - -- int64_t addend = getAddend(rel); -- const uint8_t *bufLoc = sec->content().begin() + rel.r_offset; -+ int64_t addend = rel.addend; -+ const uint8_t *bufLoc = sec->content().begin() + rel.offset; - if (!RelTy::IsRela) - addend = target.getImplicitAddend(bufLoc, type); - -@@ -432,7 +464,7 @@ void InputSection::copyRelocations(uint8_t *buf, ArrayRef rels) { - if (RelTy::IsRela) - p->r_addend = sym.getVA(addend) - section->getOutputSection()->addr; - else if (config->relocatable && type != target.noneRel) -- sec->addReloc({R_ABS, type, rel.r_offset, addend, &sym}); -+ sec->addReloc({R_ABS, type, rel.offset, addend, &sym}); - } else if (config->emachine == EM_PPC && type == R_PPC_PLTREL24 && - p->r_addend >= 0x8000 && sec->file->ppc32Got2) { - // Similar to R_MIPS_GPREL{16,32}. If the addend of R_PPC_PLTREL24 -@@ -1106,11 +1138,11 @@ template void InputSection::writeTo(uint8_t *buf) { - // If -r or --emit-relocs is given, then an InputSection - // may be a relocation section. - if (LLVM_UNLIKELY(type == SHT_RELA)) { -- copyRelocations(buf, getDataAs()); -+ copyRelocations(buf); - return; - } - if (LLVM_UNLIKELY(type == SHT_REL)) { -- copyRelocations(buf, getDataAs()); -+ copyRelocations(buf); - return; - } - -diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h -index 15122d6abd6b..2b91711abba3 100644 ---- a/lld/ELF/InputSection.h -+++ b/lld/ELF/InputSection.h -@@ -396,8 +396,10 @@ public: - static InputSection discarded; - - private: -- template -- void copyRelocations(uint8_t *buf, llvm::ArrayRef rels); -+ template void copyRelocations(uint8_t *buf); -+ -+ template -+ void copyRelocations(uint8_t *buf, llvm::iterator_range rels); - - template void copyShtGroup(uint8_t *buf); - }; -diff --git a/lld/test/ELF/riscv-relax-emit-relocs.s b/lld/test/ELF/riscv-relax-emit-relocs.s -new file mode 100644 -index 000000000000..ebd69b742d4f ---- /dev/null -+++ b/lld/test/ELF/riscv-relax-emit-relocs.s -@@ -0,0 +1,69 @@ -+# REQUIRES: riscv -+## Test that we can handle --emit-relocs while relaxing. -+ -+# RUN: rm -rf %t && mkdir %t && cd %t -+ -+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+relax %s -o 32.o -+# RUN: ld.lld -Ttext=0x10000 --emit-relocs 32.o -o 32 -+# RUN: llvm-objdump -dr --no-show-raw-insn -M no-aliases 32 | FileCheck %s -+ -+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax %s -o 64.o -+# RUN: ld.lld -Ttext=0x10000 --emit-relocs 64.o -o 64 -+# RUN: llvm-objdump -dr --no-show-raw-insn -M no-aliases 64 | FileCheck %s -+ -+## -r should keep original relocations. -+# RUN: ld.lld -r 64.o -o 64.r -+# RUN: llvm-objdump -dr --no-show-raw-insn -M no-aliases 64.r | FileCheck %s --check-prefix=CHECKR -+ -+## --no-relax should keep original relocations. -+# RUN: ld.lld --emit-relocs --no-relax 64.o -o 64.norelax -+# RUN: llvm-objdump -dr --no-show-raw-insn -M no-aliases 64.norelax | FileCheck %s --check-prefix=CHECKNORELAX -+ -+# CHECK: <_start>: -+# CHECK-NEXT: jal ra, 0x10008 -+# CHECK-NEXT: R_RISCV_JAL f -+# CHECK-NEXT: R_RISCV_RELAX *ABS* -+# CHECK-NEXT: jal ra, 0x10008 -+# CHECK-NEXT: R_RISCV_JAL f -+# CHECK-NEXT: R_RISCV_RELAX *ABS* -+# CHECK-EMPTY: -+# CHECK-NEXT: : -+# CHECK-NEXT: jalr zero, 0(ra) -+# CHECK-NEXT: R_RISCV_ALIGN *ABS*+0x4 -+ -+# CHECKR: <_start>: -+# CHECKR-NEXT: auipc ra, 0 -+# CHECKR-NEXT: R_RISCV_CALL_PLT f -+# CHECKR-NEXT: R_RISCV_RELAX *ABS* -+# CHECKR-NEXT: jalr ra, 0(ra) -+# CHECKR-NEXT: auipc ra, 0 -+# CHECKR-NEXT: R_RISCV_CALL_PLT f -+# CHECKR-NEXT: R_RISCV_RELAX *ABS* -+# CHECKR-NEXT: jalr ra, 0(ra) -+# CHECKR-NEXT: addi zero, zero, 0 -+# CHECKR-NEXT: R_RISCV_ALIGN *ABS*+0x4 -+# CHECKR-EMPTY: -+# CHECKR-NEXT: : -+# CHECKR-NEXT: jalr zero, 0(ra) -+ -+# CHECKNORELAX: <_start>: -+# CHECKNORELAX-NEXT: auipc ra, 0 -+# CHECKNORELAX-NEXT: R_RISCV_CALL_PLT f -+# CHECKNORELAX-NEXT: R_RISCV_RELAX *ABS* -+# CHECKNORELAX-NEXT: jalr ra, 16(ra) -+# CHECKNORELAX-NEXT: auipc ra, 0 -+# CHECKNORELAX-NEXT: R_RISCV_CALL_PLT f -+# CHECKNORELAX-NEXT: R_RISCV_RELAX *ABS* -+# CHECKNORELAX-NEXT: jalr ra, 8(ra) -+# CHECKNORELAX-EMPTY: -+# CHECKNORELAX-NEXT: : -+# CHECKNORELAX-NEXT: jalr zero, 0(ra) -+# CHECKNORELAX-NEXT: R_RISCV_ALIGN *ABS*+0x4 -+ -+.global _start -+_start: -+ call f -+ call f -+ .balign 8 -+f: -+ ret --- -2.20.1 - diff --git a/0004-Backport-lld-ELF-Support-relax-R_LARCH_ALIGN.patch b/0004-Backport-lld-ELF-Support-relax-R_LARCH_ALIGN.patch deleted file mode 100644 index 604fadfa226a405f3bba218e7fb9ac4fc1366fb3..0000000000000000000000000000000000000000 --- a/0004-Backport-lld-ELF-Support-relax-R_LARCH_ALIGN.patch +++ /dev/null @@ -1,563 +0,0 @@ -From 80c56e85d742bb88533e4789c76ae2b55dc36835 Mon Sep 17 00:00:00 2001 -From: Jinyang He -Date: Tue, 6 Feb 2024 09:09:13 +0800 -Subject: [PATCH 10/14] [lld][ELF] Support relax R_LARCH_ALIGN (#78692) - -Refer to commit 6611d58f5bbc ("Relax R_RISCV_ALIGN"), we can relax -R_LARCH_ALIGN by same way. Reuse `SymbolAnchor`, `RISCVRelaxAux` and -`initSymbolAnchors` to simplify codes. As `riscvFinalizeRelax` is an -arch-specific function, put it override on `TargetInfo::finalizeRelax`, -so that LoongArch can override it, too. - -The flow of relax R_LARCH_ALIGN is almost consistent with RISCV. The -difference is that LoongArch only has 4-bytes NOP and all executable -insn is 4-bytes aligned. So LoongArch not need rewrite NOP sequence. -Alignment maxBytesEmit parameter is supported in psABI v2.30. - -(cherry picked from commit 06a728f3feab876f9195738b5774e82dadc0f3a7) -(cherry picked from commit 60a8ec3a35c722a9eb8298c215321b89d0faf5b5) -Change-Id: I680e9a44f05fb2cc820736eee63ddd999e689daf ---- - lld/ELF/Arch/LoongArch.cpp | 156 ++++++++++++++++++++- - lld/ELF/Arch/RISCV.cpp | 28 +--- - lld/ELF/InputSection.cpp | 5 +- - lld/ELF/InputSection.h | 24 +++- - lld/ELF/Target.h | 3 + - lld/ELF/Writer.cpp | 4 +- - lld/test/ELF/loongarch-relax-align.s | 126 +++++++++++++++++ - lld/test/ELF/loongarch-relax-emit-relocs.s | 49 +++++++ - 8 files changed, 362 insertions(+), 33 deletions(-) - create mode 100644 lld/test/ELF/loongarch-relax-align.s - create mode 100644 lld/test/ELF/loongarch-relax-emit-relocs.s - -diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp -index d3a538577a59..3f57a76873f9 100644 ---- a/lld/ELF/Arch/LoongArch.cpp -+++ b/lld/ELF/Arch/LoongArch.cpp -@@ -36,6 +36,8 @@ public: - bool usesOnlyLowPageBits(RelType type) const override; - void relocate(uint8_t *loc, const Relocation &rel, - uint64_t val) const override; -+ bool relaxOnce(int pass) const override; -+ void finalizeRelax(int passes) const override; - }; - } // end anonymous namespace - -@@ -521,8 +523,9 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, - case R_LARCH_TLS_GD_HI20: - return R_TLSGD_GOT; - case R_LARCH_RELAX: -- // LoongArch linker relaxation is not implemented yet. -- return R_NONE; -+ return config->relax ? R_RELAX_HINT : R_NONE; -+ case R_LARCH_ALIGN: -+ return R_RELAX_HINT; - - // Other known relocs that are explicitly unimplemented: - // -@@ -696,6 +699,155 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, - } - } - -+static bool relax(InputSection &sec) { -+ const uint64_t secAddr = sec.getVA(); -+ const MutableArrayRef relocs = sec.relocs(); -+ auto &aux = *sec.relaxAux; -+ bool changed = false; -+ ArrayRef sa = ArrayRef(aux.anchors); -+ uint64_t delta = 0; -+ -+ std::fill_n(aux.relocTypes.get(), relocs.size(), R_LARCH_NONE); -+ aux.writes.clear(); -+ for (auto [i, r] : llvm::enumerate(relocs)) { -+ const uint64_t loc = secAddr + r.offset - delta; -+ uint32_t &cur = aux.relocDeltas[i], remove = 0; -+ switch (r.type) { -+ case R_LARCH_ALIGN: { -+ const uint64_t addend = -+ r.sym->isUndefined() ? Log2_64(r.addend) + 1 : r.addend; -+ const uint64_t allBytes = (1 << (addend & 0xff)) - 4; -+ const uint64_t align = 1 << (addend & 0xff); -+ const uint64_t maxBytes = addend >> 8; -+ const uint64_t off = loc & (align - 1); -+ const uint64_t curBytes = off == 0 ? 0 : align - off; -+ // All bytes beyond the alignment boundary should be removed. -+ // If emit bytes more than max bytes to emit, remove all. -+ if (maxBytes != 0 && curBytes > maxBytes) -+ remove = allBytes; -+ else -+ remove = allBytes - curBytes; -+ // If we can't satisfy this alignment, we've found a bad input. -+ if (LLVM_UNLIKELY(static_cast(remove) < 0)) { -+ errorOrWarn(getErrorLocation((const uint8_t *)loc) + -+ "insufficient padding bytes for " + lld::toString(r.type) + -+ ": " + Twine(allBytes) + " bytes available for " + -+ "requested alignment of " + Twine(align) + " bytes"); -+ remove = 0; -+ } -+ break; -+ } -+ } -+ -+ // For all anchors whose offsets are <= r.offset, they are preceded by -+ // the previous relocation whose `relocDeltas` value equals `delta`. -+ // Decrease their st_value and update their st_size. -+ for (; sa.size() && sa[0].offset <= r.offset; sa = sa.slice(1)) { -+ if (sa[0].end) -+ sa[0].d->size = sa[0].offset - delta - sa[0].d->value; -+ else -+ sa[0].d->value = sa[0].offset - delta; -+ } -+ delta += remove; -+ if (delta != cur) { -+ cur = delta; -+ changed = true; -+ } -+ } -+ -+ for (const SymbolAnchor &a : sa) { -+ if (a.end) -+ a.d->size = a.offset - delta - a.d->value; -+ else -+ a.d->value = a.offset - delta; -+ } -+ // Inform assignAddresses that the size has changed. -+ if (!isUInt<32>(delta)) -+ fatal("section size decrease is too large: " + Twine(delta)); -+ sec.bytesDropped = delta; -+ return changed; -+} -+ -+// When relaxing just R_LARCH_ALIGN, relocDeltas is usually changed only once in -+// the absence of a linker script. For call and load/store R_LARCH_RELAX, code -+// shrinkage may reduce displacement and make more relocations eligible for -+// relaxation. Code shrinkage may increase displacement to a call/load/store -+// target at a higher fixed address, invalidating an earlier relaxation. Any -+// change in section sizes can have cascading effect and require another -+// relaxation pass. -+bool LoongArch::relaxOnce(int pass) const { -+ if (config->relocatable) -+ return false; -+ -+ if (pass == 0) -+ initSymbolAnchors(); -+ -+ SmallVector storage; -+ bool changed = false; -+ for (OutputSection *osec : outputSections) { -+ if (!(osec->flags & SHF_EXECINSTR)) -+ continue; -+ for (InputSection *sec : getInputSections(*osec, storage)) -+ changed |= relax(*sec); -+ } -+ return changed; -+} -+ -+void LoongArch::finalizeRelax(int passes) const { -+ log("relaxation passes: " + Twine(passes)); -+ SmallVector storage; -+ for (OutputSection *osec : outputSections) { -+ if (!(osec->flags & SHF_EXECINSTR)) -+ continue; -+ for (InputSection *sec : getInputSections(*osec, storage)) { -+ RelaxAux &aux = *sec->relaxAux; -+ if (!aux.relocDeltas) -+ continue; -+ -+ MutableArrayRef rels = sec->relocs(); -+ ArrayRef old = sec->content(); -+ size_t newSize = old.size() - aux.relocDeltas[rels.size() - 1]; -+ uint8_t *p = context().bAlloc.Allocate(newSize); -+ uint64_t offset = 0; -+ int64_t delta = 0; -+ sec->content_ = p; -+ sec->size = newSize; -+ sec->bytesDropped = 0; -+ -+ // Update section content: remove NOPs for R_LARCH_ALIGN and rewrite -+ // instructions for relaxed relocations. -+ for (size_t i = 0, e = rels.size(); i != e; ++i) { -+ uint32_t remove = aux.relocDeltas[i] - delta; -+ delta = aux.relocDeltas[i]; -+ if (remove == 0 && aux.relocTypes[i] == R_LARCH_NONE) -+ continue; -+ -+ // Copy from last location to the current relocated location. -+ const Relocation &r = rels[i]; -+ uint64_t size = r.offset - offset; -+ memcpy(p, old.data() + offset, size); -+ p += size; -+ offset = r.offset + remove; -+ } -+ memcpy(p, old.data() + offset, old.size() - offset); -+ -+ // Subtract the previous relocDeltas value from the relocation offset. -+ // For a pair of R_LARCH_XXX/R_LARCH_RELAX with the same offset, decrease -+ // their r_offset by the same delta. -+ delta = 0; -+ for (size_t i = 0, e = rels.size(); i != e;) { -+ uint64_t cur = rels[i].offset; -+ do { -+ rels[i].offset -= delta; -+ if (aux.relocTypes[i] != R_LARCH_NONE) -+ rels[i].type = aux.relocTypes[i]; -+ } while (++i != e && rels[i].offset == cur); -+ delta = aux.relocDeltas[i - 1]; -+ } -+ } -+ } -+} -+ - TargetInfo *elf::getLoongArchTargetInfo() { - static LoongArch target; - return ⌖ -diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp -index d0d75118e30d..06120cabc132 100644 ---- a/lld/ELF/Arch/RISCV.cpp -+++ b/lld/ELF/Arch/RISCV.cpp -@@ -44,6 +44,7 @@ public: - void relocate(uint8_t *loc, const Relocation &rel, - uint64_t val) const override; - bool relaxOnce(int pass) const override; -+ void finalizeRelax(int passes) const override; - }; - - } // end anonymous namespace -@@ -513,33 +514,14 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { - } - } - --namespace { --struct SymbolAnchor { -- uint64_t offset; -- Defined *d; -- bool end; // true for the anchor of st_value+st_size --}; --} // namespace -- --struct elf::RISCVRelaxAux { -- // This records symbol start and end offsets which will be adjusted according -- // to the nearest relocDeltas element. -- SmallVector anchors; -- // For relocations[i], the actual offset is r_offset - (i ? relocDeltas[i-1] : -- // 0). -- std::unique_ptr relocDeltas; -- // For relocations[i], the actual type is relocTypes[i]. -- std::unique_ptr relocTypes; -- SmallVector writes; --}; - --static void initSymbolAnchors() { -+void elf::initSymbolAnchors() { - SmallVector storage; - for (OutputSection *osec : outputSections) { - if (!(osec->flags & SHF_EXECINSTR)) - continue; - for (InputSection *sec : getInputSections(*osec, storage)) { -- sec->relaxAux = make(); -+ sec->relaxAux = make(); - if (sec->relocs().size()) { - sec->relaxAux->relocDeltas = - std::make_unique(sec->relocs().size()); -@@ -766,7 +748,7 @@ bool RISCV::relaxOnce(int pass) const { - return changed; - } - --void elf::riscvFinalizeRelax(int passes) { -+void RISCV::finalizeRelax(int passes) const { - llvm::TimeTraceScope timeScope("Finalize RISC-V relaxation"); - log("relaxation passes: " + Twine(passes)); - SmallVector storage; -@@ -774,7 +756,7 @@ void elf::riscvFinalizeRelax(int passes) { - if (!(osec->flags & SHF_EXECINSTR)) - continue; - for (InputSection *sec : getInputSections(*osec, storage)) { -- RISCVRelaxAux &aux = *sec->relaxAux; -+ RelaxAux &aux = *sec->relaxAux; - if (!aux.relocDeltas) - continue; - -diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp -index 1aff6b968d86..b178d82407e3 100644 ---- a/lld/ELF/InputSection.cpp -+++ b/lld/ELF/InputSection.cpp -@@ -351,8 +351,9 @@ InputSectionBase *InputSection::getRelocatedSection() const { - - template - void InputSection::copyRelocations(uint8_t *buf) { -- if (config->relax && !config->relocatable && config->emachine == EM_RISCV) { -- // On RISC-V, relaxation might change relocations: copy from -+ if (config->relax && !config->relocatable && -+ (config->emachine == EM_RISCV || config->emachine == EM_LOONGARCH)) { -+ // On LoongArch and RISC-V, relaxation might change relocations: copy from - // internal ones that are updated by relaxation. - InputSectionBase *sec = getRelocatedSection(); - copyRelocations(buf, llvm::make_range(sec->relocations.begin(), -diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h -index 2b91711abba3..842bc369909d 100644 ---- a/lld/ELF/InputSection.h -+++ b/lld/ELF/InputSection.h -@@ -101,7 +101,23 @@ protected: - link(link), info(info) {} - }; - --struct RISCVRelaxAux; -+struct SymbolAnchor { -+ uint64_t offset; -+ Defined *d; -+ bool end; // true for the anchor of st_value+st_size -+}; -+ -+struct RelaxAux { -+ // This records symbol start and end offsets which will be adjusted according -+ // to the nearest relocDeltas element. -+ SmallVector anchors; -+ // For relocations[i], the actual offset is -+ // r_offset - (i ? relocDeltas[i-1] : 0). -+ std::unique_ptr relocDeltas; -+ // For relocations[i], the actual type is relocTypes[i]. -+ std::unique_ptr relocTypes; -+ SmallVector writes; -+}; - - // This corresponds to a section of an input file. - class InputSectionBase : public SectionBase { -@@ -222,9 +238,9 @@ public: - // basic blocks. - JumpInstrMod *jumpInstrMod = nullptr; - -- // Auxiliary information for RISC-V linker relaxation. RISC-V does not use -- // jumpInstrMod. -- RISCVRelaxAux *relaxAux; -+ // Auxiliary information for RISC-V and LoongArch linker relaxation. -+ // They do not use jumpInstrMod. -+ RelaxAux *relaxAux; - - // The compressed content size when `compressed` is true. - size_t compressedSize; -diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h -index 47dbe6b4d1c6..bf831afa1793 100644 ---- a/lld/ELF/Target.h -+++ b/lld/ELF/Target.h -@@ -94,6 +94,8 @@ public: - - // Do a linker relaxation pass and return true if we changed something. - virtual bool relaxOnce(int pass) const { return false; } -+ // Do finalize relaxation after collecting relaxation infos. -+ virtual void finalizeRelax(int passes) const {} - - virtual void applyJumpInstrMod(uint8_t *loc, JumpModType type, - JumpModType val) const {} -@@ -234,6 +236,7 @@ void addArmInputSectionMappingSymbols(); - void addArmSyntheticSectionMappingSymbol(Defined *); - void sortArmMappingSymbols(); - void convertArmInstructionstoBE8(InputSection *sec, uint8_t *buf); -+void initSymbolAnchors(); - - LLVM_LIBRARY_VISIBILITY extern const TargetInfo *target; - TargetInfo *getTarget(); -diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp -index 368c9aabceae..dd37bbbf76c1 100644 ---- a/lld/ELF/Writer.cpp -+++ b/lld/ELF/Writer.cpp -@@ -1668,8 +1668,8 @@ template void Writer::finalizeAddressDependentContent() { - } - } - } -- if (!config->relocatable && config->emachine == EM_RISCV) -- riscvFinalizeRelax(pass); -+ if (!config->relocatable) -+ target->finalizeRelax(pass); - - if (config->relocatable) - for (OutputSection *sec : outputSections) -diff --git a/lld/test/ELF/loongarch-relax-align.s b/lld/test/ELF/loongarch-relax-align.s -new file mode 100644 -index 000000000000..ab61e15d5cac ---- /dev/null -+++ b/lld/test/ELF/loongarch-relax-align.s -@@ -0,0 +1,126 @@ -+# REQUIRES: loongarch -+ -+# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=+relax %s -o %t.32.o -+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.64.o -+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.32.o -o %t.32 -+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.64.o -o %t.64 -+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.32.o --no-relax -o %t.32n -+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.64.o --no-relax -o %t.64n -+# RUN: llvm-objdump -td --no-show-raw-insn %t.32 | FileCheck %s -+# RUN: llvm-objdump -td --no-show-raw-insn %t.64 | FileCheck %s -+# RUN: llvm-objdump -td --no-show-raw-insn %t.32n | FileCheck %s -+# RUN: llvm-objdump -td --no-show-raw-insn %t.64n | FileCheck %s -+ -+## Test the R_LARCH_ALIGN without symbol index. -+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.o64.o --defsym=old=1 -+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.o64.o -o %t.o64 -+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.o64.o --no-relax -o %t.o64n -+# RUN: llvm-objdump -td --no-show-raw-insn %t.o64 | FileCheck %s -+# RUN: llvm-objdump -td --no-show-raw-insn %t.o64n | FileCheck %s -+ -+## -r keeps section contents unchanged. -+# RUN: ld.lld -r %t.64.o -o %t.64.r -+# RUN: llvm-objdump -dr --no-show-raw-insn %t.64.r | FileCheck %s --check-prefix=CHECKR -+ -+# CHECK-DAG: {{0*}}10000 l .text {{0*}}44 .Ltext_start -+# CHECK-DAG: {{0*}}10038 l .text {{0*}}0c .L1 -+# CHECK-DAG: {{0*}}10040 l .text {{0*}}04 .L2 -+# CHECK-DAG: {{0*}}20000 l .text2 {{0*}}14 .Ltext2_start -+ -+# CHECK: <.Ltext_start>: -+# CHECK-NEXT: break 1 -+# CHECK-NEXT: break 2 -+# CHECK-NEXT: nop -+# CHECK-NEXT: nop -+# CHECK-NEXT: break 3 -+# CHECK-NEXT: break 4 -+# CHECK-NEXT: nop -+# CHECK-NEXT: nop -+# CHECK-NEXT: pcalau12i $a0, 0 -+# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 0 -+# CHECK-NEXT: pcalau12i $a0, 0 -+# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 56 -+# CHECK-NEXT: pcalau12i $a0, 0 -+# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 64 -+# CHECK-EMPTY: -+# CHECK-NEXT: <.L1>: -+# CHECK-NEXT: nop -+# CHECK-NEXT: nop -+# CHECK-EMPTY: -+# CHECK-NEXT: <.L2>: -+# CHECK-NEXT: break 5 -+ -+# CHECK: <.Ltext2_start>: -+# CHECK-NEXT: pcalau12i $a0, 0 -+# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 0 -+# CHECK-NEXT: nop -+# CHECK-NEXT: nop -+# CHECK-NEXT: break 6 -+ -+# CHECKR: <.Ltext2_start>: -+# CHECKR-NEXT: pcalau12i $a0, 0 -+# CHECKR-NEXT: {{0*}}00: R_LARCH_PCALA_HI20 .Ltext2_start -+# CHECKR-NEXT: {{0*}}00: R_LARCH_RELAX *ABS* -+# CHECKR-NEXT: addi.d $a0, $a0, 0 -+# CHECKR-NEXT: {{0*}}04: R_LARCH_PCALA_LO12 .Ltext2_start -+# CHECKR-NEXT: {{0*}}04: R_LARCH_RELAX *ABS* -+# CHECKR-NEXT: nop -+# CHECKR-NEXT: {{0*}}08: R_LARCH_ALIGN .Lalign_symbol+0x4 -+# CHECKR-NEXT: nop -+# CHECKR-NEXT: nop -+# CHECKR-NEXT: break 6 -+ -+.macro .fake_p2align_4 max=0 -+ .ifdef old -+ .if \max==0 -+ .reloc ., R_LARCH_ALIGN, 0xc -+ nop; nop; nop -+ .endif -+ .else -+ .reloc ., R_LARCH_ALIGN, .Lalign_symbol + 0x4 + (\max << 8) -+ nop; nop; nop -+ .endif -+.endm -+ -+ .text -+.Lalign_symbol: -+.Ltext_start: -+ break 1 -+ break 2 -+## +0x8: Emit 2 nops, delete 1 nop. -+ .fake_p2align_4 -+ -+ break 3 -+## +0x14: Emit 3 nops > 8 bytes, not emit. -+ .fake_p2align_4 8 -+ -+ break 4 -+ .fake_p2align_4 8 -+## +0x18: Emit 2 nops <= 8 bytes. -+ -+## Compensate -+.ifdef old -+ nop; nop -+.endif -+ -+## +0x20: Test symbol value and symbol size can be handled. -+ la.pcrel $a0, .Ltext_start -+ la.pcrel $a0, .L1 -+ la.pcrel $a0, .L2 -+ -+## +0x38: Emit 2 nops, delete 1 nop. -+.L1: -+ .fake_p2align_4 -+.L2: -+ break 5 -+ .size .L1, . - .L1 -+ .size .L2, . - .L2 -+ .size .Ltext_start, . - .Ltext_start -+ -+## Test another text section. -+ .section .text2,"ax",@progbits -+.Ltext2_start: -+ la.pcrel $a0, .Ltext2_start -+ .fake_p2align_4 -+ break 6 -+ .size .Ltext2_start, . - .Ltext2_start -diff --git a/lld/test/ELF/loongarch-relax-emit-relocs.s b/lld/test/ELF/loongarch-relax-emit-relocs.s -new file mode 100644 -index 000000000000..581fce8c95ca ---- /dev/null -+++ b/lld/test/ELF/loongarch-relax-emit-relocs.s -@@ -0,0 +1,49 @@ -+# REQUIRES: loongarch -+## Test that we can handle --emit-relocs while relaxing. -+ -+# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=+relax %s -o %t.32.o -+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.64.o -+# RUN: ld.lld -Ttext=0x10000 --emit-relocs %t.32.o -o %t.32 -+# RUN: ld.lld -Ttext=0x10000 --emit-relocs %t.64.o -o %t.64 -+# RUN: llvm-objdump -dr %t.32 | FileCheck %s -+# RUN: llvm-objdump -dr %t.64 | FileCheck %s -+ -+## -r should keep original relocations. -+# RUN: ld.lld -r %t.64.o -o %t.64.r -+# RUN: llvm-objdump -dr %t.64.r | FileCheck %s --check-prefix=CHECKR -+ -+## --no-relax should keep original relocations. -+## TODO Due to R_LARCH_RELAX is not relaxed, it plays same as --relax now. -+# RUN: ld.lld -Ttext=0x10000 --emit-relocs --no-relax %t.64.o -o %t.64.norelax -+# RUN: llvm-objdump -dr %t.64.norelax | FileCheck %s -+ -+# CHECK: 00010000 <_start>: -+# CHECK-NEXT: pcalau12i $a0, 0 -+# CHECK-NEXT: R_LARCH_PCALA_HI20 _start -+# CHECK-NEXT: R_LARCH_RELAX *ABS* -+# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 0 -+# CHECK-NEXT: R_LARCH_PCALA_LO12 _start -+# CHECK-NEXT: R_LARCH_RELAX *ABS* -+# CHECK-NEXT: nop -+# CHECK-NEXT: R_LARCH_ALIGN .Lla-relax-align0+0x4 -+# CHECK-NEXT: nop -+# CHECK-NEXT: ret -+ -+# CHECKR: <_start>: -+# CHECKR-NEXT: pcalau12i $a0, 0 -+# CHECKR-NEXT: R_LARCH_PCALA_HI20 _start -+# CHECKR-NEXT: R_LARCH_RELAX *ABS* -+# CHECKR-NEXT: addi.d $a0, $a0, 0 -+# CHECKR-NEXT: R_LARCH_PCALA_LO12 _start -+# CHECKR-NEXT: R_LARCH_RELAX *ABS* -+# CHECKR-NEXT: nop -+# CHECKR-NEXT: R_LARCH_ALIGN .Lla-relax-align0+0x4 -+# CHECKR-NEXT: nop -+# CHECKR-NEXT: nop -+# CHECKR-NEXT: ret -+ -+.global _start -+_start: -+ la.pcrel $a0, _start -+ .p2align 4 -+ ret --- -2.20.1 - diff --git a/0005-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-_ULEB128-relocation-types.patch b/0005-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-_ULEB128-relocation-types.patch deleted file mode 100644 index ca71e30810098c8f5b6bcfbac362bc9d0ed6a65f..0000000000000000000000000000000000000000 --- a/0005-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-_ULEB128-relocation-types.patch +++ /dev/null @@ -1,199 +0,0 @@ -From a5c1174c902a9dc7fb15aa047ca31e012aea6af9 Mon Sep 17 00:00:00 2001 -From: Jinyang He -Date: Tue, 5 Mar 2024 15:50:14 +0800 -Subject: [PATCH 12/14] [lld][LoongArch] Support the R_LARCH_{ADD,SUB}_ULEB128 - relocation types (#81133) - -For a label difference like `.uleb128 A-B`, MC generates a pair of -R_LARCH_{ADD,SUB}_ULEB128 if A-B cannot be folded as a constant. GNU -assembler generates a pair of relocations in more cases (when A or B is -in a code section with linker relaxation). It is similar to RISCV. - -R_LARCH_{ADD,SUB}_ULEB128 relocations are created by Clang and GCC in -`.gcc_except_table` and other debug sections with linker relaxation -enabled. On LoongArch, first read the buf and count the available space. -Then add or sub the value. Finally truncate the expected value and fill -it into the available space. - -(cherry picked from commit eaa9ef678c63bf392ec2d5b736605db7ea7e7338) -Change-Id: Ic49d34146e47eeeabbbba00ef70b76a13322d80e ---- - lld/ELF/Arch/LoongArch.cpp | 19 +++++ - lld/test/ELF/loongarch-reloc-leb128.s | 102 ++++++++++++++++++++++++++ - 2 files changed, 121 insertions(+) - create mode 100644 lld/test/ELF/loongarch-reloc-leb128.s - -diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp -index 3f57a76873f9..160fab4aeba9 100644 ---- a/lld/ELF/Arch/LoongArch.cpp -+++ b/lld/ELF/Arch/LoongArch.cpp -@@ -11,6 +11,7 @@ - #include "Symbols.h" - #include "SyntheticSections.h" - #include "Target.h" -+#include "llvm/Support/LEB128.h" - - using namespace llvm; - using namespace llvm::object; -@@ -210,6 +211,16 @@ static bool isJirl(uint32_t insn) { - return (insn & 0xfc000000) == JIRL; - } - -+static void handleUleb128(uint8_t *loc, uint64_t val) { -+ const uint32_t maxcount = 1 + 64 / 7; -+ uint32_t count; -+ uint64_t orig = decodeULEB128(loc, &count); -+ if (count > maxcount) -+ errorOrWarn(getErrorLocation(loc) + "extra space for uleb128"); -+ uint64_t mask = count < maxcount ? (1ULL << 7 * count) - 1 : -1ULL; -+ encodeULEB128((orig + val) & mask, loc, count); -+} -+ - LoongArch::LoongArch() { - // The LoongArch ISA itself does not have a limit on page sizes. According to - // the ISA manual, the PS (page size) field in MTLB entries and CSR.STLBPS is -@@ -451,11 +462,13 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, - case R_LARCH_ADD16: - case R_LARCH_ADD32: - case R_LARCH_ADD64: -+ case R_LARCH_ADD_ULEB128: - case R_LARCH_SUB6: - case R_LARCH_SUB8: - case R_LARCH_SUB16: - case R_LARCH_SUB32: - case R_LARCH_SUB64: -+ case R_LARCH_SUB_ULEB128: - // The LoongArch add/sub relocs behave like the RISCV counterparts; reuse - // the RelExpr to avoid code duplication. - return R_RISCV_ADD; -@@ -670,6 +683,9 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, - case R_LARCH_ADD64: - write64le(loc, read64le(loc) + val); - return; -+ case R_LARCH_ADD_ULEB128: -+ handleUleb128(loc, val); -+ return; - case R_LARCH_SUB6: - *loc = (*loc & 0xc0) | ((*loc - val) & 0x3f); - return; -@@ -685,6 +701,9 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, - case R_LARCH_SUB64: - write64le(loc, read64le(loc) - val); - return; -+ case R_LARCH_SUB_ULEB128: -+ handleUleb128(loc, -val); -+ return; - - case R_LARCH_MARK_LA: - case R_LARCH_MARK_PCREL: -diff --git a/lld/test/ELF/loongarch-reloc-leb128.s b/lld/test/ELF/loongarch-reloc-leb128.s -new file mode 100644 -index 000000000000..7740ca797fca ---- /dev/null -+++ b/lld/test/ELF/loongarch-reloc-leb128.s -@@ -0,0 +1,102 @@ -+# REQUIRES: loongarch -+# RUN: rm -rf %t && split-file %s %t && cd %t -+ -+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax a.s -o a.o -+# RUN: llvm-readobj -r -x .gcc_except_table -x .debug_rnglists -x .debug_loclists a.o | FileCheck %s --check-prefix=REL -+# RUN: ld.lld -shared --gc-sections a.o -o a.so -+# RUN: llvm-readelf -x .gcc_except_table -x .debug_rnglists -x .debug_loclists a.so | FileCheck %s -+ -+# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=+relax a.s -o a32.o -+# RUN: llvm-readobj -r -x .gcc_except_table -x .debug_rnglists -x .debug_loclists a32.o | FileCheck %s --check-prefix=REL -+# RUN: ld.lld -shared --gc-sections a32.o -o a32.so -+# RUN: llvm-readelf -x .gcc_except_table -x .debug_rnglists -x .debug_loclists a32.so | FileCheck %s -+ -+# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=+relax extraspace.s -o extraspace32.o -+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax extraspace.s -o extraspace64.o -+# RUN: not ld.lld -shared extraspace32.o 2>&1 | FileCheck %s --check-prefix=ERROR -+# RUN: not ld.lld -shared extraspace64.o 2>&1 | FileCheck %s --check-prefix=ERROR -+# ERROR: error: extraspace{{.*}}.o:(.rodata+0x0): extra space for uleb128 -+ -+#--- a.s -+.cfi_startproc -+.cfi_lsda 0x1b,.LLSDA0 -+.cfi_endproc -+ -+.section .text.w,"axR" -+break 0; break 0; break 0; w1: -+ .p2align 4 # 4 bytes after relaxation -+w2: break 0 -+ -+.section .text.x,"ax" -+break 0; break 0; break 0; x1: -+ .p2align 4 # 4 bytes after relaxation -+x2: break 0 -+ -+.section .gcc_except_table,"a" -+.LLSDA0: -+.uleb128 w2-w1+116 # initial value: 0x0080 -+.uleb128 w1-w2+141 # initial value: 0x0080 -+.uleb128 w2-w1+16372 # initial value: 0x008080 -+.uleb128 w1-w2+16397 # initial value: 0x008080 -+.uleb128 w2-w1+2097140 # initial value: 0x00808080 -+.uleb128 w1-w2+2097165 # initial value: 0x00808080 -+ -+.section .debug_rnglists -+.uleb128 w2-w1+116 # initial value: 0x0080 -+.uleb128 w1-w2+141 # initial value: 0x0080 -+.uleb128 w2-w1+16372 # initial value: 0x008080 -+.uleb128 w1-w2+16397 # initial value: 0x008080 -+.uleb128 w2-w1+2097140 # initial value: 0x00808080 -+.uleb128 w1-w2+2097165 # initial value: 0x00808080 -+ -+.section .debug_loclists -+.uleb128 x2-x1 # references discarded symbols -+ -+# REL: Section ({{.*}}) .rela.debug_rnglists { -+# REL-NEXT: 0x0 R_LARCH_ADD_ULEB128 w2 0x74 -+# REL-NEXT: 0x0 R_LARCH_SUB_ULEB128 w1 0x0 -+# REL-NEXT: 0x2 R_LARCH_ADD_ULEB128 w1 0x8D -+# REL-NEXT: 0x2 R_LARCH_SUB_ULEB128 w2 0x0 -+# REL-NEXT: 0x4 R_LARCH_ADD_ULEB128 w2 0x3FF4 -+# REL-NEXT: 0x4 R_LARCH_SUB_ULEB128 w1 0x0 -+# REL-NEXT: 0x7 R_LARCH_ADD_ULEB128 w1 0x400D -+# REL-NEXT: 0x7 R_LARCH_SUB_ULEB128 w2 0x0 -+# REL-NEXT: 0xA R_LARCH_ADD_ULEB128 w2 0x1FFFF4 -+# REL-NEXT: 0xA R_LARCH_SUB_ULEB128 w1 0x0 -+# REL-NEXT: 0xE R_LARCH_ADD_ULEB128 w1 0x20000D -+# REL-NEXT: 0xE R_LARCH_SUB_ULEB128 w2 0x0 -+# REL-NEXT: } -+# REL: Section ({{.*}}) .rela.debug_loclists { -+# REL-NEXT: 0x0 R_LARCH_ADD_ULEB128 x2 0x0 -+# REL-NEXT: 0x0 R_LARCH_SUB_ULEB128 x1 0x0 -+# REL-NEXT: } -+ -+# REL: Hex dump of section '.gcc_except_table': -+# REL-NEXT: 0x00000000 80008000 80800080 80008080 80008080 . -+# REL-NEXT: 0x00000010 8000 . -+# REL: Hex dump of section '.debug_rnglists': -+# REL-NEXT: 0x00000000 80008000 80800080 80008080 80008080 . -+# REL-NEXT: 0x00000010 8000 . -+# REL: Hex dump of section '.debug_loclists': -+# REL-NEXT: 0x00000000 00 . -+ -+# CHECK: Hex dump of section '.gcc_except_table': -+# CHECK-NEXT: 0x[[#%x,]] f8008901 f8ff0089 8001f8ff ff008980 . -+# CHECK-NEXT: 0x[[#%x,]] 8001 . -+# CHECK: Hex dump of section '.debug_rnglists': -+# CHECK-NEXT: 0x00000000 f8008901 f8ff0089 8001f8ff ff008980 . -+# CHECK-NEXT: 0x00000010 8001 . -+# CHECK: Hex dump of section '.debug_loclists': -+# CHECK-NEXT: 0x00000000 0c . -+ -+#--- extraspace.s -+.text -+w1: -+ la.pcrel $t0, w1 -+w2: -+ -+.rodata -+.reloc ., R_LARCH_ADD_ULEB128, w2 -+.reloc ., R_LARCH_SUB_ULEB128, w1 -+.fill 10, 1, 0x80 -+.byte 0 --- -2.20.1 - diff --git a/0006-Add-BiSheng-Autotuner-support-for-LLVM-compiler.patch b/0006-Add-BiSheng-Autotuner-support-for-LLVM-compiler.patch deleted file mode 100644 index d65be064cb1aee3080e75c1a3eadd44f43982505..0000000000000000000000000000000000000000 --- a/0006-Add-BiSheng-Autotuner-support-for-LLVM-compiler.patch +++ /dev/null @@ -1,56 +0,0 @@ -From a9863e2b6e6783aa9be0b9d1d187084fd4b32a3a Mon Sep 17 00:00:00 2001 -From: Muhammad Asif Manzoor -Date: Thu, 21 Mar 2024 12:50:38 -0400 -Subject: [PATCH] Add BiSheng Autotuner support for LLVM compiler - -Automatic tuning is an automatic iterative process that optimizes a given -program by manipulating compilation options for optimal performance. -BiSheng Autotuner provides a resumable interface for tuning process. BiSheng -Autotuner can tune 1) individual code segments/blocks (fine grain turning) like -loops, callsites, instructions, etc. and 2) entire modules/programs (coarse -grain tuning) for compiler flags, pass ordering, etc. -This patch enables LLVM compiler to extract tuneable code regions and then apply -suggested configuration (by Autotuner) to find out the optimal configurations. ---- - lld/ELF/Driver.cpp | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp -index c2059c70e15a..ffd0842b9078 100644 ---- a/lld/ELF/Driver.cpp -+++ b/lld/ELF/Driver.cpp -@@ -341,6 +341,18 @@ void LinkerDriver::addLibrary(StringRef name) { - // Technically this can be delayed until we read bitcode files, but - // we don't bother to do lazily because the initialization is fast. - static void initLLVM() { -+#if defined(ENABLE_AUTOTUNER) -+ // AUTO-TUNING - initialization -+ if (Error E = autotuning::Engine.init(config->outputFile.data())) { -+ error(toString(std::move(E))); -+ return; -+ } -+ if (autotuning::Engine.isEnabled() && autotuning::Engine.isParseInput() && -+ (autotuning::Engine.LLVMParams.size() || -+ autotuning::Engine.ProgramParams.size())) -+ llvm::cl::ParseAutoTunerOptions(autotuning::Engine.LLVMParams, -+ autotuning::Engine.ProgramParams); -+#endif - InitializeAllTargets(); - InitializeAllTargetMCs(); - InitializeAllAsmPrinters(); -@@ -2814,6 +2826,12 @@ void LinkerDriver::link(opt::InputArgList &args) { - reportBackrefs(); - writeArchiveStats(); - writeWhyExtract(); -+#if defined(ENABLE_AUTOTUNER) -+ // AUTO-TUNING - finalization -+ if (Error E = autotuning::Engine.finalize()) { -+ error(toString(std::move(E))); -+ } -+#endif - if (errorCount()) - return; - --- -2.33.0 - diff --git a/0007-Backport-LoongArch-add-support-for-call36-and-extreme-relocs.patch b/0007-Backport-LoongArch-add-support-for-call36-and-extreme-relocs.patch deleted file mode 100644 index 103400d6442966c1aac21b362de6bb69a3b5521f..0000000000000000000000000000000000000000 --- a/0007-Backport-LoongArch-add-support-for-call36-and-extreme-relocs.patch +++ /dev/null @@ -1,764 +0,0 @@ -From 2b870b1f213f2d645f4fa685371fbefea09b2969 Mon Sep 17 00:00:00 2001 -From: Lu Weining -Date: Mon, 25 Dec 2023 17:40:48 +0800 -Subject: [PATCH 1/6] [lld][LoongArch] Support the R_LARCH_CALL36 relocation - type (#73346) - -R_LARCH_CALL36 was designed for function call on medium code model where -the 2 instructions (pcaddu18i + jirl) must be adjacent. This is expected -to replace current medium code model implementation, i.e. -R_LARCH_PCALA_{HI20,LO12} on pcalau12i + jirl. - -See https://github.com/loongson/la-abi-specs/pull/3 for more details. - -(cherry picked from commit 88548df0fc08364bd03148c936e36f0bb07dde8a) ---- - lld/ELF/Arch/LoongArch.cpp | 20 ++++++++++ - lld/test/ELF/loongarch-call36.s | 69 +++++++++++++++++++++++++++++++++ - 2 files changed, 89 insertions(+) - create mode 100644 lld/test/ELF/loongarch-call36.s - -diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp -index 160fab4aeba9..72d9c6838e31 100644 ---- a/lld/ELF/Arch/LoongArch.cpp -+++ b/lld/ELF/Arch/LoongArch.cpp -@@ -479,6 +479,7 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, - case R_LARCH_B16: - case R_LARCH_B21: - case R_LARCH_B26: -+ case R_LARCH_CALL36: - return R_PLT_PC; - case R_LARCH_GOT_PC_HI20: - case R_LARCH_GOT64_PC_LO20: -@@ -607,6 +608,25 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, - write32le(loc, setD10k16(read32le(loc), val >> 2)); - return; - -+ case R_LARCH_CALL36: { -+ // This relocation is designed for adjancent pcaddu18i+jirl pairs that -+ // are patched in one time. Because of sign extension of these insns' -+ // immediate fields, the relocation range is [-128G - 0x20000, +128G - -+ // 0x20000) (of course must be 4-byte aligned). -+ if (((int64_t)val + 0x20000) != llvm::SignExtend64(val + 0x20000, 38)) -+ reportRangeError(loc, rel, Twine(val), llvm::minIntN(38) - 0x20000, -+ llvm::maxIntN(38) - 0x20000); -+ checkAlignment(loc, val, 4, rel); -+ // Since jirl performs sign extension on the offset immediate, adds (1<<17) -+ // to original val to get the correct hi20. -+ uint32_t hi20 = extractBits(val + (1 << 17), 37, 18); -+ // Despite the name, the lower part is actually 18 bits with 4-byte aligned. -+ uint32_t lo16 = extractBits(val, 17, 2); -+ write32le(loc, setJ20(read32le(loc), hi20)); -+ write32le(loc + 4, setK16(read32le(loc + 4), lo16)); -+ return; -+ } -+ - // Relocs intended for `addi`, `ld` or `st`. - case R_LARCH_PCALA_LO12: - // We have to again inspect the insn word to handle the R_LARCH_PCALA_LO12 -diff --git a/lld/test/ELF/loongarch-call36.s b/lld/test/ELF/loongarch-call36.s -new file mode 100644 -index 000000000000..2d25a2ac64ed ---- /dev/null -+++ b/lld/test/ELF/loongarch-call36.s -@@ -0,0 +1,69 @@ -+# REQUIRES: loongarch -+ -+# RUN: rm -rf %t && split-file %s %t -+# RUN: llvm-mc --filetype=obj --triple=loongarch64-unknown-elf %t/a.s -o %t/a.o -+ -+# RUN: ld.lld %t/a.o --section-start=.text=0x20010 --section-start=.sec.foo=0x60020 -o %t/exe1 -+# RUN: llvm-objdump --no-show-raw-insn -d %t/exe1 | FileCheck --match-full-lines %s --check-prefix=EXE1 -+## hi20 = target - pc + (1 << 17) >> 18 = 0x60020 - 0x20010 + 0x20000 >> 18 = 1 -+## lo18 = target - pc & (1 << 18) - 1 = 0x60020 - 0x20010 & 0x3ffff = 16 -+# EXE1: 20010: pcaddu18i $t0, 1 -+# EXE1-NEXT: 20014: jirl $zero, $t0, 16 -+ -+# RUN: ld.lld %t/a.o --section-start=.text=0x20010 --section-start=.sec.foo=0x40020 -o %t/exe2 -+# RUN: llvm-objdump --no-show-raw-insn -d %t/exe2 | FileCheck --match-full-lines %s --check-prefix=EXE2 -+## hi20 = target - pc + (1 << 17) >> 18 = 0x40020 - 0x20010 + 0x20000 >> 18 = 1 -+## lo18 = target - pc & (1 << 18) - 1 = 0x40020 - 0x20010 & 0x3ffff = -131056 -+# EXE2: 20010: pcaddu18i $t0, 1 -+# EXE2-NEXT: 20014: jirl $zero, $t0, -131056 -+ -+# RUN: ld.lld %t/a.o -shared -T %t/a.t -o %t/a.so -+# RUN: llvm-readelf -x .got.plt %t/a.so | FileCheck --check-prefix=GOTPLT %s -+# RUN: llvm-objdump -d --no-show-raw-insn %t/a.so | FileCheck --check-prefix=SO %s -+## PLT should be present in this case. -+# SO: Disassembly of section .plt: -+# SO: <.plt>: -+## foo@plt: -+# SO: 1234520: pcaddu12i $t3, 64{{$}} -+# SO-NEXT: ld.d $t3, $t3, 544{{$}} -+# SO-NEXT: jirl $t1, $t3, 0 -+# SO-NEXT: nop -+ -+# SO: Disassembly of section .text: -+# SO: <_start>: -+## hi20 = foo@plt - pc + (1 << 17) >> 18 = 0x1234520 - 0x1274670 + 0x20000 >> 18 = -1 -+## lo18 = foo@plt - pc & (1 << 18) - 1 = 0x1234520 - 0x1274670 & 0x3ffff = -336 -+# SO-NEXT: pcaddu18i $t0, -1{{$}} -+# SO-NEXT: jirl $zero, $t0, -336{{$}} -+ -+# GOTPLT: section '.got.plt': -+# GOTPLT-NEXT: 0x01274730 00000000 00000000 00000000 00000000 -+# GOTPLT-NEXT: 0x01274740 00452301 00000000 -+ -+# RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x2000020000 -o /dev/null 2>&1 | \ -+# RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-RANGE %s -+# ERROR-RANGE: error: [[FILE]]:(.text+0x0): relocation R_LARCH_CALL36 out of range: 137438953472 is not in [-137439084544, 137438822399]; references 'foo' -+ -+## Impossible case in reality becasue all LoongArch instructions are fixed 4-bytes long. -+# RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x40001 -o /dev/null 2>&1 | \ -+# RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-ALIGN %s -+# ERROR-ALIGN: error: [[FILE]]:(.text+0x0): improper alignment for relocation R_LARCH_CALL36: 0x20001 is not aligned to 4 bytes -+ -+#--- a.t -+SECTIONS { -+ .plt 0x1234500: { *(.plt) } -+ .text 0x1274670: { *(.text) } -+} -+ -+#--- a.s -+.text -+.global _start -+_start: -+ .reloc ., R_LARCH_CALL36, foo -+ pcaddu18i $t0, 0 -+ jirl $zero, $t0, 0 -+ -+.section .sec.foo,"ax" -+.global foo -+foo: -+ ret --- -2.20.1 - - -From 6accc3e17550f87c2e5154fdee4056e21f680542 Mon Sep 17 00:00:00 2001 -From: Weining Lu -Date: Mon, 25 Dec 2023 18:28:19 +0800 -Subject: [PATCH 2/6] [lld][test][LoongArch] Remove the test for R_LARCH_CALL36 - range checking - -Several buildbots report: -ld.lld: error: failed to open /dev/null: Cannot allocate memory - -For example: -- https://lab.llvm.org/buildbot/#/builders/184/builds/8842 -- https://lab.llvm.org/buildbot/#/builders/247/builds/12559 - -(cherry picked from commit 0fbc728dba97149e530cfb7f2ada0283c398a7ce) ---- - lld/test/ELF/loongarch-call36.s | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/lld/test/ELF/loongarch-call36.s b/lld/test/ELF/loongarch-call36.s -index 2d25a2ac64ed..0a00adacbd6a 100644 ---- a/lld/test/ELF/loongarch-call36.s -+++ b/lld/test/ELF/loongarch-call36.s -@@ -40,10 +40,6 @@ - # GOTPLT-NEXT: 0x01274730 00000000 00000000 00000000 00000000 - # GOTPLT-NEXT: 0x01274740 00452301 00000000 - --# RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x2000020000 -o /dev/null 2>&1 | \ --# RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-RANGE %s --# ERROR-RANGE: error: [[FILE]]:(.text+0x0): relocation R_LARCH_CALL36 out of range: 137438953472 is not in [-137439084544, 137438822399]; references 'foo' -- - ## Impossible case in reality becasue all LoongArch instructions are fixed 4-bytes long. - # RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x40001 -o /dev/null 2>&1 | \ - # RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-ALIGN %s --- -2.20.1 - - -From be0c0cd979b6f4e2d778ca16d96a3e465a3ac4dc Mon Sep 17 00:00:00 2001 -From: Weining Lu -Date: Mon, 25 Dec 2023 22:41:09 +0800 -Subject: [PATCH 3/6] Revert "[lld][test][LoongArch] Remove the test for - R_LARCH_CALL36 range checking" - -This reverts commit 0fbc728dba97149e530cfb7f2ada0283c398a7ce. - -In 88548df0fc08, both the .sec.foo and .tex sections used the same -section flags, hence sharing one segment, pushing the output file -size too large. This breaks on many buildbots. - -Now assign section .sec.foo different flags ("awx") from .text ("ax") -so that both sections get their own segment. - -(cherry picked from commit 6452395561eaae59e38f1df84f5413dffdb9169f) ---- - lld/test/ELF/loongarch-call36.s | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/lld/test/ELF/loongarch-call36.s b/lld/test/ELF/loongarch-call36.s -index 0a00adacbd6a..b593fdf1f604 100644 ---- a/lld/test/ELF/loongarch-call36.s -+++ b/lld/test/ELF/loongarch-call36.s -@@ -40,6 +40,10 @@ - # GOTPLT-NEXT: 0x01274730 00000000 00000000 00000000 00000000 - # GOTPLT-NEXT: 0x01274740 00452301 00000000 - -+# RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x2000020000 -o /dev/null 2>&1 | \ -+# RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-RANGE %s -+# ERROR-RANGE: error: [[FILE]]:(.text+0x0): relocation R_LARCH_CALL36 out of range: 137438953472 is not in [-137439084544, 137438822399]; references 'foo' -+ - ## Impossible case in reality becasue all LoongArch instructions are fixed 4-bytes long. - # RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x40001 -o /dev/null 2>&1 | \ - # RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-ALIGN %s -@@ -59,7 +63,7 @@ _start: - pcaddu18i $t0, 0 - jirl $zero, $t0, 0 - --.section .sec.foo,"ax" -+.section .sec.foo,"awx" - .global foo - foo: - ret --- -2.20.1 - - -From cf0d9db4664d59e163d53c62ae1de663092ab2d2 Mon Sep 17 00:00:00 2001 -From: Weining Lu -Date: Fri, 10 Nov 2023 13:37:55 +0800 -Subject: [PATCH 4/6] [lld][ELF] Add a corner testcase for - elf::getLoongArchPageDelta - -If `page(dest) - page(pc)` is 0xfffffffffff000, i.e. page(pc) is next -to page(dest), and lo12(dest) > 0x7ff, correct %pc64_lo12 and %pc64_hi12 -should be both -1 (which can be checked with binutils) but they are both -0 on lld. This patch adds such a test showing lld's incorrect behaviour -and following patch will fix this issue. - -(cherry picked from commit e752b58e0d26fc08bca6b2a4e56b05af7f8d8d66) ---- - lld/test/ELF/loongarch-pc-aligned.s | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/lld/test/ELF/loongarch-pc-aligned.s b/lld/test/ELF/loongarch-pc-aligned.s -index 9df3492d1877..f6ac56e5261d 100644 ---- a/lld/test/ELF/loongarch-pc-aligned.s -+++ b/lld/test/ELF/loongarch-pc-aligned.s -@@ -260,6 +260,19 @@ - # EXTREME15-NEXT: lu32i.d $t0, -349526 - # EXTREME15-NEXT: lu52i.d $t0, $t0, -1093 - -+## FIXME: Correct %pc64_lo20 should be 0xfffff (-1) and %pc64_hi12 should be 0xfff (-1), but current values are: -+## page delta = 0x0000000000000000, page offset = 0x888 -+## %pc_lo12 = 0x888 = -1912 -+## %pc_hi20 = 0x00000 = 0 -+## %pc64_lo20 = 0x00000 = 0 -+## %pc64_hi12 = 0x00000 = 0 -+# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x0000000012344888 --section-start=.text=0x0000000012345678 -o %t/extreme16 -+# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme16 | FileCheck %s --check-prefix=EXTREME16 -+# EXTREME16: addi.d $t0, $zero, -1912 -+# EXTREME16-NEXT: pcalau12i $t1, 0 -+# EXTREME16-NEXT: lu32i.d $t0, 0 -+# EXTREME16-NEXT: lu52i.d $t0, $t0, 0 -+ - #--- a.s - .rodata - x: --- -2.20.1 - - -From 11d61b028f306d5ace2b09154781575e88b118cb Mon Sep 17 00:00:00 2001 -From: Weining Lu -Date: Sat, 25 Nov 2023 15:44:05 +0800 -Subject: [PATCH 5/6] [lld][LoongArch] Add a another corner testcase for - elf::getLoongArchPageDelta - -Similar to e752b58e0d26. - -(cherry picked from commit 84a20989c6f72d0f7d04c9981d51c7838e95855c) ---- - lld/ELF/Arch/LoongArch.cpp | 1 - - lld/test/ELF/loongarch-pc-aligned.s | 13 +++++++++++++ - 2 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp -index 72d9c6838e31..516d02bb9e3f 100644 ---- a/lld/ELF/Arch/LoongArch.cpp -+++ b/lld/ELF/Arch/LoongArch.cpp -@@ -168,7 +168,6 @@ uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc) { - result -= 0x10000'0000; - else if (!negativeA && negativeB) - result += 0x10000'0000; -- - return result; - } - -diff --git a/lld/test/ELF/loongarch-pc-aligned.s b/lld/test/ELF/loongarch-pc-aligned.s -index f6ac56e5261d..e7950400a5c8 100644 ---- a/lld/test/ELF/loongarch-pc-aligned.s -+++ b/lld/test/ELF/loongarch-pc-aligned.s -@@ -273,6 +273,19 @@ - # EXTREME16-NEXT: lu32i.d $t0, 0 - # EXTREME16-NEXT: lu52i.d $t0, $t0, 0 - -+## FIXME: Correct %pc64_lo20 should be 0x00000 (0) and %pc64_hi12 should be 0x000 (0), but current values are: -+## page delta = 0xffffffff80000000, page offset = 0x888 -+## %pc_lo12 = 0x888 = -1912 -+## %pc_hi20 = 0x80000 = -524288 -+## %pc64_lo20 = 0xfffff = -1 -+## %pc64_hi12 = 0xfff = -1 -+# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x000071238ffff888 --section-start=.text=0x0000712310000678 -o %t/extreme17 -+# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme17 | FileCheck %s --check-prefix=EXTREME17 -+# EXTREME17: addi.d $t0, $zero, -1912 -+# EXTREME17-NEXT: pcalau12i $t1, -524288 -+# EXTREME17-NEXT: lu32i.d $t0, -1 -+# EXTREME17-NEXT: lu52i.d $t0, $t0, -1 -+ - #--- a.s - .rodata - x: --- -2.20.1 - - -From 1ea127e041629ae2df9b9cf6a85e25b6276d4a99 Mon Sep 17 00:00:00 2001 -From: Lu Weining -Date: Wed, 10 Jan 2024 18:03:52 +0800 -Subject: [PATCH 6/6] [lld][LoongArch] Handle extreme code model relocs - according to psABI v2.30 (#73387) - -psABI v2.30 requires the extreme code model instructions sequence -(pcalau12i+addi.d+lu32i.d+lu52i.d) to be adjacent. - -See https://github.com/llvm/llvm-project/pull/71907 and -https://github.com/loongson-community/discussions/issues/17 for details. - -(cherry picked from commit 38394a3d0b8b9a1fdc444bdebeba17a19250997d) ---- - lld/ELF/Arch/LoongArch.cpp | 110 +++++++--------------------- - lld/ELF/InputSection.cpp | 10 +-- - lld/ELF/Target.h | 2 +- - lld/test/ELF/loongarch-pc-aligned.s | 109 ++++++++++++++------------- - 4 files changed, 93 insertions(+), 138 deletions(-) - -diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp -index 516d02bb9e3f..19147a0f6df6 100644 ---- a/lld/ELF/Arch/LoongArch.cpp -+++ b/lld/ELF/Arch/LoongArch.cpp -@@ -85,89 +85,33 @@ static uint64_t getLoongArchPage(uint64_t p) { - static uint32_t lo12(uint32_t val) { return val & 0xfff; } - - // Calculate the adjusted page delta between dest and PC. --uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc) { -- // Consider the large code model access pattern, of which the smaller code -- // models' access patterns are a subset: -- // -- // pcalau12i U, %foo_hi20(sym) ; b in [-0x80000, 0x7ffff] -- // addi.d T, zero, %foo_lo12(sym) ; a in [-0x800, 0x7ff] -- // lu32i.d T, %foo64_lo20(sym) ; c in [-0x80000, 0x7ffff] -- // lu52i.d T, T, %foo64_hi12(sym) ; d in [-0x800, 0x7ff] -- // {ldx,stx,add}.* dest, U, T -- // -- // Let page(pc) = 0xRRR'QQQQQ'PPPPP'000 and dest = 0xZZZ'YYYYY'XXXXX'AAA, -- // with RQ, P, ZY, X and A representing the respective bitfields as unsigned -- // integers. We have: -- // -- // page(dest) = 0xZZZ'YYYYY'XXXXX'000 -- // - page(pc) = 0xRRR'QQQQQ'PPPPP'000 -- // ---------------------------------- -- // 0xddd'ccccc'bbbbb'000 -- // -- // Now consider the above pattern's actual effects: -- // -- // page(pc) 0xRRR'QQQQQ'PPPPP'000 -- // pcalau12i + 0xiii'iiiii'bbbbb'000 -- // addi + 0xjjj'jjjjj'kkkkk'AAA -- // lu32i.d & lu52i.d + 0xddd'ccccc'00000'000 -- // -------------------------------------------------- -- // dest = U + T -- // = ((RQ<<32) + (P<<12) + i + (b<<12)) + (j + k + A + (cd<<32)) -- // = (((RQ+cd)<<32) + i + j) + (((P+b)<<12) + k) + A -- // = (ZY<<32) + (X<<12) + A -- // -- // ZY<<32 = (RQ<<32)+(cd<<32)+i+j, X<<12 = (P<<12)+(b<<12)+k -- // cd<<32 = (ZY<<32)-(RQ<<32)-i-j, b<<12 = (X<<12)-(P<<12)-k -- // -- // where i and k are terms representing the effect of b's and A's sign -- // extension respectively. -- // -- // i = signed b < 0 ? -0x10000'0000 : 0 -- // k = signed A < 0 ? -0x1000 : 0 -- // -- // The j term is a bit complex: it represents the higher half of -- // sign-extended bits from A that are effectively lost if i == 0 but k != 0, -- // due to overwriting by lu32i.d & lu52i.d. -- // -- // j = signed A < 0 && signed b >= 0 ? 0x10000'0000 : 0 -- // -- // The actual effect of the instruction sequence before the final addition, -- // i.e. our desired result value, is thus: -- // -- // result = (cd<<32) + (b<<12) -- // = (ZY<<32)-(RQ<<32)-i-j + (X<<12)-(P<<12)-k -- // = ((ZY<<32)+(X<<12)) - ((RQ<<32)+(P<<12)) - i - j - k -- // = page(dest) - page(pc) - i - j - k -- // -- // when signed A >= 0 && signed b >= 0: -- // -- // i = j = k = 0 -- // result = page(dest) - page(pc) -- // -- // when signed A >= 0 && signed b < 0: -- // -- // i = -0x10000'0000, j = k = 0 -- // result = page(dest) - page(pc) + 0x10000'0000 -- // -- // when signed A < 0 && signed b >= 0: -- // -- // i = 0, j = 0x10000'0000, k = -0x1000 -- // result = page(dest) - page(pc) - 0x10000'0000 + 0x1000 -- // -- // when signed A < 0 && signed b < 0: -- // -- // i = -0x10000'0000, j = 0, k = -0x1000 -- // result = page(dest) - page(pc) + 0x1000 -- uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pc); -- bool negativeA = lo12(dest) > 0x7ff; -- bool negativeB = (result & 0x8000'0000) != 0; -- -- if (negativeA) -- result += 0x1000; -- if (negativeA && !negativeB) -- result -= 0x10000'0000; -- else if (!negativeA && negativeB) -- result += 0x10000'0000; -+uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type) { -+ // Note that if the sequence being relocated is `pcalau12i + addi.d + lu32i.d -+ // + lu52i.d`, they must be adjancent so that we can infer the PC of -+ // `pcalau12i` when calculating the page delta for the other two instructions -+ // (lu32i.d and lu52i.d). Compensate all the sign-extensions is a bit -+ // complicated. Just use psABI recommended algorithm. -+ uint64_t pcalau12i_pc; -+ switch (type) { -+ case R_LARCH_PCALA64_LO20: -+ case R_LARCH_GOT64_PC_LO20: -+ case R_LARCH_TLS_IE64_PC_LO20: -+ pcalau12i_pc = pc - 8; -+ break; -+ case R_LARCH_PCALA64_HI12: -+ case R_LARCH_GOT64_PC_HI12: -+ case R_LARCH_TLS_IE64_PC_HI12: -+ pcalau12i_pc = pc - 12; -+ break; -+ default: -+ pcalau12i_pc = pc; -+ break; -+ } -+ uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pcalau12i_pc); -+ if (dest & 0x800) -+ result += 0x1000 - 0x1'0000'0000; -+ if (result & 0x8000'0000) -+ result += 0x1'0000'0000; - return result; - } - -diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp -index b178d82407e3..44444b62251d 100644 ---- a/lld/ELF/InputSection.cpp -+++ b/lld/ELF/InputSection.cpp -@@ -712,8 +712,8 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, - return sym.getGotVA() + a - p; - case R_LOONGARCH_GOT_PAGE_PC: - if (sym.hasFlag(NEEDS_TLSGD)) -- return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p); -- return getLoongArchPageDelta(sym.getGotVA() + a, p); -+ return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p, type); -+ return getLoongArchPageDelta(sym.getGotVA() + a, p, type); - case R_MIPS_GOTREL: - return sym.getVA(a) - in.mipsGot->getGp(file); - case R_MIPS_GOT_GP: -@@ -763,7 +763,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, - return 0; - } - case R_LOONGARCH_PAGE_PC: -- return getLoongArchPageDelta(sym.getVA(a), p); -+ return getLoongArchPageDelta(sym.getVA(a), p, type); - case R_PC: - case R_ARM_PCA: { - uint64_t dest; -@@ -798,7 +798,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, - case R_PPC64_CALL_PLT: - return sym.getPltVA() + a - p; - case R_LOONGARCH_PLT_PAGE_PC: -- return getLoongArchPageDelta(sym.getPltVA() + a, p); -+ return getLoongArchPageDelta(sym.getPltVA() + a, p, type); - case R_PLT_GOTPLT: - return sym.getPltVA() + a - in.gotPlt->getVA(); - case R_PPC32_PLTREL: -@@ -860,7 +860,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, - case R_TLSGD_PC: - return in.got->getGlobalDynAddr(sym) + a - p; - case R_LOONGARCH_TLSGD_PAGE_PC: -- return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p); -+ return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p, type); - case R_TLSLD_GOTPLT: - return in.got->getVA() + in.got->getTlsIndexOff() + a - in.gotPlt->getVA(); - case R_TLSLD_GOT: -diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h -index bf831afa1793..aeabe47f92a1 100644 ---- a/lld/ELF/Target.h -+++ b/lld/ELF/Target.h -@@ -229,7 +229,7 @@ void addPPC64SaveRestore(); - uint64_t getPPC64TocBase(); - uint64_t getAArch64Page(uint64_t expr); - template void writeARMCmseImportLib(); --uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc); -+uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type); - void riscvFinalizeRelax(int passes); - void mergeRISCVAttributesSections(); - void addArmInputSectionMappingSymbols(); -diff --git a/lld/test/ELF/loongarch-pc-aligned.s b/lld/test/ELF/loongarch-pc-aligned.s -index e7950400a5c8..0405961e5f74 100644 ---- a/lld/test/ELF/loongarch-pc-aligned.s -+++ b/lld/test/ELF/loongarch-pc-aligned.s -@@ -75,8 +75,8 @@ - ## %pc64_hi12 = 0x444 = 1092 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x4443333334567111 --section-start=.text=0x0000000012345678 -o %t/extreme0 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme0 | FileCheck %s --check-prefix=EXTREME0 --# EXTREME0: addi.d $t0, $zero, 273 --# EXTREME0-NEXT: pcalau12i $t1, 139810 -+# EXTREME0: pcalau12i $t1, 139810 -+# EXTREME0-NEXT: addi.d $t0, $zero, 273 - # EXTREME0-NEXT: lu32i.d $t0, 209715 - # EXTREME0-NEXT: lu52i.d $t0, $t0, 1092 - -@@ -87,8 +87,8 @@ - ## %pc64_hi12 = 0x444 = 1092 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x4443333334567888 --section-start=.text=0x0000000012345678 -o %t/extreme1 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme1 | FileCheck %s --check-prefix=EXTREME1 --# EXTREME1: addi.d $t0, $zero, -1912 --# EXTREME1-NEXT: pcalau12i $t1, 139811 -+# EXTREME1: pcalau12i $t1, 139811 -+# EXTREME1-NEXT: addi.d $t0, $zero, -1912 - # EXTREME1-NEXT: lu32i.d $t0, 209714 - # EXTREME1-NEXT: lu52i.d $t0, $t0, 1092 - -@@ -99,8 +99,8 @@ - ## %pc64_hi12 = 0x444 = 1092 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x44433333abcde111 --section-start=.text=0x0000000012345678 -o %t/extreme2 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme2 | FileCheck %s --check-prefix=EXTREME2 --# EXTREME2: addi.d $t0, $zero, 273 --# EXTREME2-NEXT: pcalau12i $t1, -419431 -+# EXTREME2: pcalau12i $t1, -419431 -+# EXTREME2-NEXT: addi.d $t0, $zero, 273 - # EXTREME2-NEXT: lu32i.d $t0, 209716 - # EXTREME2-NEXT: lu52i.d $t0, $t0, 1092 - -@@ -111,8 +111,8 @@ - ## %pc64_hi12 = 0x444 = 1092 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x44433333abcde888 --section-start=.text=0x0000000012345678 -o %t/extreme3 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme3 | FileCheck %s --check-prefix=EXTREME3 --# EXTREME3: addi.d $t0, $zero, -1912 --# EXTREME3-NEXT: pcalau12i $t1, -419430 -+# EXTREME3: pcalau12i $t1, -419430 -+# EXTREME3-NEXT: addi.d $t0, $zero, -1912 - # EXTREME3-NEXT: lu32i.d $t0, 209715 - # EXTREME3-NEXT: lu52i.d $t0, $t0, 1092 - -@@ -123,8 +123,8 @@ - ## %pc64_hi12 = 0x444 = 1092 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaa34567111 --section-start=.text=0x0000000012345678 -o %t/extreme4 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme4 | FileCheck %s --check-prefix=EXTREME4 --# EXTREME4: addi.d $t0, $zero, 273 --# EXTREME4-NEXT: pcalau12i $t1, 139810 -+# EXTREME4: pcalau12i $t1, 139810 -+# EXTREME4-NEXT: addi.d $t0, $zero, 273 - # EXTREME4-NEXT: lu32i.d $t0, -349526 - # EXTREME4-NEXT: lu52i.d $t0, $t0, 1092 - -@@ -135,8 +135,8 @@ - ## %pc64_hi12 = 0x444 = 1092 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaa34567888 --section-start=.text=0x0000000012345678 -o %t/extreme5 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme5 | FileCheck %s --check-prefix=EXTREME5 --# EXTREME5: addi.d $t0, $zero, -1912 --# EXTREME5-NEXT: pcalau12i $t1, 139811 -+# EXTREME5: pcalau12i $t1, 139811 -+# EXTREME5-NEXT: addi.d $t0, $zero, -1912 - # EXTREME5-NEXT: lu32i.d $t0, -349527 - # EXTREME5-NEXT: lu52i.d $t0, $t0, 1092 - -@@ -147,8 +147,8 @@ - ## %pc64_hi12 = 0x444 = 1092 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaaabcde111 --section-start=.text=0x0000000012345678 -o %t/extreme6 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme6 | FileCheck %s --check-prefix=EXTREME6 --# EXTREME6: addi.d $t0, $zero, 273 --# EXTREME6-NEXT: pcalau12i $t1, -419431 -+# EXTREME6: pcalau12i $t1, -419431 -+# EXTREME6-NEXT: addi.d $t0, $zero, 273 - # EXTREME6-NEXT: lu32i.d $t0, -349525 - # EXTREME6-NEXT: lu52i.d $t0, $t0, 1092 - -@@ -159,8 +159,8 @@ - ## %pc64_hi12 = 0x444 = 1092 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaaabcde888 --section-start=.text=0x0000000012345678 -o %t/extreme7 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme7 | FileCheck %s --check-prefix=EXTREME7 --# EXTREME7: addi.d $t0, $zero, -1912 --# EXTREME7-NEXT: pcalau12i $t1, -419430 -+# EXTREME7: pcalau12i $t1, -419430 -+# EXTREME7-NEXT: addi.d $t0, $zero, -1912 - # EXTREME7-NEXT: lu32i.d $t0, -349526 - # EXTREME7-NEXT: lu52i.d $t0, $t0, 1092 - -@@ -171,8 +171,8 @@ - ## %pc64_hi12 = 0xbbb = -1093 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb3333334567111 --section-start=.text=0x0000000012345678 -o %t/extreme8 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme8 | FileCheck %s --check-prefix=EXTREME8 --# EXTREME8: addi.d $t0, $zero, 273 --# EXTREME8-NEXT: pcalau12i $t1, 139810 -+# EXTREME8: pcalau12i $t1, 139810 -+# EXTREME8-NEXT: addi.d $t0, $zero, 273 - # EXTREME8-NEXT: lu32i.d $t0, 209715 - # EXTREME8-NEXT: lu52i.d $t0, $t0, -1093 - -@@ -183,8 +183,8 @@ - ## %pc64_hi12 = 0xbbb = -1093 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb3333334567888 --section-start=.text=0x0000000012345678 -o %t/extreme9 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme9 | FileCheck %s --check-prefix=EXTREME9 --# EXTREME9: addi.d $t0, $zero, -1912 --# EXTREME9-NEXT: pcalau12i $t1, 139811 -+# EXTREME9: pcalau12i $t1, 139811 -+# EXTREME9-NEXT: addi.d $t0, $zero, -1912 - # EXTREME9-NEXT: lu32i.d $t0, 209714 - # EXTREME9-NEXT: lu52i.d $t0, $t0, -1093 - -@@ -195,8 +195,8 @@ - ## %pc64_hi12 = 0xbbb = -1093 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb33333abcde111 --section-start=.text=0x0000000012345678 -o %t/extreme10 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme10 | FileCheck %s --check-prefix=EXTREME10 --# EXTREME10: addi.d $t0, $zero, 273 --# EXTREME10-NEXT: pcalau12i $t1, -419431 -+# EXTREME10: pcalau12i $t1, -419431 -+# EXTREME10-NEXT: addi.d $t0, $zero, 273 - # EXTREME10-NEXT: lu32i.d $t0, 209716 - # EXTREME10-NEXT: lu52i.d $t0, $t0, -1093 - -@@ -207,8 +207,8 @@ - ## %pc64_hi12 = 0xbbb = -1093 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb33333abcde888 --section-start=.text=0x0000000012345678 -o %t/extreme11 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme11 | FileCheck %s --check-prefix=EXTREME11 --# EXTREME11: addi.d $t0, $zero, -1912 --# EXTREME11-NEXT: pcalau12i $t1, -419430 -+# EXTREME11: pcalau12i $t1, -419430 -+# EXTREME11-NEXT: addi.d $t0, $zero, -1912 - # EXTREME11-NEXT: lu32i.d $t0, 209715 - # EXTREME11-NEXT: lu52i.d $t0, $t0, -1093 - -@@ -219,8 +219,8 @@ - ## %pc64_hi12 = 0xbbb = -1093 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaa34567111 --section-start=.text=0x0000000012345678 -o %t/extreme12 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme12 | FileCheck %s --check-prefix=EXTREME12 --# EXTREME12: addi.d $t0, $zero, 273 --# EXTREME12-NEXT: pcalau12i $t1, 139810 -+# EXTREME12: pcalau12i $t1, 139810 -+# EXTREME12-NEXT: addi.d $t0, $zero, 273 - # EXTREME12-NEXT: lu32i.d $t0, -349526 - # EXTREME12-NEXT: lu52i.d $t0, $t0, -1093 - -@@ -231,8 +231,8 @@ - ## %pc64_hi12 = 0xbbb = -1093 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaa34567888 --section-start=.text=0x0000000012345678 -o %t/extreme13 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme13 | FileCheck %s --check-prefix=EXTREME13 --# EXTREME13: addi.d $t0, $zero, -1912 --# EXTREME13-NEXT: pcalau12i $t1, 139811 -+# EXTREME13: pcalau12i $t1, 139811 -+# EXTREME13-NEXT: addi.d $t0, $zero, -1912 - # EXTREME13-NEXT: lu32i.d $t0, -349527 - # EXTREME13-NEXT: lu52i.d $t0, $t0, -1093 - -@@ -243,8 +243,8 @@ - ## %pc64_hi12 = 0xbbb = -1093 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaaabcde111 --section-start=.text=0x0000000012345678 -o %t/extreme14 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme14 | FileCheck %s --check-prefix=EXTREME14 --# EXTREME14: addi.d $t0, $zero, 273 --# EXTREME14-NEXT: pcalau12i $t1, -419431 -+# EXTREME14: pcalau12i $t1, -419431 -+# EXTREME14-NEXT: addi.d $t0, $zero, 273 - # EXTREME14-NEXT: lu32i.d $t0, -349525 - # EXTREME14-NEXT: lu52i.d $t0, $t0, -1093 - -@@ -255,36 +255,47 @@ - ## %pc64_hi12 = 0xbbb = -1093 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaaabcde888 --section-start=.text=0x0000000012345678 -o %t/extreme15 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme15 | FileCheck %s --check-prefix=EXTREME15 --# EXTREME15: addi.d $t0, $zero, -1912 --# EXTREME15-NEXT: pcalau12i $t1, -419430 -+# EXTREME15: pcalau12i $t1, -419430 -+# EXTREME15-NEXT: addi.d $t0, $zero, -1912 - # EXTREME15-NEXT: lu32i.d $t0, -349526 - # EXTREME15-NEXT: lu52i.d $t0, $t0, -1093 - --## FIXME: Correct %pc64_lo20 should be 0xfffff (-1) and %pc64_hi12 should be 0xfff (-1), but current values are: --## page delta = 0x0000000000000000, page offset = 0x888 -+## page delta = 0xffffffff00000000, page offset = 0x888 - ## %pc_lo12 = 0x888 = -1912 - ## %pc_hi20 = 0x00000 = 0 --## %pc64_lo20 = 0x00000 = 0 --## %pc64_hi12 = 0x00000 = 0 -+## %pc64_lo20 = 0xfffff = -1 -+## %pc64_hi12 = 0xfff = -1 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x0000000012344888 --section-start=.text=0x0000000012345678 -o %t/extreme16 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme16 | FileCheck %s --check-prefix=EXTREME16 --# EXTREME16: addi.d $t0, $zero, -1912 --# EXTREME16-NEXT: pcalau12i $t1, 0 --# EXTREME16-NEXT: lu32i.d $t0, 0 --# EXTREME16-NEXT: lu52i.d $t0, $t0, 0 -+# EXTREME16: pcalau12i $t1, 0 -+# EXTREME16-NEXT: addi.d $t0, $zero, -1912 -+# EXTREME16-NEXT: lu32i.d $t0, -1 -+# EXTREME16-NEXT: lu52i.d $t0, $t0, -1 - --## FIXME: Correct %pc64_lo20 should be 0x00000 (0) and %pc64_hi12 should be 0x000 (0), but current values are: --## page delta = 0xffffffff80000000, page offset = 0x888 -+## page delta = 0x0000000080000000, page offset = 0x888 - ## %pc_lo12 = 0x888 = -1912 - ## %pc_hi20 = 0x80000 = -524288 --## %pc64_lo20 = 0xfffff = -1 --## %pc64_hi12 = 0xfff = -1 -+## %pc64_lo20 = 0xfffff = 0 -+## %pc64_hi12 = 0xfff = 0 - # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x000071238ffff888 --section-start=.text=0x0000712310000678 -o %t/extreme17 - # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme17 | FileCheck %s --check-prefix=EXTREME17 --# EXTREME17: addi.d $t0, $zero, -1912 --# EXTREME17-NEXT: pcalau12i $t1, -524288 --# EXTREME17-NEXT: lu32i.d $t0, -1 --# EXTREME17-NEXT: lu52i.d $t0, $t0, -1 -+# EXTREME17: pcalau12i $t1, -524288 -+# EXTREME17-NEXT: addi.d $t0, $zero, -1912 -+# EXTREME17-NEXT: lu32i.d $t0, 0 -+# EXTREME17-NEXT: lu52i.d $t0, $t0, 0 -+ -+## A case that pcalau12i, lu32i.d and lu52i.d are in different pages. -+## page delta = 0x0000000080000000, page offset = 0x123 -+## %pc_lo12 = 0x111 = 273 -+## %pc_hi20 = 0x80000 = -524288 -+## %pc64_lo20 = 0x00001 = 1 -+## %pc64_hi12 = 0x000 = 0 -+# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x80000111 --section-start=.text=0xff8 -o %t/extreme18 -+# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme18 | FileCheck %s --check-prefix=EXTREME18 -+# EXTREME18: pcalau12i $t1, -524288 -+# EXTREME18-NEXT: addi.d $t0, $zero, 273 -+# EXTREME18-NEXT: lu32i.d $t0, 1 -+# EXTREME18-NEXT: lu52i.d $t0, $t0, 0 - - #--- a.s - .rodata -@@ -303,7 +314,7 @@ x: - .text - .global _start - _start: -- addi.d $t0, $zero, %pc_lo12(x) - pcalau12i $t1, %pc_hi20(x) -+ addi.d $t0, $zero, %pc_lo12(x) - lu32i.d $t0, %pc64_lo20(x) - lu52i.d $t0, $t0, %pc64_hi12(x) --- -2.20.1 - diff --git a/README.en.md b/README.en.md index 8e8b6d8504da8794747d3f67549f6811e2a43075..01bb97bf24c6aa97808214954a0bf19ff3460343 100644 --- a/README.en.md +++ b/README.en.md @@ -1,8 +1,22 @@ -# lld +# lld-latest #### Description -This package contains library and header files needed to develop new native -programs that use the LLD infrastructure. +LLVM Linker + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx #### Contribution @@ -19,4 +33,4 @@ programs that use the LLD infrastructure. 3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) 4. The most valuable open source project [GVP](https://gitee.com/gvp) 5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) \ No newline at end of file +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index fa118f6f94452db788258fb20733f1b4b6d7952b..afa4af064da5c33f78a51d5425d5028f519bb731 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,23 @@ -# lld +# lld-latest #### 介绍 -This package contains library and header files needed to develop new native -programs that use the LLD infrastructure. +LLVM Linker + +#### 软件架构 +软件架构说明 + + +#### 安装教程 + +1. xxxx +2. xxxx +3. xxxx + +#### 使用说明 + +1. xxxx +2. xxxx +3. xxxx #### 参与贡献 @@ -19,4 +34,4 @@ programs that use the LLD infrastructure. 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) \ No newline at end of file +6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/lld-17.0.6.src.tar.xz b/lld-17.0.6.src.tar.xz deleted file mode 100644 index 6649129bf50b6b2ad2bce9f57598779aa7c55ab8..0000000000000000000000000000000000000000 Binary files a/lld-17.0.6.src.tar.xz and /dev/null differ diff --git a/lld-18.1.8.src.tar.xz b/lld-18.1.8.src.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..39634bf89a753994bebafa75a5a9c102f4f88a44 Binary files /dev/null and b/lld-18.1.8.src.tar.xz differ diff --git a/lld.spec b/lld.spec index f18d03d5e2b9d674b9045e32e8600519c2731469..d331ff55a5be7265bbcd5b1f2cecbc2f8c523cdc 100644 --- a/lld.spec +++ b/lld.spec @@ -1,27 +1,20 @@ -%undefine __cmake_in_source_build - -%bcond_without sys_llvm %bcond_without check -%bcond_with toolchain_clang -%bcond_without bisheng_autotuner +%bcond_without toolchain_clang %if %{with toolchain_clang} %global toolchain clang %endif -%global maj_ver 17 -%global min_ver 0 -%global patch_ver 6 +%global maj_ver 18 +%global min_ver 1 +%global patch_ver 8 -%if %{with sys_llvm} -%global pkg_name lld -%global install_prefix %{_prefix} -%global install_datadir %{_datadir} -%else -%global pkg_name lld%{maj_ver} -%global install_prefix %{_libdir}/llvm%{maj_ver} -%global install_datadir %{install_prefix}/share -%endif +%global _scl_prefix /opt/openEuler +%{?scl:%scl_package %scl} +%{!?scl:%global scl_prefix llvm-toolset-%{maj_ver}-} +%{!?scl:%global pkg_name %{name}} +%global install_prefix %{!?scl:%{_scl_prefix}/llvm-toolset-%{maj_ver}/root}%{_prefix} +%global install_datadir %{!?scl:%{_scl_prefix}/llvm-toolset-%{maj_ver}/root}%{_datadir} %global install_bindir %{install_prefix}/bin %if 0%{?__isa_bits} == 64 @@ -38,9 +31,9 @@ # Disable LTO as this causes crash if gcc lto enabled. %define _lto_cflags %{nil} -Name: %{pkg_name} +Name: %{?scl_prefix}lld Version: %{maj_ver}.%{min_ver}.%{patch_ver} -Release: 8 +Release: 1 Summary: The LLVM Linker License: NCSA @@ -48,26 +41,13 @@ URL: http://llvm.org Source0: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{version}/lld-%{version}.src.tar.xz Patch1: fedora-PATCH-lld-Import-compact_unwind_encoding.h-from-libu.patch -Patch2: 0002-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-6-relocation-type.patch -Patch3: 0003-Backport-ELF-RISCV-Implement-emit-relocs-with-relaxation.patch -Patch4: 0004-Backport-lld-ELF-Support-relax-R_LARCH_ALIGN.patch -Patch5: 0005-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-_ULEB128-relocation-types.patch -Patch6: 0006-Add-BiSheng-Autotuner-support-for-LLVM-compiler.patch -Patch7: 0007-Backport-LoongArch-add-support-for-call36-and-extreme-relocs.patch BuildRequires: clang BuildRequires: cmake -%if %{with sys_llvm} -BuildRequires: llvm-devel = %{version} -BuildRequires: llvm-googletest = %{version} -BuildRequires: llvm-test = %{version} -BuildRequires: llvm-cmake-utils = %{version} -%else -BuildRequires: llvm%{maj_ver}-devel = %{version} -BuildRequires: llvm%{maj_ver}-googletest = %{version} -BuildRequires: llvm%{maj_ver}-test = %{version} -BuildRequires: llvm%{maj_ver}-cmake-utils = %{version} -%endif +BuildRequires: %{?scl_prefix}llvm-devel = %{version} +BuildRequires: %{?scl_prefix}llvm-googletest = %{version} +BuildRequires: %{?scl_prefix}llvm-test = %{version} +BuildRequires: %{?scl_prefix}llvm-cmake-utils = %{version} BuildRequires: ncurses-devel BuildRequires: ninja-build BuildRequires: python3-rpm-macros @@ -77,14 +57,14 @@ BuildRequires: zlib-devel Requires(post): %{_sbindir}/update-alternatives Requires(preun): %{_sbindir}/update-alternatives -Requires: %{name}-libs = %{version}-%{release} +Requires: %{pkg_name}-libs = %{version}-%{release} %description The LLVM project linker. %package devel Summary: Libraries and header files for LLD -Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{pkg_name}-libs%{?_isa} = %{version}-%{release} %description devel This package contains library and header files needed to develop new native @@ -100,7 +80,9 @@ Shared libraries for LLD. %autosetup -n lld-%{version}.src -p2 %build -%cmake -G Ninja \ +mkdir -p _build +cd _build +%cmake .. -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=%{install_prefix} \ -DLLVM_LINK_LLVM_DYLIB:BOOL=ON \ @@ -115,22 +97,19 @@ Shared libraries for LLD. %if "%{toolchain}" == "clang" -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -%endif -%if %{with bisheng_autotuner} - -DENABLE_AUTOTUNER=ON \ %endif -DLLVM_MAIN_SRC_DIR=%{install_prefix}/src -%cmake_build +%ninja_build %install -%cmake_install +%ninja_install -C _build rm %{buildroot}%{install_includedir}/mach-o/compact_unwind_encoding.h %check %if %{with check} -%cmake_build --target check-lld +%ninja_build check-lld -C _build %endif %files @@ -146,6 +125,9 @@ rm %{buildroot}%{install_includedir}/mach-o/compact_unwind_encoding.h %{install_libdir}/liblld*.so.* %changelog +* Fri Dec 6 2024 liyunfei - 18.1.8-1 +- init for Multi-Version LLVM-18.1.8 + * Tue Nov 12 2024 Funda Wang - 17.0.6-8 - fix check section diff --git a/lld.yaml b/lld.yaml deleted file mode 100644 index c7c50f6ac87dd806f0574c6b3a4fd97b11d3e479..0000000000000000000000000000000000000000 --- a/lld.yaml +++ /dev/null @@ -1,4 +0,0 @@ -version_control: github -src_repo: llvm/llvm-project -tag_prefix: ^llvmorg- -separator: .