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..6c73bfcc58ffc1fd762aede1f799633612ead1af 100644 --- a/README.en.md +++ b/README.en.md @@ -1,22 +1,3 @@ # lld -#### Description -This package contains library and header files needed to develop new native -programs that use the LLD infrastructure. - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -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 +This package has been merged into [src-openeuler/llvm](https://gitee.com/src-openeuler/llvm) \ No newline at end of file diff --git a/README.md b/README.md index fa118f6f94452db788258fb20733f1b4b6d7952b..97ee4a46f661b758db78cc44ad2c342d747bf55f 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,3 @@ # lld -#### 介绍 -This package contains library and header files needed to develop new native -programs that use the LLD infrastructure. - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -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 +该软件包已合并入[src-openeuler/llvm](https://gitee.com/src-openeuler/llvm) \ No newline at end of file diff --git a/fedora-PATCH-lld-Import-compact_unwind_encoding.h-from-libu.patch b/fedora-PATCH-lld-Import-compact_unwind_encoding.h-from-libu.patch deleted file mode 100644 index a37f8c3a03da37688d009ea9c6ff3d1ece9de6e5..0000000000000000000000000000000000000000 --- a/fedora-PATCH-lld-Import-compact_unwind_encoding.h-from-libu.patch +++ /dev/null @@ -1,500 +0,0 @@ -From 43dfe54ce017c8d37eaec480a2f13a492bbc4203 Mon Sep 17 00:00:00 2001 -From: serge-sans-paille -Date: Thu, 25 Feb 2021 14:24:14 +0100 -Subject: [PATCH 2/2] [PATCH][lld] Import compact_unwind_encoding.h from - libunwind - -This avoids an implicit cross package dependency - -Signed-off-by: Chenxi Mao ---- - lld/include/mach-o/compact_unwind_encoding.h | 477 +++++++++++++++++++++++++++ - 1 file changed, 477 insertions(+) - create mode 100644 lld/include/mach-o/compact_unwind_encoding.h - -diff --git a/lld/include/mach-o/compact_unwind_encoding.h b/lld/include/mach-o/compact_unwind_encoding.h -new file mode 100644 -index 0000000..5301b10 ---- /dev/null -+++ b/lld/include/mach-o/compact_unwind_encoding.h -@@ -0,0 +1,477 @@ -+//===------------------ mach-o/compact_unwind_encoding.h ------------------===// -+// -+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -+// See https://llvm.org/LICENSE.txt for license information. -+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -+// -+// -+// Darwin's alternative to DWARF based unwind encodings. -+// -+//===----------------------------------------------------------------------===// -+ -+ -+#ifndef __COMPACT_UNWIND_ENCODING__ -+#define __COMPACT_UNWIND_ENCODING__ -+ -+#include -+ -+// -+// Compilers can emit standard DWARF FDEs in the __TEXT,__eh_frame section -+// of object files. Or compilers can emit compact unwind information in -+// the __LD,__compact_unwind section. -+// -+// When the linker creates a final linked image, it will create a -+// __TEXT,__unwind_info section. This section is a small and fast way for the -+// runtime to access unwind info for any given function. If the compiler -+// emitted compact unwind info for the function, that compact unwind info will -+// be encoded in the __TEXT,__unwind_info section. If the compiler emitted -+// DWARF unwind info, the __TEXT,__unwind_info section will contain the offset -+// of the FDE in the __TEXT,__eh_frame section in the final linked image. -+// -+// Note: Previously, the linker would transform some DWARF unwind infos into -+// compact unwind info. But that is fragile and no longer done. -+ -+ -+// -+// The compact unwind endoding is a 32-bit value which encoded in an -+// architecture specific way, which registers to restore from where, and how -+// to unwind out of the function. -+// -+typedef uint32_t compact_unwind_encoding_t; -+ -+ -+// architecture independent bits -+enum { -+ UNWIND_IS_NOT_FUNCTION_START = 0x80000000, -+ UNWIND_HAS_LSDA = 0x40000000, -+ UNWIND_PERSONALITY_MASK = 0x30000000, -+}; -+ -+ -+ -+ -+// -+// x86 -+// -+// 1-bit: start -+// 1-bit: has lsda -+// 2-bit: personality index -+// -+// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=DWARF -+// ebp based: -+// 15-bits (5*3-bits per reg) register permutation -+// 8-bits for stack offset -+// frameless: -+// 8-bits stack size -+// 3-bits stack adjust -+// 3-bits register count -+// 10-bits register permutation -+// -+enum { -+ UNWIND_X86_MODE_MASK = 0x0F000000, -+ UNWIND_X86_MODE_EBP_FRAME = 0x01000000, -+ UNWIND_X86_MODE_STACK_IMMD = 0x02000000, -+ UNWIND_X86_MODE_STACK_IND = 0x03000000, -+ UNWIND_X86_MODE_DWARF = 0x04000000, -+ -+ UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF, -+ UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000, -+ -+ UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000, -+ UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000, -+ UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00, -+ UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, -+ -+ UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF, -+}; -+ -+enum { -+ UNWIND_X86_REG_NONE = 0, -+ UNWIND_X86_REG_EBX = 1, -+ UNWIND_X86_REG_ECX = 2, -+ UNWIND_X86_REG_EDX = 3, -+ UNWIND_X86_REG_EDI = 4, -+ UNWIND_X86_REG_ESI = 5, -+ UNWIND_X86_REG_EBP = 6, -+}; -+ -+// -+// For x86 there are four modes for the compact unwind encoding: -+// UNWIND_X86_MODE_EBP_FRAME: -+// EBP based frame where EBP is push on stack immediately after return address, -+// then ESP is moved to EBP. Thus, to unwind ESP is restored with the current -+// EPB value, then EBP is restored by popping off the stack, and the return -+// is done by popping the stack once more into the pc. -+// All non-volatile registers that need to be restored must have been saved -+// in a small range in the stack that starts EBP-4 to EBP-1020. The offset/4 -+// is encoded in the UNWIND_X86_EBP_FRAME_OFFSET bits. The registers saved -+// are encoded in the UNWIND_X86_EBP_FRAME_REGISTERS bits as five 3-bit entries. -+// Each entry contains which register to restore. -+// UNWIND_X86_MODE_STACK_IMMD: -+// A "frameless" (EBP not used as frame pointer) function with a small -+// constant stack size. To return, a constant (encoded in the compact -+// unwind encoding) is added to the ESP. Then the return is done by -+// popping the stack into the pc. -+// All non-volatile registers that need to be restored must have been saved -+// on the stack immediately after the return address. The stack_size/4 is -+// encoded in the UNWIND_X86_FRAMELESS_STACK_SIZE (max stack size is 1024). -+// The number of registers saved is encoded in UNWIND_X86_FRAMELESS_STACK_REG_COUNT. -+// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION constains which registers were -+// saved and their order. -+// UNWIND_X86_MODE_STACK_IND: -+// A "frameless" (EBP not used as frame pointer) function large constant -+// stack size. This case is like the previous, except the stack size is too -+// large to encode in the compact unwind encoding. Instead it requires that -+// the function contains "subl $nnnnnnnn,ESP" in its prolog. The compact -+// encoding contains the offset to the nnnnnnnn value in the function in -+// UNWIND_X86_FRAMELESS_STACK_SIZE. -+// UNWIND_X86_MODE_DWARF: -+// No compact unwind encoding is available. Instead the low 24-bits of the -+// compact encoding is the offset of the DWARF FDE in the __eh_frame section. -+// This mode is never used in object files. It is only generated by the -+// linker in final linked images which have only DWARF unwind info for a -+// function. -+// -+// The permutation encoding is a Lehmer code sequence encoded into a -+// single variable-base number so we can encode the ordering of up to -+// six registers in a 10-bit space. -+// -+// The following is the algorithm used to create the permutation encoding used -+// with frameless stacks. It is passed the number of registers to be saved and -+// an array of the register numbers saved. -+// -+//uint32_t permute_encode(uint32_t registerCount, const uint32_t registers[6]) -+//{ -+// uint32_t renumregs[6]; -+// for (int i=6-registerCount; i < 6; ++i) { -+// int countless = 0; -+// for (int j=6-registerCount; j < i; ++j) { -+// if ( registers[j] < registers[i] ) -+// ++countless; -+// } -+// renumregs[i] = registers[i] - countless -1; -+// } -+// uint32_t permutationEncoding = 0; -+// switch ( registerCount ) { -+// case 6: -+// permutationEncoding |= (120*renumregs[0] + 24*renumregs[1] -+// + 6*renumregs[2] + 2*renumregs[3] -+// + renumregs[4]); -+// break; -+// case 5: -+// permutationEncoding |= (120*renumregs[1] + 24*renumregs[2] -+// + 6*renumregs[3] + 2*renumregs[4] -+// + renumregs[5]); -+// break; -+// case 4: -+// permutationEncoding |= (60*renumregs[2] + 12*renumregs[3] -+// + 3*renumregs[4] + renumregs[5]); -+// break; -+// case 3: -+// permutationEncoding |= (20*renumregs[3] + 4*renumregs[4] -+// + renumregs[5]); -+// break; -+// case 2: -+// permutationEncoding |= (5*renumregs[4] + renumregs[5]); -+// break; -+// case 1: -+// permutationEncoding |= (renumregs[5]); -+// break; -+// } -+// return permutationEncoding; -+//} -+// -+ -+ -+ -+ -+// -+// x86_64 -+// -+// 1-bit: start -+// 1-bit: has lsda -+// 2-bit: personality index -+// -+// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=DWARF -+// rbp based: -+// 15-bits (5*3-bits per reg) register permutation -+// 8-bits for stack offset -+// frameless: -+// 8-bits stack size -+// 3-bits stack adjust -+// 3-bits register count -+// 10-bits register permutation -+// -+enum { -+ UNWIND_X86_64_MODE_MASK = 0x0F000000, -+ UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000, -+ UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000, -+ UNWIND_X86_64_MODE_STACK_IND = 0x03000000, -+ UNWIND_X86_64_MODE_DWARF = 0x04000000, -+ -+ UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF, -+ UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000, -+ -+ UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000, -+ UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000, -+ UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00, -+ UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, -+ -+ UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF, -+}; -+ -+enum { -+ UNWIND_X86_64_REG_NONE = 0, -+ UNWIND_X86_64_REG_RBX = 1, -+ UNWIND_X86_64_REG_R12 = 2, -+ UNWIND_X86_64_REG_R13 = 3, -+ UNWIND_X86_64_REG_R14 = 4, -+ UNWIND_X86_64_REG_R15 = 5, -+ UNWIND_X86_64_REG_RBP = 6, -+}; -+// -+// For x86_64 there are four modes for the compact unwind encoding: -+// UNWIND_X86_64_MODE_RBP_FRAME: -+// RBP based frame where RBP is push on stack immediately after return address, -+// then RSP is moved to RBP. Thus, to unwind RSP is restored with the current -+// EPB value, then RBP is restored by popping off the stack, and the return -+// is done by popping the stack once more into the pc. -+// All non-volatile registers that need to be restored must have been saved -+// in a small range in the stack that starts RBP-8 to RBP-2040. The offset/8 -+// is encoded in the UNWIND_X86_64_RBP_FRAME_OFFSET bits. The registers saved -+// are encoded in the UNWIND_X86_64_RBP_FRAME_REGISTERS bits as five 3-bit entries. -+// Each entry contains which register to restore. -+// UNWIND_X86_64_MODE_STACK_IMMD: -+// A "frameless" (RBP not used as frame pointer) function with a small -+// constant stack size. To return, a constant (encoded in the compact -+// unwind encoding) is added to the RSP. Then the return is done by -+// popping the stack into the pc. -+// All non-volatile registers that need to be restored must have been saved -+// on the stack immediately after the return address. The stack_size/8 is -+// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048). -+// The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT. -+// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION constains which registers were -+// saved and their order. -+// UNWIND_X86_64_MODE_STACK_IND: -+// A "frameless" (RBP not used as frame pointer) function large constant -+// stack size. This case is like the previous, except the stack size is too -+// large to encode in the compact unwind encoding. Instead it requires that -+// the function contains "subq $nnnnnnnn,RSP" in its prolog. The compact -+// encoding contains the offset to the nnnnnnnn value in the function in -+// UNWIND_X86_64_FRAMELESS_STACK_SIZE. -+// UNWIND_X86_64_MODE_DWARF: -+// No compact unwind encoding is available. Instead the low 24-bits of the -+// compact encoding is the offset of the DWARF FDE in the __eh_frame section. -+// This mode is never used in object files. It is only generated by the -+// linker in final linked images which have only DWARF unwind info for a -+// function. -+// -+ -+ -+// ARM64 -+// -+// 1-bit: start -+// 1-bit: has lsda -+// 2-bit: personality index -+// -+// 4-bits: 4=frame-based, 3=DWARF, 2=frameless -+// frameless: -+// 12-bits of stack size -+// frame-based: -+// 4-bits D reg pairs saved -+// 5-bits X reg pairs saved -+// DWARF: -+// 24-bits offset of DWARF FDE in __eh_frame section -+// -+enum { -+ UNWIND_ARM64_MODE_MASK = 0x0F000000, -+ UNWIND_ARM64_MODE_FRAMELESS = 0x02000000, -+ UNWIND_ARM64_MODE_DWARF = 0x03000000, -+ UNWIND_ARM64_MODE_FRAME = 0x04000000, -+ -+ UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001, -+ UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002, -+ UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004, -+ UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008, -+ UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010, -+ UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100, -+ UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200, -+ UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400, -+ UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800, -+ -+ UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000, -+ UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF, -+}; -+// For arm64 there are three modes for the compact unwind encoding: -+// UNWIND_ARM64_MODE_FRAME: -+// This is a standard arm64 prolog where FP/LR are immediately pushed on the -+// stack, then SP is copied to FP. If there are any non-volatile registers -+// saved, then are copied into the stack frame in pairs in a contiguous -+// range right below the saved FP/LR pair. Any subset of the five X pairs -+// and four D pairs can be saved, but the memory layout must be in register -+// number order. -+// UNWIND_ARM64_MODE_FRAMELESS: -+// A "frameless" leaf function, where FP/LR are not saved. The return address -+// remains in LR throughout the function. If any non-volatile registers -+// are saved, they must be pushed onto the stack before any stack space is -+// allocated for local variables. The stack sized (including any saved -+// non-volatile registers) divided by 16 is encoded in the bits -+// UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK. -+// UNWIND_ARM64_MODE_DWARF: -+// No compact unwind encoding is available. Instead the low 24-bits of the -+// compact encoding is the offset of the DWARF FDE in the __eh_frame section. -+// This mode is never used in object files. It is only generated by the -+// linker in final linked images which have only DWARF unwind info for a -+// function. -+// -+ -+ -+ -+ -+ -+//////////////////////////////////////////////////////////////////////////////// -+// -+// Relocatable Object Files: __LD,__compact_unwind -+// -+//////////////////////////////////////////////////////////////////////////////// -+ -+// -+// A compiler can generated compact unwind information for a function by adding -+// a "row" to the __LD,__compact_unwind section. This section has the -+// S_ATTR_DEBUG bit set, so the section will be ignored by older linkers. -+// It is removed by the new linker, so never ends up in final executables. -+// This section is a table, initially with one row per function (that needs -+// unwind info). The table columns and some conceptual entries are: -+// -+// range-start pointer to start of function/range -+// range-length -+// compact-unwind-encoding 32-bit encoding -+// personality-function or zero if no personality function -+// lsda or zero if no LSDA data -+// -+// The length and encoding fields are 32-bits. The other are all pointer sized. -+// -+// In x86_64 assembly, these entry would look like: -+// -+// .section __LD,__compact_unwind,regular,debug -+// -+// #compact unwind for _foo -+// .quad _foo -+// .set L1,LfooEnd-_foo -+// .long L1 -+// .long 0x01010001 -+// .quad 0 -+// .quad 0 -+// -+// #compact unwind for _bar -+// .quad _bar -+// .set L2,LbarEnd-_bar -+// .long L2 -+// .long 0x01020011 -+// .quad __gxx_personality -+// .quad except_tab1 -+// -+// -+// Notes: There is no need for any labels in the the __compact_unwind section. -+// The use of the .set directive is to force the evaluation of the -+// range-length at assembly time, instead of generating relocations. -+// -+// To support future compiler optimizations where which non-volatile registers -+// are saved changes within a function (e.g. delay saving non-volatiles until -+// necessary), there can by multiple lines in the __compact_unwind table for one -+// function, each with a different (non-overlapping) range and each with -+// different compact unwind encodings that correspond to the non-volatiles -+// saved at that range of the function. -+// -+// If a particular function is so wacky that there is no compact unwind way -+// to encode it, then the compiler can emit traditional DWARF unwind info. -+// The runtime will use which ever is available. -+// -+// Runtime support for compact unwind encodings are only available on 10.6 -+// and later. So, the compiler should not generate it when targeting pre-10.6. -+ -+ -+ -+ -+//////////////////////////////////////////////////////////////////////////////// -+// -+// Final Linked Images: __TEXT,__unwind_info -+// -+//////////////////////////////////////////////////////////////////////////////// -+ -+// -+// The __TEXT,__unwind_info section is laid out for an efficient two level lookup. -+// The header of the section contains a coarse index that maps function address -+// to the page (4096 byte block) containing the unwind info for that function. -+// -+ -+#define UNWIND_SECTION_VERSION 1 -+struct unwind_info_section_header -+{ -+ uint32_t version; // UNWIND_SECTION_VERSION -+ uint32_t commonEncodingsArraySectionOffset; -+ uint32_t commonEncodingsArrayCount; -+ uint32_t personalityArraySectionOffset; -+ uint32_t personalityArrayCount; -+ uint32_t indexSectionOffset; -+ uint32_t indexCount; -+ // compact_unwind_encoding_t[] -+ // uint32_t personalities[] -+ // unwind_info_section_header_index_entry[] -+ // unwind_info_section_header_lsda_index_entry[] -+}; -+ -+struct unwind_info_section_header_index_entry -+{ -+ uint32_t functionOffset; -+ uint32_t secondLevelPagesSectionOffset; // section offset to start of regular or compress page -+ uint32_t lsdaIndexArraySectionOffset; // section offset to start of lsda_index array for this range -+}; -+ -+struct unwind_info_section_header_lsda_index_entry -+{ -+ uint32_t functionOffset; -+ uint32_t lsdaOffset; -+}; -+ -+// -+// There are two kinds of second level index pages: regular and compressed. -+// A compressed page can hold up to 1021 entries, but it cannot be used -+// if too many different encoding types are used. The regular page holds -+// 511 entries. -+// -+ -+struct unwind_info_regular_second_level_entry -+{ -+ uint32_t functionOffset; -+ compact_unwind_encoding_t encoding; -+}; -+ -+#define UNWIND_SECOND_LEVEL_REGULAR 2 -+struct unwind_info_regular_second_level_page_header -+{ -+ uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR -+ uint16_t entryPageOffset; -+ uint16_t entryCount; -+ // entry array -+}; -+ -+#define UNWIND_SECOND_LEVEL_COMPRESSED 3 -+struct unwind_info_compressed_second_level_page_header -+{ -+ uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED -+ uint16_t entryPageOffset; -+ uint16_t entryCount; -+ uint16_t encodingsPageOffset; -+ uint16_t encodingsCount; -+ // 32-bit entry array -+ // encodings array -+}; -+ -+#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF) -+#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) ((entry >> 24) & 0xFF) -+ -+ -+ -+#endif -+ --- -1.8.3.1 - 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.spec b/lld.spec deleted file mode 100644 index 183330cb1ad45cb273c68223014e3569c9c5ab00..0000000000000000000000000000000000000000 --- a/lld.spec +++ /dev/null @@ -1,168 +0,0 @@ -%bcond_without sys_llvm -%bcond_without check -%bcond_with toolchain_clang -%bcond_without bisheng_autotuner - -%if %{with toolchain_clang} -%global toolchain clang -%endif - -%global maj_ver 17 -%global min_ver 0 -%global patch_ver 6 - -%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 install_bindir %{install_prefix}/bin -%if 0%{?__isa_bits} == 64 -%global install_libdir %{install_prefix}/lib64 -%else -%global install_libdir %{install_prefix}/lib -%endif -%global install_includedir %{install_prefix}/include - -# Don't include unittests in automatic generation of provides or requires. -%global __provides_exclude_from ^%{_libdir}/lld/.*$ -%global __requires_exclude ^libgtest.*$ - -# Disable LTO as this causes crash if gcc lto enabled. -%define _lto_cflags %{nil} - -Name: %{pkg_name} -Version: %{maj_ver}.%{min_ver}.%{patch_ver} -Release: 6 -Summary: The LLVM Linker - -License: NCSA -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: ncurses-devel -BuildRequires: ninja-build -BuildRequires: python3-rpm-macros -BuildRequires: python3-lit >= %{version} -BuildRequires: zlib-devel - -Requires(post): %{_sbindir}/update-alternatives -Requires(preun): %{_sbindir}/update-alternatives - -Requires: %{name}-libs = %{version}-%{release} - -%description -The LLVM project linker. - -%package devel -Summary: Libraries and header files for LLD -Requires: %{name}-libs%{?_isa} = %{version}-%{release} - -%description devel -This package contains library and header files needed to develop new native -programs that use the LLD infrastructure. - -%package libs -Summary: LLD shared libraries - -%description libs -Shared libraries for LLD. - -%prep -%autosetup -n lld-%{version}.src -p2 - -%build -mkdir -p _build -cd _build -%cmake .. -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=%{install_prefix} \ - -DLLVM_LINK_LLVM_DYLIB:BOOL=ON \ - -DLLVM_DYLIB_COMPONENTS="all" \ - -DCMAKE_SKIP_RPATH:BOOL=ON \ - -DPYTHON_EXECUTABLE=%{__python3} \ - -DLLVM_INCLUDE_TESTS=ON \ - -DLLVM_EXTERNAL_LIT=%{_bindir}/lit \ - -DLLVM_LIT_ARGS="-sv \ - --path %{install_prefix}" \ - -DLLVM_COMMON_CMAKE_UTILS=%{install_datadir}/llvm/cmake \ -%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 - -%ninja_build - -%install -%ninja_install -C _build - -rm %{buildroot}%{install_includedir}/mach-o/compact_unwind_encoding.h - -%check -%if %{with check} -%ninja_build check-lld -C _build -%endif - -%files -%license LICENSE.TXT -%{install_bindir}/* - -%files devel -%{install_includedir}/lld -%{install_libdir}/liblld*.so -%{install_libdir}/cmake/lld/ - -%files libs -%{install_libdir}/liblld*.so.* - -%changelog -* Mon Sep 23 2024 zhanglimin - 17.0.6-6 -- [LoongArch] Backport the support for call36 and extreme model relocs. - -* Tue Jul 30 2024 liyunfei - 17.0.6-5 -- Disable toolchain_clang build for BiSheng Autotuner support temporary. - -* Tue Jul 16 2024 liyunfei - 17.0.6-4 -- Add BiSheng Autotuner support. - -* Fri Jul 5 2024 liyunfei - 17.0.6-3 -- Add toolchain_clang build support - -* Mon Mar 25 2024 zhanglimin - 17.0.6-2 -- Supoort `relax` feature on LoongArch - -* Fri Dec 1 2023 zhoujing - 17.0.6-1 -- Update to 17.0.6 - -* Thu May 25 2023 cf-zhao - 12.0.1-1 -- Package init