Compare commits

...

11 Commits

Author SHA1 Message Date
openeuler-ci-bot
54e453517a
!24 init for Multi-Version LLVM-18.1.8
From: @liyunfei33 
Reviewed-by: @eastb233 
Signed-off-by: @eastb233
2024-12-10 07:20:07 +00:00
liyunfei
662c7f8ebf init for Multi-Version LLVM-18.1.8
Signed-off-by: liyunfei <liyunfei33@huawei.com>
2024-12-09 10:19:06 +08:00
openeuler-ci-bot
c66ce69cc4
!23 fix check section
From: @fundawang 
Reviewed-by: @liyunfei33 
Signed-off-by: @liyunfei33
2024-11-13 01:26:09 +00:00
Funda Wang
241f41c0ba fix check section 2024-11-12 21:17:53 +08:00
openeuler-ci-bot
57bee72fdd
!22 adopt to new cmake macro
From: @fundawang 
Reviewed-by: @liyunfei33 
Signed-off-by: @liyunfei33
2024-11-12 12:55:46 +00:00
Funda Wang
3e2755936b adopt to new cmake macro 2024-11-11 09:24:31 +08:00
openeuler-ci-bot
ddc937a977
!20 [Backport][LoongArch] Add support for call36 and extreme model relocs
From: @ami-zhang 
Reviewed-by: @cf-zhao 
Signed-off-by: @cf-zhao
2024-10-13 06:30:15 +00:00
Ami-zhang
c8961dce9d [Backport][LoongArch] Add support for call36 and extreme model relocs 2024-09-23 16:22:24 +08:00
openeuler-ci-bot
68c85882b5
!16 Disable toolchain_clang build for BiSheng Autotuner support temporary.
From: @liyunfei33 
Reviewed-by: @cf-zhao 
Signed-off-by: @cf-zhao
2024-07-30 03:56:34 +00:00
liyunfei
0d9069e8b1
Disable toolchain_clang build for BiSheng Autotuner support temporary.
Signed-off-by: liyunfei <liyunfei33@huawei.com>
2024-07-30 03:42:35 +00:00
openeuler-ci-bot
8624c41cf5
!14 Add BiSheng Autotuner support
From: @liyunfei33 
Reviewed-by: @cf-zhao 
Signed-off-by: @cf-zhao
2024-07-25 02:41:30 +00:00
10 changed files with 69 additions and 1180 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,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,25 +1,20 @@
%bcond_without sys_llvm
%bcond_without check
%bcond_without toolchain_clang
%bcond_without bisheng_autotuner
%if %{with toolchain_clang}
%global toolchain clang
%endif
%global maj_ver 17
%global min_ver 0
%global patch_ver 6
%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
@ -36,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: 4
Release: 1
Summary: The LLVM Linker
License: NCSA
@ -46,25 +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
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
@ -74,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
@ -114,9 +97,6 @@ cd _build
%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
@ -145,6 +125,21 @@ 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
* Mon Nov 11 2024 Funda Wang <fundawang@yeah.net> - 17.0.6-7
- adopt to new cmake macro
* Mon Sep 23 2024 zhanglimin <zhanglimin@loongson.cn> - 17.0.6-6
- [LoongArch] Backport the support for call36 and extreme model relocs.
* Tue Jul 30 2024 liyunfei <liyunfei33@huawei.com> - 17.0.6-5
- Disable toolchain_clang build for BiSheng Autotuner support temporary.
* Tue Jul 16 2024 liyunfei <liyunfei33@huawei.com> - 17.0.6-4
- Add BiSheng Autotuner support.