代码拉取完成,页面将自动刷新
relax
feature
From 8d7b71890179d32474b3a1a1c627481bd5a2327d Mon Sep 17 00:00:00 2001
From: zhanglimin <zhanglimin@loongson.cn>
Date: Fri, 15 Mar 2024 14:39:48 +0800
Subject: [PATCH 06/14] [LoongArch][RISCV] Support
R_LARCH_{ADD,SUB}_ULEB128/R_RISCV_{SET,SUB}_ULEB128 for .uleb128 directives
This patch is originally from three upstream commits:
1, R_LARCH_{ADD,SUB}_ULEB128 are originally landed from b57159cb(#76433).
2, R_RISCV_{SET,SUB}_ULEB128 are originally supported from 1df5ea29. Among it, we change
the default behaviour of `-riscv-uleb128-reloc` to not produce uleb128 reloc, in order
to avoid any other side-effects due to the updated implementation of `MCAssembler::relaxLEB()`
function. And at the same time, we ensure that this patch can't introduce new default traits
(such as the generation for uleb128 reloc) on RISCV in this version.
3, Fix invalid-sleb.s in original commit d7398a35.
Change-Id: Ie687b7d8483c76cf647141162641db1a9d819a04
---
.../llvm/BinaryFormat/ELFRelocs/RISCV.def | 2 +
llvm/include/llvm/MC/MCAsmBackend.h | 8 +++
llvm/include/llvm/MC/MCFixup.h | 1 +
llvm/include/llvm/MC/MCFragment.h | 9 ++-
llvm/lib/MC/MCAsmBackend.cpp | 1 +
llvm/lib/MC/MCAssembler.cpp | 39 ++++++++--
.../MCTargetDesc/LoongArchAsmBackend.cpp | 69 ++++++++++++++----
.../MCTargetDesc/LoongArchAsmBackend.h | 3 +
.../RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 27 +++++++
.../RISCV/MCTargetDesc/RISCVAsmBackend.h | 2 +
llvm/test/MC/ELF/RISCV/gen-dwarf.s | 5 +-
llvm/test/MC/LoongArch/Relocations/leb128.s | 72 +++++++++++++++++++
.../MC/LoongArch/Relocations/relax-addsub.s | 57 +++++++++++----
llvm/test/MC/X86/invalid-sleb.s | 5 --
14 files changed, 252 insertions(+), 48 deletions(-)
create mode 100644 llvm/test/MC/LoongArch/Relocations/leb128.s
delete mode 100644 llvm/test/MC/X86/invalid-sleb.s
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
index 9a126df01531..c7fd6490041c 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
@@ -55,3 +55,5 @@ ELF_RELOC(R_RISCV_SET32, 56)
ELF_RELOC(R_RISCV_32_PCREL, 57)
ELF_RELOC(R_RISCV_IRELATIVE, 58)
ELF_RELOC(R_RISCV_PLT32, 59)
+ELF_RELOC(R_RISCV_SET_ULEB128, 60)
+ELF_RELOC(R_RISCV_SUB_ULEB128, 61)
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index 5e08fb41679b..968a767b17f8 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -21,6 +21,7 @@ class MCAlignFragment;
class MCDwarfCallFrameFragment;
class MCDwarfLineAddrFragment;
class MCFragment;
+class MCLEBFragment;
class MCRelaxableFragment;
class MCSymbol;
class MCAsmLayout;
@@ -194,6 +195,13 @@ public:
return false;
}
+ // Defined by linker relaxation targets to possibly emit LEB128 relocations
+ // and set Value at the relocated location.
+ virtual std::pair<bool, bool>
+ relaxLEB128(MCLEBFragment &LF, MCAsmLayout &Layout, int64_t &Value) const {
+ return std::make_pair(false, false);
+ }
+
/// @}
/// Returns the minimum size of a nop in bytes on this target. The assembler
diff --git a/llvm/include/llvm/MC/MCFixup.h b/llvm/include/llvm/MC/MCFixup.h
index 069ca058310f..7f48a90cb1ec 100644
--- a/llvm/include/llvm/MC/MCFixup.h
+++ b/llvm/include/llvm/MC/MCFixup.h
@@ -25,6 +25,7 @@ enum MCFixupKind {
FK_Data_4, ///< A four-byte fixup.
FK_Data_8, ///< A eight-byte fixup.
FK_Data_6b, ///< A six-bits fixup.
+ FK_Data_leb128, ///< A leb128 fixup.
FK_PCRel_1, ///< A one-byte pc relative fixup.
FK_PCRel_2, ///< A two-byte pc relative fixup.
FK_PCRel_4, ///< A four-byte pc relative fixup.
diff --git a/llvm/include/llvm/MC/MCFragment.h b/llvm/include/llvm/MC/MCFragment.h
index 7be4792a4521..e965732010fe 100644
--- a/llvm/include/llvm/MC/MCFragment.h
+++ b/llvm/include/llvm/MC/MCFragment.h
@@ -428,7 +428,7 @@ public:
}
};
-class MCLEBFragment : public MCFragment {
+class MCLEBFragment final : public MCEncodedFragmentWithFixups<10, 1> {
/// True if this is a sleb128, false if uleb128.
bool IsSigned;
@@ -439,17 +439,16 @@ class MCLEBFragment : public MCFragment {
public:
MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
- : MCFragment(FT_LEB, false, Sec), IsSigned(IsSigned_), Value(&Value_) {
+ : MCEncodedFragmentWithFixups<10, 1>(FT_LEB, false, Sec),
+ IsSigned(IsSigned_), Value(&Value_) {
Contents.push_back(0);
}
const MCExpr &getValue() const { return *Value; }
+ void setValue(const MCExpr *Expr) { Value = Expr; }
bool isSigned() const { return IsSigned; }
- SmallString<8> &getContents() { return Contents; }
- const SmallString<8> &getContents() const { return Contents; }
-
/// @}
static bool classof(const MCFragment *F) {
diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp
index 64bbc63719c7..2eef7d363fe7 100644
--- a/llvm/lib/MC/MCAsmBackend.cpp
+++ b/llvm/lib/MC/MCAsmBackend.cpp
@@ -89,6 +89,7 @@ const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"FK_Data_4", 0, 32, 0},
{"FK_Data_8", 0, 64, 0},
{"FK_Data_6b", 0, 6, 0},
+ {"FK_Data_leb128", 0, 0, 0},
{"FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel},
{"FK_PCRel_2", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
{"FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 55ed1a285cd7..86c798ec9e27 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -918,6 +918,12 @@ void MCAssembler::layout(MCAsmLayout &Layout) {
Contents = DF.getContents();
break;
}
+ case MCFragment::FT_LEB: {
+ auto &LF = cast<MCLEBFragment>(Frag);
+ Fixups = LF.getFixups();
+ Contents = LF.getContents();
+ break;
+ }
case MCFragment::FT_PseudoProbe: {
MCPseudoProbeAddrFragment &PF = cast<MCPseudoProbeAddrFragment>(Frag);
Fixups = PF.getFixups();
@@ -1006,12 +1012,31 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
}
bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) {
- uint64_t OldSize = LF.getContents().size();
+ const unsigned OldSize = static_cast<unsigned>(LF.getContents().size());
+ unsigned PadTo = OldSize;
int64_t Value;
- bool Abs = LF.getValue().evaluateKnownAbsolute(Value, Layout);
- if (!Abs)
- report_fatal_error("sleb128 and uleb128 expressions must be absolute");
- SmallString<8> &Data = LF.getContents();
+ SmallVectorImpl<char> &Data = LF.getContents();
+ LF.getFixups().clear();
+ // Use evaluateKnownAbsolute for Mach-O as a hack: .subsections_via_symbols
+ // requires that .uleb128 A-B is foldable where A and B reside in different
+ // fragments. This is used by __gcc_except_table.
+ bool Abs = getSubsectionsViaSymbols()
+ ? LF.getValue().evaluateKnownAbsolute(Value, Layout)
+ : LF.getValue().evaluateAsAbsolute(Value, Layout);
+ if (!Abs) {
+ bool Relaxed, UseZeroPad;
+ std::tie(Relaxed, UseZeroPad) = getBackend().relaxLEB128(LF, Layout, Value);
+ if (!Relaxed) {
+ getContext().reportError(LF.getValue().getLoc(),
+ Twine(LF.isSigned() ? ".s" : ".u") +
+ "leb128 expression is not absolute");
+ LF.setValue(MCConstantExpr::create(0, Context));
+ }
+ uint8_t Tmp[10]; // maximum size: ceil(64/7)
+ PadTo = std::max(PadTo, encodeULEB128(uint64_t(Value), Tmp));
+ if (UseZeroPad)
+ Value = 0;
+ }
Data.clear();
raw_svector_ostream OSE(Data);
// The compiler can generate EH table assembly that is impossible to assemble
@@ -1019,9 +1044,9 @@ bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) {
// to a later alignment fragment. To accommodate such tables, relaxation can
// only increase an LEB fragment size here, not decrease it. See PR35809.
if (LF.isSigned())
- encodeSLEB128(Value, OSE, OldSize);
+ encodeSLEB128(Value, OSE, PadTo);
else
- encodeULEB128(Value, OSE, OldSize);
+ encodeULEB128(Value, OSE, PadTo);
return OldSize != LF.getContents().size();
}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 1ed047a8e632..9227d4d6afed 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -92,6 +92,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case FK_Data_2:
case FK_Data_4:
case FK_Data_8:
+ case FK_Data_leb128:
return Value;
case LoongArch::fixup_loongarch_b16: {
if (!isInt<18>(Value))
@@ -129,6 +130,15 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
}
}
+static void fixupLeb128(MCContext &Ctx, const MCFixup &Fixup,
+ MutableArrayRef<char> Data, uint64_t Value) {
+ unsigned I;
+ for (I = 0; I != Data.size() && Value; ++I, Value >>= 7)
+ Data[I] |= uint8_t(Value & 0x7f);
+ if (Value)
+ Ctx.reportError(Fixup.getLoc(), "Invalid uleb128 value!");
+}
+
void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
@@ -144,6 +154,10 @@ void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm,
MCFixupKindInfo Info = getFixupKindInfo(Kind);
MCContext &Ctx = Asm.getContext();
+ // Fixup leb128 separately.
+ if (Fixup.getTargetKind() == FK_Data_leb128)
+ return fixupLeb128(Ctx, Fixup, Data, Value);
+
// Apply any target-specific value adjustments.
Value = adjustFixupValue(Fixup, Value, Ctx);
@@ -173,6 +187,7 @@ bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
case FK_Data_2:
case FK_Data_4:
case FK_Data_8:
+ case FK_Data_leb128:
return !Target.isAbsolute();
}
}
@@ -202,9 +217,24 @@ getRelocPairForSize(unsigned Size) {
return std::make_pair(
MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD64),
MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB64));
+ case 128:
+ return std::make_pair(
+ MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD_ULEB128),
+ MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB_ULEB128));
}
}
+std::pair<bool, bool> LoongArchAsmBackend::relaxLEB128(MCLEBFragment &LF,
+ MCAsmLayout &Layout,
+ int64_t &Value) const {
+ const MCExpr &Expr = LF.getValue();
+ if (LF.isSigned() || !Expr.evaluateKnownAbsolute(Value, Layout))
+ return std::make_pair(false, false);
+ LF.getFixups().push_back(
+ MCFixup::create(0, &Expr, FK_Data_leb128, Expr.getLoc()));
+ return std::make_pair(true, true);
+}
+
bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
const MCSubtargetInfo *STI) const {
// We mostly follow binutils' convention here: align to 4-byte boundary with a
@@ -226,21 +256,27 @@ bool LoongArchAsmBackend::handleAddSubRelocations(const MCAsmLayout &Layout,
uint64_t &FixedValue) const {
std::pair<MCFixupKind, MCFixupKind> FK;
uint64_t FixedValueA, FixedValueB;
- const MCSection &SecA = Target.getSymA()->getSymbol().getSection();
- const MCSection &SecB = Target.getSymB()->getSymbol().getSection();
-
- // We need record relocation if SecA != SecB. Usually SecB is same as the
- // section of Fixup, which will be record the relocation as PCRel. If SecB
- // is not same as the section of Fixup, it will report error. Just return
- // false and then this work can be finished by handleFixup.
- if (&SecA != &SecB)
- return false;
-
- // In SecA == SecB case. If the linker relaxation is enabled, we need record
- // the ADD, SUB relocations. Otherwise the FixedValue has already been
- // calculated out in evaluateFixup, return true and avoid record relocations.
- if (!STI.hasFeature(LoongArch::FeatureRelax))
- return true;
+ const MCSymbol &SA = Target.getSymA()->getSymbol();
+ const MCSymbol &SB = Target.getSymB()->getSymbol();
+
+ bool force = !SA.isInSection() || !SB.isInSection();
+ if (!force) {
+ const MCSection &SecA = SA.getSection();
+ const MCSection &SecB = SB.getSection();
+
+ // We need record relocation if SecA != SecB. Usually SecB is same as the
+ // section of Fixup, which will be record the relocation as PCRel. If SecB
+ // is not same as the section of Fixup, it will report error. Just return
+ // false and then this work can be finished by handleFixup.
+ if (&SecA != &SecB)
+ return false;
+
+ // In SecA == SecB case. If the linker relaxation is enabled, we need record
+ // the ADD, SUB relocations. Otherwise the FixedValue has already been calc-
+ // ulated out in evaluateFixup, return true and avoid record relocations.
+ if (!STI.hasFeature(LoongArch::FeatureRelax))
+ return true;
+ }
switch (Fixup.getKind()) {
case llvm::FK_Data_1:
@@ -255,6 +291,9 @@ bool LoongArchAsmBackend::handleAddSubRelocations(const MCAsmLayout &Layout,
case llvm::FK_Data_8:
FK = getRelocPairForSize(64);
break;
+ case llvm::FK_Data_leb128:
+ FK = getRelocPairForSize(128);
+ break;
default:
llvm_unreachable("unsupported fixup size");
}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
index 20f25b5cf53b..49801e4fd81a 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
@@ -65,6 +65,9 @@ public:
void relaxInstruction(MCInst &Inst,
const MCSubtargetInfo &STI) const override {}
+ std::pair<bool, bool> relaxLEB128(MCLEBFragment &LF, MCAsmLayout &Layout,
+ int64_t &Value) const override;
+
bool writeNopData(raw_ostream &OS, uint64_t Count,
const MCSubtargetInfo *STI) const override;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 1b890fbe041a..5c651aa93225 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -19,6 +19,7 @@
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
@@ -27,6 +28,13 @@
using namespace llvm;
+// Temporary workaround for old linkers that do not support ULEB128 relocations,
+// which are abused by DWARF v5 DW_LLE_offset_pair/DW_RLE_offset_pair
+// implemented in Clang/LLVM.
+static cl::opt<bool> ULEB128Reloc(
+ "riscv-uleb128-reloc", cl::init(false), cl::Hidden,
+ cl::desc("Emit R_RISCV_SET_ULEB128/E_RISCV_SUB_ULEB128 if appropriate"));
+
std::optional<MCFixupKind> RISCVAsmBackend::getFixupKind(StringRef Name) const {
if (STI.getTargetTriple().isOSBinFormatELF()) {
unsigned Type;
@@ -126,6 +134,7 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
case FK_Data_2:
case FK_Data_4:
case FK_Data_8:
+ case FK_Data_leb128:
if (Target.isAbsolute())
return false;
break;
@@ -330,6 +339,19 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
return true;
}
+std::pair<bool, bool> RISCVAsmBackend::relaxLEB128(MCLEBFragment &LF,
+ MCAsmLayout &Layout,
+ int64_t &Value) const {
+ if (LF.isSigned())
+ return std::make_pair(false, false);
+ const MCExpr &Expr = LF.getValue();
+ if (ULEB128Reloc) {
+ LF.getFixups().push_back(
+ MCFixup::create(0, &Expr, FK_Data_leb128, Expr.getLoc()));
+ }
+ return std::make_pair(Expr.evaluateKnownAbsolute(Value, Layout), false);
+}
+
// Given a compressed control flow instruction this function returns
// the expanded instruction.
unsigned RISCVAsmBackend::getRelaxedOpcode(unsigned Op) const {
@@ -416,6 +438,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case FK_Data_4:
case FK_Data_8:
case FK_Data_6b:
+ case FK_Data_leb128:
return Value;
case RISCV::fixup_riscv_set_6b:
return Value & 0x03;
@@ -596,6 +619,10 @@ bool RISCVAsmBackend::handleAddSubRelocations(const MCAsmLayout &Layout,
TA = ELF::R_RISCV_ADD64;
TB = ELF::R_RISCV_SUB64;
break;
+ case llvm::FK_Data_leb128:
+ TA = ELF::R_RISCV_SET_ULEB128;
+ TB = ELF::R_RISCV_SUB_ULEB128;
+ break;
default:
llvm_unreachable("unsupported fixup size");
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
index 0ea1f32e8296..edefb171bcdc 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
@@ -99,6 +99,8 @@ public:
bool &WasRelaxed) const override;
bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF, MCAsmLayout &Layout,
bool &WasRelaxed) const override;
+ std::pair<bool, bool> relaxLEB128(MCLEBFragment &LF, MCAsmLayout &Layout,
+ int64_t &Value) const override;
bool writeNopData(raw_ostream &OS, uint64_t Count,
const MCSubtargetInfo *STI) const override;
diff --git a/llvm/test/MC/ELF/RISCV/gen-dwarf.s b/llvm/test/MC/ELF/RISCV/gen-dwarf.s
index 2235559d5f35..2a7dc777e70c 100644
--- a/llvm/test/MC/ELF/RISCV/gen-dwarf.s
+++ b/llvm/test/MC/ELF/RISCV/gen-dwarf.s
@@ -9,7 +9,7 @@
## emit special opcodes to make .debug_line smaller, but we don't do this for
## consistency.
-# RUN: llvm-mc -filetype=obj -triple=riscv64 -g -dwarf-version=5 -mattr=+relax < %s -o %t
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -g -dwarf-version=5 -mattr=+relax -riscv-uleb128-reloc=1 < %s -o %t
# RUN: llvm-dwarfdump -eh-frame -debug-line -debug-rnglists -v %t | FileCheck %s
# RUN: llvm-readobj -r -x .eh_frame %t | FileCheck %s --check-prefix=RELOC
@@ -48,9 +48,10 @@
# RELOC-NEXT: 0x34 R_RISCV_32_PCREL <null> 0x0
# RELOC-NEXT: }
-## TODO A section needs two relocations.
# RELOC: Section ([[#]]) .rela.debug_rnglists {
# RELOC-NEXT: 0xD R_RISCV_64 .text.foo 0x0
+# RELOC-NEXT: 0x15 R_RISCV_SET_ULEB128 <null> 0x0
+# RELOC-NEXT: 0x15 R_RISCV_SUB_ULEB128 .text.foo 0x0
# RELOC-NEXT: 0x17 R_RISCV_64 .text.bar 0x0
# RELOC-NEXT: }
diff --git a/llvm/test/MC/LoongArch/Relocations/leb128.s b/llvm/test/MC/LoongArch/Relocations/leb128.s
new file mode 100644
index 000000000000..7a96ec551b76
--- /dev/null
+++ b/llvm/test/MC/LoongArch/Relocations/leb128.s
@@ -0,0 +1,72 @@
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s -o %t
+# RUN: llvm-readobj -r -x .alloc_w %t | FileCheck --check-prefixes=CHECK,NORELAX %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.relax
+# RUN: llvm-readobj -r -x .alloc_w %t.relax | FileCheck --check-prefixes=CHECK,RELAX %s
+
+# RUN: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax --defsym ERR=1 %s -o /dev/null 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ERR
+# RUN: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax --defsym ERR=1 %s -o /dev/null 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ERR
+
+# CHECK: Relocations [
+# CHECK-NEXT: .rela.alloc_w {
+# RELAX-NEXT: 0x0 R_LARCH_ADD_ULEB128 w1 0x0
+# RELAX-NEXT: 0x0 R_LARCH_SUB_ULEB128 w 0x0
+# RELAX-NEXT: 0x1 R_LARCH_ADD_ULEB128 w2 0x0
+# RELAX-NEXT: 0x1 R_LARCH_SUB_ULEB128 w1 0x0
+# CHECK-NEXT: 0x2 R_LARCH_PCALA_HI20 foo 0x0
+# RELAX-NEXT: 0x2 R_LARCH_RELAX - 0x0
+# CHECK-NEXT: 0x6 R_LARCH_PCALA_LO12 foo 0x0
+# RELAX-NEXT: 0x6 R_LARCH_RELAX - 0x0
+# RELAX-NEXT: 0xA R_LARCH_ADD_ULEB128 w2 0x0
+# RELAX-NEXT: 0xA R_LARCH_SUB_ULEB128 w1 0x0
+# RELAX-NEXT: 0xB R_LARCH_ADD_ULEB128 w2 0x78
+# RELAX-NEXT: 0xB R_LARCH_SUB_ULEB128 w1 0x0
+# RELAX-NEXT: 0xD R_LARCH_ADD_ULEB128 w1 0x0
+# RELAX-NEXT: 0xD R_LARCH_SUB_ULEB128 w2 0x0
+# RELAX-NEXT: 0x17 R_LARCH_ADD_ULEB128 w3 0x6F
+# RELAX-NEXT: 0x17 R_LARCH_SUB_ULEB128 w2 0x0
+# RELAX-NEXT: 0x18 R_LARCH_ADD_ULEB128 w3 0x71
+# RELAX-NEXT: 0x18 R_LARCH_SUB_ULEB128 w2 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+# CHECK: Hex dump of section '.alloc_w':
+# NORELAX-NEXT: 0x00000000 02080c00 001a8c01 c0020880 01f8ffff
+# NORELAX-NEXT: 0x00000010 ffffffff ffff017f 8101
+# RELAX-NEXT: 0x00000000 00000c00 001a8c01 c0020080 00808080
+# RELAX-NEXT: 0x00000010 80808080 80800000 8000
+
+.section .alloc_w,"ax",@progbits; w:
+.uleb128 w1-w # w1 is later defined in the same section
+.uleb128 w2-w1 # w1 and w2 are separated by a linker relaxable instruction
+w1:
+ la.pcrel $t0, foo
+w2:
+.uleb128 w2-w1 # 0x08
+.uleb128 w2-w1+120 # 0x0180
+.uleb128 -(w2-w1) # 0x01fffffffffffffffff8
+.uleb128 w3-w2+111 # 0x7f
+.uleb128 w3-w2+113 # 0x0181
+w3:
+
+.ifdef ERR
+# ERR: :[[#@LINE+1]]:16: error: .uleb128 expression is not absolute
+.uleb128 extern-w # extern is undefined
+# ERR: :[[#@LINE+1]]:11: error: .uleb128 expression is not absolute
+.uleb128 w-extern
+# ERR: :[[#@LINE+1]]:11: error: .uleb128 expression is not absolute
+.uleb128 x-w # x is later defined in another section
+
+.section .alloc_x,"aw",@progbits; x:
+# ERR: :[[#@LINE+1]]:11: error: .uleb128 expression is not absolute
+.uleb128 y-x
+.section .alloc_y,"aw",@progbits; y:
+# ERR: :[[#@LINE+1]]:11: error: .uleb128 expression is not absolute
+.uleb128 x-y
+
+# ERR: :[[#@LINE+1]]:10: error: .uleb128 expression is not absolute
+.uleb128 extern
+# ERR: :[[#@LINE+1]]:10: error: .uleb128 expression is not absolute
+.uleb128 y
+.endif
diff --git a/llvm/test/MC/LoongArch/Relocations/relax-addsub.s b/llvm/test/MC/LoongArch/Relocations/relax-addsub.s
index 14922657ae89..cd01332afd0b 100644
--- a/llvm/test/MC/LoongArch/Relocations/relax-addsub.s
+++ b/llvm/test/MC/LoongArch/Relocations/relax-addsub.s
@@ -8,12 +8,23 @@
# NORELAX-NEXT: 0x10 R_LARCH_PCALA_HI20 .text 0x0
# NORELAX-NEXT: 0x14 R_LARCH_PCALA_LO12 .text 0x0
# NORELAX-NEXT: }
+# NORELAX-NEXT: Section ({{.*}}) .rela.data {
+# NORELAX-NEXT: 0x30 R_LARCH_ADD8 foo 0x0
+# NORELAX-NEXT: 0x30 R_LARCH_SUB8 .text 0x10
+# NORELAX-NEXT: 0x31 R_LARCH_ADD16 foo 0x0
+# NORELAX-NEXT: 0x31 R_LARCH_SUB16 .text 0x10
+# NORELAX-NEXT: 0x33 R_LARCH_ADD32 foo 0x0
+# NORELAX-NEXT: 0x33 R_LARCH_SUB32 .text 0x10
+# NORELAX-NEXT: 0x37 R_LARCH_ADD64 foo 0x0
+# NORELAX-NEXT: 0x37 R_LARCH_SUB64 .text 0x10
+# NORELAX-NEXT: }
# NORELAX-NEXT: ]
# NORELAX: Hex dump of section '.data':
-# NORELAX-NEXT: 0x00000000 04040004 00000004 00000000 0000000c
-# NORELAX-NEXT: 0x00000010 0c000c00 00000c00 00000000 00000808
-# NORELAX-NEXT: 0x00000020 00080000 00080000 00000000 00
+# NORELAX-NEXT: 0x00000000 04040004 00000004 00000000 00000004
+# NORELAX-NEXT: 0x00000010 0c0c000c 0000000c 00000000 0000000c
+# NORELAX-NEXT: 0x00000020 08080008 00000008 00000000 00000008
+# NORELAX-NEXT: 0x00000030 00000000 00000000 00000000 000000
# RELAX: Relocations [
# RELAX-NEXT: Section ({{.*}}) .rela.text {
@@ -23,21 +34,32 @@
# RELAX-NEXT: 0x14 R_LARCH_RELAX - 0x0
# RELAX-NEXT: }
# RELAX-NEXT: Section ({{.*}}) .rela.data {
-# RELAX-NEXT: 0x1E R_LARCH_ADD8 .L4 0x0
-# RELAX-NEXT: 0x1E R_LARCH_SUB8 .L3 0x0
-# RELAX-NEXT: 0x1F R_LARCH_ADD16 .L4 0x0
-# RELAX-NEXT: 0x1F R_LARCH_SUB16 .L3 0x0
-# RELAX-NEXT: 0x21 R_LARCH_ADD32 .L4 0x0
-# RELAX-NEXT: 0x21 R_LARCH_SUB32 .L3 0x0
-# RELAX-NEXT: 0x25 R_LARCH_ADD64 .L4 0x0
-# RELAX-NEXT: 0x25 R_LARCH_SUB64 .L3 0x0
+# RELAX-NEXT: 0x20 R_LARCH_ADD8 .L4 0x0
+# RELAX-NEXT: 0x20 R_LARCH_SUB8 .L3 0x0
+# RELAX-NEXT: 0x21 R_LARCH_ADD16 .L4 0x0
+# RELAX-NEXT: 0x21 R_LARCH_SUB16 .L3 0x0
+# RELAX-NEXT: 0x23 R_LARCH_ADD32 .L4 0x0
+# RELAX-NEXT: 0x23 R_LARCH_SUB32 .L3 0x0
+# RELAX-NEXT: 0x27 R_LARCH_ADD64 .L4 0x0
+# RELAX-NEXT: 0x27 R_LARCH_SUB64 .L3 0x0
+# RELAX-NEXT: 0x2F R_LARCH_ADD_ULEB128 .L4 0x0
+# RELAX-NEXT: 0x2F R_LARCH_SUB_ULEB128 .L3 0x0
+# RELAX-NEXT: 0x30 R_LARCH_ADD8 foo 0x0
+# RELAX-NEXT: 0x30 R_LARCH_SUB8 .L3 0x0
+# RELAX-NEXT: 0x31 R_LARCH_ADD16 foo 0x0
+# RELAX-NEXT: 0x31 R_LARCH_SUB16 .L3 0x0
+# RELAX-NEXT: 0x33 R_LARCH_ADD32 foo 0x0
+# RELAX-NEXT: 0x33 R_LARCH_SUB32 .L3 0x0
+# RELAX-NEXT: 0x37 R_LARCH_ADD64 foo 0x0
+# RELAX-NEXT: 0x37 R_LARCH_SUB64 .L3 0x0
# RELAX-NEXT: }
# RELAX-NEXT: ]
# RELAX: Hex dump of section '.data':
-# RELAX-NEXT: 0x00000000 04040004 00000004 00000000 0000000c
-# RELAX-NEXT: 0x00000010 0c000c00 00000c00 00000000 00000000
-# RELAX-NEXT: 0x00000020 00000000 00000000 00000000 00
+# RELAX-NEXT: 0x00000000 04040004 00000004 00000000 00000004
+# RELAX-NEXT: 0x00000010 0c0c000c 0000000c 00000000 0000000c
+# RELAX-NEXT: 0x00000020 00000000 00000000 00000000 00000000
+# RELAX-NEXT: 0x00000030 00000000 00000000 00000000 000000
.text
.L1:
@@ -55,13 +77,20 @@
.short .L2 - .L1
.word .L2 - .L1
.dword .L2 - .L1
+.uleb128 .L2 - .L1
## TODO Handle alignment directive.
.byte .L3 - .L2
.short .L3 - .L2
.word .L3 - .L2
.dword .L3 - .L2
+.uleb128 .L3 - .L2
## With relaxation, emit relocs because the la.pcrel makes the diff variable.
.byte .L4 - .L3
.short .L4 - .L3
.word .L4 - .L3
.dword .L4 - .L3
+.uleb128 .L4 - .L3
+.byte foo - .L3
+.short foo - .L3
+.word foo - .L3
+.dword foo - .L3
diff --git a/llvm/test/MC/X86/invalid-sleb.s b/llvm/test/MC/X86/invalid-sleb.s
deleted file mode 100644
index 7d7df351ce4e..000000000000
--- a/llvm/test/MC/X86/invalid-sleb.s
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: not --crash llvm-mc -filetype=obj -triple x86_64-pc-linux %s -o %t 2>&1 | FileCheck %s
-
-// CHECK: sleb128 and uleb128 expressions must be absolute
-
- .sleb128 undefined
--
2.20.1
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。