[llvm] [SPARC][MC] Fix `%gdop_hix22()` and `%gdop_lox10()` to use correct relocations (PR #137915)
Alex Rønne Petersen via llvm-commits
llvm-commits at lists.llvm.org
Sun May 4 01:14:27 PDT 2025
https://github.com/alexrp updated https://github.com/llvm/llvm-project/pull/137915
>From 91927610d643387271c29a563a3b37c31a8f301e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= <alex at alexrp.com>
Date: Sun, 4 May 2025 09:58:23 +0200
Subject: [PATCH] [SPARC][MC] Fix %gdop_hix22() and %gdop_lox10() to use
correct relocations.
1bfc5e7 introduced support for %gdop_hix22() and %gdop_lox10(). However, it
incorrectly mapped them to R_SPARC_GOTDATA_HIX22 and R_SPARC_GOTDATA_LOX10.
They should in fact emit R_SPARC_GOTDATA_OP_HIX22 and R_SPARC_GOTDATA_OP_LOX10.
This became a problem when assembling glibc's PIC startup code:
sethi %gdop_hix22(main), %o0
xor %o0, %gdop_lox10(main), %o0
ldx [%l7 + %o0], %o0, %gdop(main)
After the xor, %o0 should contain the GOT offset for main, but because of the
incorrect relocations, it actually ends up containing the address of main, which
of course makes the following ldx fail.
---
.../Sparc/MCTargetDesc/SparcAsmBackend.cpp | 13 ++-----------
.../Sparc/MCTargetDesc/SparcELFObjectWriter.cpp | 5 ++---
.../Target/Sparc/MCTargetDesc/SparcFixupKinds.h | 9 ++-------
.../Target/Sparc/MCTargetDesc/SparcMCExpr.cpp | 16 ++++++++--------
llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h | 4 ++--
llvm/test/MC/Sparc/relocation-specifier.s | 4 ++--
6 files changed, 18 insertions(+), 33 deletions(-)
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index 6386f6786df3c..59febfb405fa8 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -82,11 +82,6 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
case Sparc::fixup_sparc_hm:
return (Value >> 32) & 0x3ff;
-
- case Sparc::fixup_sparc_gotdata_lox10:
- case Sparc::fixup_sparc_gotdata_hix22:
- case Sparc::fixup_sparc_gotdata_op:
- return 0;
}
}
@@ -137,6 +132,7 @@ namespace {
}
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override {
+ // clang-format off
const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = {
// name offset bits flags
{ "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
@@ -157,9 +153,6 @@ namespace {
{ "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_hix22", 10, 22, 0 },
{ "fixup_sparc_lox10", 19, 13, 0 },
- { "fixup_sparc_gotdata_hix22", 0, 0, 0 },
- { "fixup_sparc_gotdata_lox10", 0, 0, 0 },
- { "fixup_sparc_gotdata_op", 0, 0, 0 },
};
const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = {
@@ -182,10 +175,8 @@ namespace {
{ "fixup_sparc_wplt30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_hix22", 0, 22, 0 },
{ "fixup_sparc_lox10", 0, 13, 0 },
- { "fixup_sparc_gotdata_hix22", 0, 0, 0 },
- { "fixup_sparc_gotdata_lox10", 0, 0, 0 },
- { "fixup_sparc_gotdata_op", 0, 0, 0 },
};
+ // clang-format on
// Fixup kinds from .reloc directive are like R_SPARC_NONE. They do
// not require any extra processing.
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index 1ed5313703b42..111e65847d352 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -98,6 +98,7 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
}
}
+ // clang-format off
switch(Fixup.getTargetKind()) {
default:
llvm_unreachable("Unimplemented fixup -> relocation");
@@ -127,10 +128,8 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
case Sparc::fixup_sparc_lm: return ELF::R_SPARC_LM22;
case Sparc::fixup_sparc_hix22: return ELF::R_SPARC_HIX22;
case Sparc::fixup_sparc_lox10: return ELF::R_SPARC_LOX10;
- case Sparc::fixup_sparc_gotdata_hix22: return ELF::R_SPARC_GOTDATA_HIX22;
- case Sparc::fixup_sparc_gotdata_lox10: return ELF::R_SPARC_GOTDATA_LOX10;
- case Sparc::fixup_sparc_gotdata_op: return ELF::R_SPARC_GOTDATA_OP;
}
+ // clang-format on
return ELF::R_SPARC_NONE;
}
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
index 5158efae70c10..c99b583df1920 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
@@ -13,6 +13,7 @@
namespace llvm {
namespace Sparc {
+ // clang-format off
enum Fixups {
// fixup_sparc_call30 - 30-bit PC relative relocation for call
fixup_sparc_call30 = FirstTargetFixupKind,
@@ -70,17 +71,11 @@ namespace llvm {
/// 13-bit fixup corresponding to %lox(foo)
fixup_sparc_lox10,
- /// 22-bit fixup corresponding to %gdop_hix22(foo)
- fixup_sparc_gotdata_hix22,
- /// 13-bit fixup corresponding to %gdop_lox10(foo)
- fixup_sparc_gotdata_lox10,
- /// 32-bit fixup corresponding to %gdop(foo)
- fixup_sparc_gotdata_op,
-
// Marker
LastTargetFixupKind,
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
};
+ // clang-format on
}
}
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
index ce4f573e87288..f48a5d79caea8 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
@@ -80,9 +80,9 @@ StringRef SparcMCExpr::getSpecifierName(SparcMCExpr::Specifier S) {
case VK_TLS_LE_LOX10: return "tle_lox10";
case VK_HIX22: return "hix";
case VK_LOX10: return "lox";
- case VK_GOTDATA_HIX22: return "gdop_hix22";
- case VK_GOTDATA_LOX10: return "gdop_lox10";
- case VK_GOTDATA_OP: return "gdop";
+ case VK_GOTDATA_OP_HIX22: return "gdop_hix22";
+ case VK_GOTDATA_OP_LOX10: return "gdop_lox10";
+ case VK_GOTDATA_OP: return "gdop";
}
// clang-format on
llvm_unreachable("Unhandled SparcMCExpr::Specifier");
@@ -126,8 +126,8 @@ SparcMCExpr::Specifier SparcMCExpr::parseSpecifier(StringRef name) {
.Case("tle_lox10", VK_TLS_LE_LOX10)
.Case("hix", VK_HIX22)
.Case("lox", VK_LOX10)
- .Case("gdop_hix22", VK_GOTDATA_HIX22)
- .Case("gdop_lox10", VK_GOTDATA_LOX10)
+ .Case("gdop_hix22", VK_GOTDATA_OP_HIX22)
+ .Case("gdop_lox10", VK_GOTDATA_OP_LOX10)
.Case("gdop", VK_GOTDATA_OP)
.Default(VK_None);
}
@@ -172,9 +172,9 @@ uint16_t SparcMCExpr::getFixupKind() const {
case VK_TLS_LE_LOX10: return ELF::R_SPARC_TLS_LE_LOX10;
case VK_HIX22: return Sparc::fixup_sparc_hix22;
case VK_LOX10: return Sparc::fixup_sparc_lox10;
- case VK_GOTDATA_HIX22: return Sparc::fixup_sparc_gotdata_hix22;
- case VK_GOTDATA_LOX10: return Sparc::fixup_sparc_gotdata_lox10;
- case VK_GOTDATA_OP: return Sparc::fixup_sparc_gotdata_op;
+ case VK_GOTDATA_OP_HIX22: return ELF::R_SPARC_GOTDATA_OP_HIX22;
+ case VK_GOTDATA_OP_LOX10: return ELF::R_SPARC_GOTDATA_OP_LOX10;
+ case VK_GOTDATA_OP: return ELF::R_SPARC_GOTDATA_OP;
}
// clang-format on
}
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
index 7a561dfec250a..bfaf299597fa1 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
@@ -61,8 +61,8 @@ class SparcMCExpr : public MCTargetExpr {
VK_TLS_LE_LOX10,
VK_HIX22,
VK_LOX10,
- VK_GOTDATA_HIX22,
- VK_GOTDATA_LOX10,
+ VK_GOTDATA_OP_HIX22,
+ VK_GOTDATA_OP_LOX10,
VK_GOTDATA_OP,
};
diff --git a/llvm/test/MC/Sparc/relocation-specifier.s b/llvm/test/MC/Sparc/relocation-specifier.s
index cd4d95a10ad32..1051cc7b97e95 100644
--- a/llvm/test/MC/Sparc/relocation-specifier.s
+++ b/llvm/test/MC/Sparc/relocation-specifier.s
@@ -63,8 +63,8 @@ sethi %lm(sym), %l0
# ASM-NEXT: ldx [%l7+%l1], %l2, %gdop(sym)
# OBJDUMP: R_SPARC_HIX22 sym
# OBJDUMP: R_SPARC_LOX10 sym
-# OBJDUMP: R_SPARC_GOTDATA_HIX22 sym
-# OBJDUMP: R_SPARC_GOTDATA_LOX10 sym
+# OBJDUMP: R_SPARC_GOTDATA_OP_HIX22 sym
+# OBJDUMP: R_SPARC_GOTDATA_OP_LOX10 sym
# OBJDUMP: R_SPARC_GOTDATA_OP sym
sethi %hix(sym), %g1
xor %g1, %lox(sym), %g1
More information about the llvm-commits
mailing list