init for Multi-Version LLVM-18.1.8
Signed-off-by: liyunfei <liyunfei33@huawei.com>
This commit is contained in:
parent
c66ce69cc4
commit
662c7f8ebf
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 ⌖
|
||||
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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
22
README.en.md
22
README.en.md
@ -1,8 +1,22 @@
|
||||
# lld
|
||||
# lld-latest
|
||||
|
||||
#### Description
|
||||
This package contains library and header files needed to develop new native
|
||||
programs that use the LLD infrastructure.
|
||||
LLVM Linker
|
||||
|
||||
#### Software Architecture
|
||||
Software architecture description
|
||||
|
||||
#### Installation
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Instructions
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Contribution
|
||||
|
||||
@ -19,4 +33,4 @@ programs that use the LLD infrastructure.
|
||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
|
||||
23
README.md
23
README.md
@ -1,8 +1,23 @@
|
||||
# lld
|
||||
# lld-latest
|
||||
|
||||
#### 介绍
|
||||
This package contains library and header files needed to develop new native
|
||||
programs that use the LLD infrastructure.
|
||||
LLVM Linker
|
||||
|
||||
#### 软件架构
|
||||
软件架构说明
|
||||
|
||||
|
||||
#### 安装教程
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### 使用说明
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### 参与贡献
|
||||
|
||||
@ -19,4 +34,4 @@ programs that use the LLD infrastructure.
|
||||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
||||
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
||||
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
||||
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
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
BIN
lld-18.1.8.src.tar.xz
Normal file
Binary file not shown.
72
lld.spec
72
lld.spec
@ -1,27 +1,20 @@
|
||||
%undefine __cmake_in_source_build
|
||||
|
||||
%bcond_without sys_llvm
|
||||
%bcond_without check
|
||||
%bcond_with toolchain_clang
|
||||
%bcond_without bisheng_autotuner
|
||||
%bcond_without toolchain_clang
|
||||
|
||||
%if %{with toolchain_clang}
|
||||
%global toolchain clang
|
||||
%endif
|
||||
|
||||
%global maj_ver 17
|
||||
%global min_ver 0
|
||||
%global patch_ver 6
|
||||
%global maj_ver 18
|
||||
%global min_ver 1
|
||||
%global patch_ver 8
|
||||
|
||||
%if %{with sys_llvm}
|
||||
%global pkg_name lld
|
||||
%global install_prefix %{_prefix}
|
||||
%global install_datadir %{_datadir}
|
||||
%else
|
||||
%global pkg_name lld%{maj_ver}
|
||||
%global install_prefix %{_libdir}/llvm%{maj_ver}
|
||||
%global install_datadir %{install_prefix}/share
|
||||
%endif
|
||||
%global _scl_prefix /opt/openEuler
|
||||
%{?scl:%scl_package %scl}
|
||||
%{!?scl:%global scl_prefix llvm-toolset-%{maj_ver}-}
|
||||
%{!?scl:%global pkg_name %{name}}
|
||||
%global install_prefix %{!?scl:%{_scl_prefix}/llvm-toolset-%{maj_ver}/root}%{_prefix}
|
||||
%global install_datadir %{!?scl:%{_scl_prefix}/llvm-toolset-%{maj_ver}/root}%{_datadir}
|
||||
|
||||
%global install_bindir %{install_prefix}/bin
|
||||
%if 0%{?__isa_bits} == 64
|
||||
@ -38,9 +31,9 @@
|
||||
# Disable LTO as this causes crash if gcc lto enabled.
|
||||
%define _lto_cflags %{nil}
|
||||
|
||||
Name: %{pkg_name}
|
||||
Name: %{?scl_prefix}lld
|
||||
Version: %{maj_ver}.%{min_ver}.%{patch_ver}
|
||||
Release: 8
|
||||
Release: 1
|
||||
Summary: The LLVM Linker
|
||||
|
||||
License: NCSA
|
||||
@ -48,26 +41,13 @@ URL: http://llvm.org
|
||||
Source0: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{version}/lld-%{version}.src.tar.xz
|
||||
|
||||
Patch1: fedora-PATCH-lld-Import-compact_unwind_encoding.h-from-libu.patch
|
||||
Patch2: 0002-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-6-relocation-type.patch
|
||||
Patch3: 0003-Backport-ELF-RISCV-Implement-emit-relocs-with-relaxation.patch
|
||||
Patch4: 0004-Backport-lld-ELF-Support-relax-R_LARCH_ALIGN.patch
|
||||
Patch5: 0005-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-_ULEB128-relocation-types.patch
|
||||
Patch6: 0006-Add-BiSheng-Autotuner-support-for-LLVM-compiler.patch
|
||||
Patch7: 0007-Backport-LoongArch-add-support-for-call36-and-extreme-relocs.patch
|
||||
|
||||
BuildRequires: clang
|
||||
BuildRequires: cmake
|
||||
%if %{with sys_llvm}
|
||||
BuildRequires: llvm-devel = %{version}
|
||||
BuildRequires: llvm-googletest = %{version}
|
||||
BuildRequires: llvm-test = %{version}
|
||||
BuildRequires: llvm-cmake-utils = %{version}
|
||||
%else
|
||||
BuildRequires: llvm%{maj_ver}-devel = %{version}
|
||||
BuildRequires: llvm%{maj_ver}-googletest = %{version}
|
||||
BuildRequires: llvm%{maj_ver}-test = %{version}
|
||||
BuildRequires: llvm%{maj_ver}-cmake-utils = %{version}
|
||||
%endif
|
||||
BuildRequires: %{?scl_prefix}llvm-devel = %{version}
|
||||
BuildRequires: %{?scl_prefix}llvm-googletest = %{version}
|
||||
BuildRequires: %{?scl_prefix}llvm-test = %{version}
|
||||
BuildRequires: %{?scl_prefix}llvm-cmake-utils = %{version}
|
||||
BuildRequires: ncurses-devel
|
||||
BuildRequires: ninja-build
|
||||
BuildRequires: python3-rpm-macros
|
||||
@ -77,14 +57,14 @@ BuildRequires: zlib-devel
|
||||
Requires(post): %{_sbindir}/update-alternatives
|
||||
Requires(preun): %{_sbindir}/update-alternatives
|
||||
|
||||
Requires: %{name}-libs = %{version}-%{release}
|
||||
Requires: %{pkg_name}-libs = %{version}-%{release}
|
||||
|
||||
%description
|
||||
The LLVM project linker.
|
||||
|
||||
%package devel
|
||||
Summary: Libraries and header files for LLD
|
||||
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
|
||||
Requires: %{pkg_name}-libs%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description devel
|
||||
This package contains library and header files needed to develop new native
|
||||
@ -100,7 +80,9 @@ Shared libraries for LLD.
|
||||
%autosetup -n lld-%{version}.src -p2
|
||||
|
||||
%build
|
||||
%cmake -G Ninja \
|
||||
mkdir -p _build
|
||||
cd _build
|
||||
%cmake .. -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=%{install_prefix} \
|
||||
-DLLVM_LINK_LLVM_DYLIB:BOOL=ON \
|
||||
@ -115,22 +97,19 @@ Shared libraries for LLD.
|
||||
%if "%{toolchain}" == "clang"
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
%endif
|
||||
%if %{with bisheng_autotuner}
|
||||
-DENABLE_AUTOTUNER=ON \
|
||||
%endif
|
||||
-DLLVM_MAIN_SRC_DIR=%{install_prefix}/src
|
||||
|
||||
%cmake_build
|
||||
%ninja_build
|
||||
|
||||
%install
|
||||
%cmake_install
|
||||
%ninja_install -C _build
|
||||
|
||||
rm %{buildroot}%{install_includedir}/mach-o/compact_unwind_encoding.h
|
||||
|
||||
%check
|
||||
%if %{with check}
|
||||
%cmake_build --target check-lld
|
||||
%ninja_build check-lld -C _build
|
||||
%endif
|
||||
|
||||
%files
|
||||
@ -146,6 +125,9 @@ rm %{buildroot}%{install_includedir}/mach-o/compact_unwind_encoding.h
|
||||
%{install_libdir}/liblld*.so.*
|
||||
|
||||
%changelog
|
||||
* Fri Dec 6 2024 liyunfei <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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user