[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
Sat May 3 00:02:11 PDT 2025


https://github.com/alexrp updated https://github.com/llvm/llvm-project/pull/137915

>From a3181fe232c1015d8d0cff897ce436baaca28192 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= <alex at alexrp.com>
Date: Wed, 30 Apr 2025 04:11:30 +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     | 18 ++++++++++--------
 .../MCTargetDesc/SparcELFObjectWriter.cpp      |  8 +++++---
 .../Sparc/MCTargetDesc/SparcFixupKinds.h       |  6 ++++--
 .../Target/Sparc/MCTargetDesc/SparcMCExpr.cpp  | 16 ++++++++--------
 .../Target/Sparc/MCTargetDesc/SparcMCExpr.h    |  4 ++--
 llvm/test/MC/Sparc/sparc-relocations.s         |  8 ++++----
 6 files changed, 33 insertions(+), 27 deletions(-)

diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index cc8b86e6135b5..a604a4b3b5655 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -107,8 +107,8 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
   case Sparc::fixup_sparc_tls_ie_ld:
   case Sparc::fixup_sparc_tls_ie_ldx:
   case Sparc::fixup_sparc_tls_ie_add:
-  case Sparc::fixup_sparc_gotdata_lox10:
-  case Sparc::fixup_sparc_gotdata_hix22:
+  case Sparc::fixup_sparc_gotdata_op_lox10:
+  case Sparc::fixup_sparc_gotdata_op_hix22:
   case Sparc::fixup_sparc_gotdata_op:
     return 0;
   }
@@ -161,6 +161,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 },
@@ -202,9 +203,9 @@ namespace {
         { "fixup_sparc_tls_le_lox10",   0,  0,  0 },
         { "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 },
+        { "fixup_sparc_gotdata_op_hix22", 10, 22,  0 },
+        { "fixup_sparc_gotdata_op_lox10", 19, 13,  0 },
+        { "fixup_sparc_gotdata_op",        0,  0,  0 },
       };
 
       const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = {
@@ -248,10 +249,11 @@ namespace {
         { "fixup_sparc_tls_le_lox10",   0,  0,  0 },
         { "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 },
+        { "fixup_sparc_gotdata_op_hix22",  0, 22,  0 },
+        { "fixup_sparc_gotdata_op_lox10",  0, 13,  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 f95e5ac1664e6..9efdfb6329e10 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -90,6 +90,7 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
     }
   }
 
+  // clang-format off
   switch(Fixup.getTargetKind()) {
   default:
     llvm_unreachable("Unimplemented fixup -> relocation");
@@ -136,10 +137,11 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
   case Sparc::fixup_sparc_tls_le_lox10:  return ELF::R_SPARC_TLS_LE_LOX10;
   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;
+  case Sparc::fixup_sparc_gotdata_op_hix22: return ELF::R_SPARC_GOTDATA_OP_HIX22;
+  case Sparc::fixup_sparc_gotdata_op_lox10: return ELF::R_SPARC_GOTDATA_OP_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 3b91326589894..667904ed05dc7 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,
@@ -100,9 +101,9 @@ namespace llvm {
       fixup_sparc_lox10,
 
       /// 22-bit fixup corresponding to %gdop_hix22(foo)
-      fixup_sparc_gotdata_hix22,
+      fixup_sparc_gotdata_op_hix22,
       /// 13-bit fixup corresponding to %gdop_lox10(foo)
-      fixup_sparc_gotdata_lox10,
+      fixup_sparc_gotdata_op_lox10,
       /// 32-bit fixup corresponding to %gdop(foo)
       fixup_sparc_gotdata_op,
 
@@ -110,6 +111,7 @@ namespace llvm {
       LastTargetFixupKind,
       NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
     };
+  // clang-format off
   }
 }
 
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
index fa05622ad75b1..375130945b467 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
@@ -83,9 +83,9 @@ bool SparcMCExpr::printSpecifier(raw_ostream &OS, Specifier S) {
   case VK_TLS_LE_LOX10:  OS << "%tle_lox10(";  return true;
   case VK_HIX22:         OS << "%hix(";        return true;
   case VK_LOX10:         OS << "%lox(";        return true;
-  case VK_GOTDATA_HIX22: OS << "%gdop_hix22("; return true;
-  case VK_GOTDATA_LOX10: OS << "%gdop_lox10("; return true;
-  case VK_GOTDATA_OP:    OS << "%gdop(";       return true;
+  case VK_GOTDATA_OP_HIX22: OS << "%gdop_hix22("; return true;
+  case VK_GOTDATA_OP_LOX10: OS << "%gdop_lox10("; return true;
+  case VK_GOTDATA_OP:       OS << "%gdop(";       return true;
   }
   // clang-format on
   llvm_unreachable("Unhandled SparcMCExpr::Specifier");
@@ -129,8 +129,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);
 }
@@ -175,9 +175,9 @@ Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::Specifier S) {
   case VK_TLS_LE_LOX10:  return Sparc::fixup_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 Sparc::fixup_sparc_gotdata_op_hix22;
+  case VK_GOTDATA_OP_LOX10: return Sparc::fixup_sparc_gotdata_op_lox10;
+  case VK_GOTDATA_OP:       return Sparc::fixup_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 05d9a5ce67104..c53e02293a38f 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/sparc-relocations.s b/llvm/test/MC/Sparc/sparc-relocations.s
index 027164d77b256..be1fb483d16a2 100644
--- a/llvm/test/MC/Sparc/sparc-relocations.s
+++ b/llvm/test/MC/Sparc/sparc-relocations.s
@@ -18,8 +18,8 @@
         ! CHECK-OBJ-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_13 sym
         ! CHECK-OBJ-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_HIX22 sym
         ! CHECK-OBJ-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_LOX10 sym
-        ! CHECK-OBJ-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOTDATA_HIX22 sym
-        ! CHECK-OBJ-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOTDATA_LOX10 sym
+        ! CHECK-OBJ-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOTDATA_OP_HIX22 sym
+        ! CHECK-OBJ-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOTDATA_OP_LOX10 sym
         ! CHECK-OBJ-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOTDATA_OP sym
         ! CHECK-OBJ-NEXT: }
 
@@ -68,10 +68,10 @@
         ! CHECK: xor %g1, %lox(sym), %g1 ! encoding: [0x82,0x18,0b011AAAAA,A]
         xor %g1, %lox(sym), %g1
 
-        ! CHECK: sethi %gdop_hix22(sym), %l1 ! encoding: [0x23,0x00,0x00,0x00]
+        ! CHECK: sethi %gdop_hix22(sym), %l1 ! encoding: [0x23,0b00AAAAAA,A,A]
         sethi %gdop_hix22(sym), %l1
 
-        ! CHECK: or %l1, %gdop_lox10(sym), %l1 ! encoding: [0xa2,0x14,0x60,0x00]
+        ! CHECK: or %l1, %gdop_lox10(sym), %l1 ! encoding: [0xa2,0x14,0b011AAAAA,A]
         or %l1, %gdop_lox10(sym), %l1
 
         ! CHECK: ldx [%l7+%l1], %l2, %gdop(sym) ! encoding: [0xe4,0x5d,0xc0,0x11]



More information about the llvm-commits mailing list