init for Multi-Version LLVM-18.1.8

Signed-off-by: liyunfei <liyunfei33@huawei.com>
This commit is contained in:
liyunfei 2024-12-09 10:19:06 +08:00
parent c66ce69cc4
commit 662c7f8ebf
12 changed files with 64 additions and 1956 deletions

View File

@ -1,78 +0,0 @@
From 7f14e7c1b116fc865ddebb78e67816bfc5216178 Mon Sep 17 00:00:00 2001
From: Jinyang He <hejinyang@loongson.cn>
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

View File

@ -1,239 +0,0 @@
From d53182c7fcc371f575fd71fa74e28220db6e9b82 Mon Sep 17 00:00:00 2001
From: Job Noorman <jnoorman@igalia.com>
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 <class ELFT, class RelTy>
+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<ELFT, RelTy>(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<ELFT> &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<ELFT>(rel), &file.getRelocTargetSym(rel)};
+ }
+ };
+
+ using RawRels = ArrayRef<RelTy>;
+ using MapRelIter =
+ llvm::mapped_iterator<typename RawRels::iterator, MapRel>;
+ auto mapRel = MapRel{*getFile<ELFT>()};
+ RawRels rawRels = getDataAs<RelTy>();
+ auto rels = llvm::make_range(MapRelIter(rawRels.begin(), mapRel),
+ MapRelIter(rawRels.end(), mapRel));
+ copyRelocations<ELFT, RelTy>(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 <class ELFT, class RelTy>
-void InputSection::copyRelocations(uint8_t *buf, ArrayRef<RelTy> rels) {
+template <class ELFT, class RelTy, class RelIt>
+void InputSection::copyRelocations(uint8_t *buf,
+ llvm::iterator_range<RelIt> 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<ELFT> *file = getFile<ELFT>();
- Symbol &sym = file->getRelocTargetSym(rel);
+ Symbol &sym = *rel.sym;
auto *p = reinterpret_cast<typename ELFT::Rela *>(buf);
buf += sizeof(RelTy);
if (RelTy::IsRela)
- p->r_addend = getAddend<ELFT>(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<RelTy> rels) {
continue;
}
- int64_t addend = getAddend<ELFT>(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<RelTy> 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 <class ELFT> 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<ELFT>(buf, getDataAs<typename ELFT::Rela>());
+ copyRelocations<ELFT, typename ELFT::Rela>(buf);
return;
}
if (LLVM_UNLIKELY(type == SHT_REL)) {
- copyRelocations<ELFT>(buf, getDataAs<typename ELFT::Rel>());
+ copyRelocations<ELFT, typename ELFT::Rel>(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 <class ELFT, class RelTy>
- void copyRelocations(uint8_t *buf, llvm::ArrayRef<RelTy> rels);
+ template <class ELFT, class RelTy> void copyRelocations(uint8_t *buf);
+
+ template <class ELFT, class RelTy, class RelIt>
+ void copyRelocations(uint8_t *buf, llvm::iterator_range<RelIt> rels);
template <class ELFT> 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 <f>
+# CHECK-NEXT: R_RISCV_JAL f
+# CHECK-NEXT: R_RISCV_RELAX *ABS*
+# CHECK-NEXT: jal ra, 0x10008 <f>
+# CHECK-NEXT: R_RISCV_JAL f
+# CHECK-NEXT: R_RISCV_RELAX *ABS*
+# CHECK-EMPTY:
+# CHECK-NEXT: <f>:
+# 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: <f>:
+# 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: <f>:
+# 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

View File

@ -1,563 +0,0 @@
From 80c56e85d742bb88533e4789c76ae2b55dc36835 Mon Sep 17 00:00:00 2001
From: Jinyang He <hejinyang@loongson.cn>
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<Relocation> relocs = sec.relocs();
+ auto &aux = *sec.relaxAux;
+ bool changed = false;
+ ArrayRef<SymbolAnchor> 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<int32_t>(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<InputSection *, 0> 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<InputSection *, 0> 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<Relocation> rels = sec->relocs();
+ ArrayRef<uint8_t> old = sec->content();
+ size_t newSize = old.size() - aux.relocDeltas[rels.size() - 1];
+ uint8_t *p = context().bAlloc.Allocate<uint8_t>(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 &target;
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<SymbolAnchor, 0> anchors;
- // For relocations[i], the actual offset is r_offset - (i ? relocDeltas[i-1] :
- // 0).
- std::unique_ptr<uint32_t[]> relocDeltas;
- // For relocations[i], the actual type is relocTypes[i].
- std::unique_ptr<RelType[]> relocTypes;
- SmallVector<uint32_t, 0> writes;
-};
-static void initSymbolAnchors() {
+void elf::initSymbolAnchors() {
SmallVector<InputSection *, 0> storage;
for (OutputSection *osec : outputSections) {
if (!(osec->flags & SHF_EXECINSTR))
continue;
for (InputSection *sec : getInputSections(*osec, storage)) {
- sec->relaxAux = make<RISCVRelaxAux>();
+ sec->relaxAux = make<RelaxAux>();
if (sec->relocs().size()) {
sec->relaxAux->relocDeltas =
std::make_unique<uint32_t[]>(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<InputSection *, 0> 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 <class ELFT, class RelTy>
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<ELFT, RelTy>(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<SymbolAnchor, 0> anchors;
+ // For relocations[i], the actual offset is
+ // r_offset - (i ? relocDeltas[i-1] : 0).
+ std::unique_ptr<uint32_t[]> relocDeltas;
+ // For relocations[i], the actual type is relocTypes[i].
+ std::unique_ptr<RelType[]> relocTypes;
+ SmallVector<uint32_t, 0> 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 <class ELFT> void Writer<ELFT>::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

View File

@ -1,199 +0,0 @@
From a5c1174c902a9dc7fb15aa047ca31e012aea6af9 Mon Sep 17 00:00:00 2001
From: Jinyang He <hejinyang@loongson.cn>
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

View File

@ -1,56 +0,0 @@
From a9863e2b6e6783aa9be0b9d1d187084fd4b32a3a Mon Sep 17 00:00:00 2001
From: Muhammad Asif Manzoor <muhammad.asif.manzoor1@huawei.com>
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

View File

@ -1,764 +0,0 @@
From 2b870b1f213f2d645f4fa685371fbefea09b2969 Mon Sep 17 00:00:00 2001
From: Lu Weining <luweining@loongson.cn>
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 <luweining@loongson.cn>
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 <luweining@loongson.cn>
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 <luweining@loongson.cn>
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 <luweining@loongson.cn>
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 <luweining@loongson.cn>
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 <typename ELFT> 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

View File

@ -1,8 +1,22 @@
# lld
# lld-latest
#### Description
This package contains library and header files needed to develop new native
programs that use the LLD infrastructure.
LLVM Linker
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
@ -19,4 +33,4 @@ programs that use the LLD infrastructure.
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -1,8 +1,23 @@
# lld
# lld-latest
#### 介绍
This package contains library and header files needed to develop new native
programs that use the LLD infrastructure.
LLVM Linker
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
@ -19,4 +34,4 @@ programs that use the LLD infrastructure.
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

Binary file not shown.

BIN
lld-18.1.8.src.tar.xz Normal file

Binary file not shown.

View File

@ -1,27 +1,20 @@
%undefine __cmake_in_source_build
%bcond_without sys_llvm
%bcond_without check
%bcond_with toolchain_clang
%bcond_without bisheng_autotuner
%bcond_without toolchain_clang
%if %{with toolchain_clang}
%global toolchain clang
%endif
%global maj_ver 17
%global min_ver 0
%global patch_ver 6
%global maj_ver 18
%global min_ver 1
%global patch_ver 8
%if %{with sys_llvm}
%global pkg_name lld
%global install_prefix %{_prefix}
%global install_datadir %{_datadir}
%else
%global pkg_name lld%{maj_ver}
%global install_prefix %{_libdir}/llvm%{maj_ver}
%global install_datadir %{install_prefix}/share
%endif
%global _scl_prefix /opt/openEuler
%{?scl:%scl_package %scl}
%{!?scl:%global scl_prefix llvm-toolset-%{maj_ver}-}
%{!?scl:%global pkg_name %{name}}
%global install_prefix %{!?scl:%{_scl_prefix}/llvm-toolset-%{maj_ver}/root}%{_prefix}
%global install_datadir %{!?scl:%{_scl_prefix}/llvm-toolset-%{maj_ver}/root}%{_datadir}
%global install_bindir %{install_prefix}/bin
%if 0%{?__isa_bits} == 64
@ -38,9 +31,9 @@
# Disable LTO as this causes crash if gcc lto enabled.
%define _lto_cflags %{nil}
Name: %{pkg_name}
Name: %{?scl_prefix}lld
Version: %{maj_ver}.%{min_ver}.%{patch_ver}
Release: 8
Release: 1
Summary: The LLVM Linker
License: NCSA
@ -48,26 +41,13 @@ URL: http://llvm.org
Source0: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{version}/lld-%{version}.src.tar.xz
Patch1: fedora-PATCH-lld-Import-compact_unwind_encoding.h-from-libu.patch
Patch2: 0002-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-6-relocation-type.patch
Patch3: 0003-Backport-ELF-RISCV-Implement-emit-relocs-with-relaxation.patch
Patch4: 0004-Backport-lld-ELF-Support-relax-R_LARCH_ALIGN.patch
Patch5: 0005-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-_ULEB128-relocation-types.patch
Patch6: 0006-Add-BiSheng-Autotuner-support-for-LLVM-compiler.patch
Patch7: 0007-Backport-LoongArch-add-support-for-call36-and-extreme-relocs.patch
BuildRequires: clang
BuildRequires: cmake
%if %{with sys_llvm}
BuildRequires: llvm-devel = %{version}
BuildRequires: llvm-googletest = %{version}
BuildRequires: llvm-test = %{version}
BuildRequires: llvm-cmake-utils = %{version}
%else
BuildRequires: llvm%{maj_ver}-devel = %{version}
BuildRequires: llvm%{maj_ver}-googletest = %{version}
BuildRequires: llvm%{maj_ver}-test = %{version}
BuildRequires: llvm%{maj_ver}-cmake-utils = %{version}
%endif
BuildRequires: %{?scl_prefix}llvm-devel = %{version}
BuildRequires: %{?scl_prefix}llvm-googletest = %{version}
BuildRequires: %{?scl_prefix}llvm-test = %{version}
BuildRequires: %{?scl_prefix}llvm-cmake-utils = %{version}
BuildRequires: ncurses-devel
BuildRequires: ninja-build
BuildRequires: python3-rpm-macros
@ -77,14 +57,14 @@ BuildRequires: zlib-devel
Requires(post): %{_sbindir}/update-alternatives
Requires(preun): %{_sbindir}/update-alternatives
Requires: %{name}-libs = %{version}-%{release}
Requires: %{pkg_name}-libs = %{version}-%{release}
%description
The LLVM project linker.
%package devel
Summary: Libraries and header files for LLD
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Requires: %{pkg_name}-libs%{?_isa} = %{version}-%{release}
%description devel
This package contains library and header files needed to develop new native
@ -100,7 +80,9 @@ Shared libraries for LLD.
%autosetup -n lld-%{version}.src -p2
%build
%cmake -G Ninja \
mkdir -p _build
cd _build
%cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=%{install_prefix} \
-DLLVM_LINK_LLVM_DYLIB:BOOL=ON \
@ -115,22 +97,19 @@ Shared libraries for LLD.
%if "%{toolchain}" == "clang"
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
%endif
%if %{with bisheng_autotuner}
-DENABLE_AUTOTUNER=ON \
%endif
-DLLVM_MAIN_SRC_DIR=%{install_prefix}/src
%cmake_build
%ninja_build
%install
%cmake_install
%ninja_install -C _build
rm %{buildroot}%{install_includedir}/mach-o/compact_unwind_encoding.h
%check
%if %{with check}
%cmake_build --target check-lld
%ninja_build check-lld -C _build
%endif
%files
@ -146,6 +125,9 @@ rm %{buildroot}%{install_includedir}/mach-o/compact_unwind_encoding.h
%{install_libdir}/liblld*.so.*
%changelog
* Fri Dec 6 2024 liyunfei <liyunfei33@huawei.com> - 18.1.8-1
- init for Multi-Version LLVM-18.1.8
* Tue Nov 12 2024 Funda Wang <fundawang@yeah.net> - 17.0.6-8
- fix check section

View File

@ -1,4 +0,0 @@
version_control: github
src_repo: llvm/llvm-project
tag_prefix: ^llvmorg-
separator: .