Skip to content

[SPARC][MC] Fix %gdop_hix22() and %gdop_lox10() to use correct relocations #137915

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 4, 2025

Conversation

alexrp
Copy link
Member

@alexrp alexrp commented Apr 30, 2025

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.

@llvmbot llvmbot added backend:Sparc mc Machine (object) code labels Apr 30, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 30, 2025

@llvm/pr-subscribers-backend-sparc

Author: Alex Rønne Petersen (alexrp)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/137915.diff

6 Files Affected:

  • (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp (+8-8)
  • (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp (+3-3)
  • (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h (+2-2)
  • (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp (+8-8)
  • (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h (+2-2)
  • (modified) llvm/test/MC/Sparc/sparc-relocations.s (+4-4)
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index cc8b86e6135b5..bab598a833f6f 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;
   }
@@ -202,9 +202,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,9 +248,9 @@ 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 },
       };
 
       // Fixup kinds from .reloc directive are like R_SPARC_NONE. They do
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index f95e5ac1664e6..be1044a1231e0 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -136,9 +136,9 @@ 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;
   }
 
   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..71b3bd181ad34 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
@@ -100,9 +100,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,
 
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]

@llvmbot
Copy link
Member

llvmbot commented Apr 30, 2025

@llvm/pr-subscribers-mc

Author: Alex Rønne Petersen (alexrp)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/137915.diff

6 Files Affected:

  • (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp (+8-8)
  • (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp (+3-3)
  • (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h (+2-2)
  • (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp (+8-8)
  • (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h (+2-2)
  • (modified) llvm/test/MC/Sparc/sparc-relocations.s (+4-4)
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index cc8b86e6135b5..bab598a833f6f 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;
   }
@@ -202,9 +202,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,9 +248,9 @@ 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 },
       };
 
       // Fixup kinds from .reloc directive are like R_SPARC_NONE. They do
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index f95e5ac1664e6..be1044a1231e0 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -136,9 +136,9 @@ 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;
   }
 
   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..71b3bd181ad34 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
@@ -100,9 +100,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,
 
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]

Copy link

github-actions bot commented Apr 30, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@alexrp
Copy link
Member Author

alexrp commented Apr 30, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

This would just be pointless formatting churn in the existing code.

@MaskRay
Copy link
Member

MaskRay commented May 3, 2025

(Still on a trip with limited computer access)

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

This would just be pointless formatting churn in the existing code.

You might add // clang-format off and on if needed, like what I added to SparcMCExpr.cpp

Note: if a fixup kind always leads to a relocation, you can encode its value literally. See

% rg R_LARCH_TLS_IE_PC_HI20 llvm/lib/
llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
214:      FixupKind = ELF::R_LARCH_TLS_IE_PC_HI20;

and llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp for examples.

@alexrp alexrp force-pushed the sparc-gotdata-relocs branch 2 times, most recently from 94be52e to a3181fe Compare May 3, 2025 07:02
@alexrp
Copy link
Member Author

alexrp commented May 3, 2025

You might add // clang-format off and on if needed, like what I added to SparcMCExpr.cpp

Done.

Note: if a fixup kind always leads to a relocation, you can encode its value literally.

That makes sense, but from what I can tell, the SPARC backend would need some refactoring to do this, so probably best not to mix in with this change?

Copy link
Contributor

@koachan koachan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than those already raised by maskray, I think this seems okay~

Copy link
Contributor

@s-barannikov s-barannikov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@alexrp alexrp force-pushed the sparc-gotdata-relocs branch from a3181fe to 5bb8af1 Compare May 4, 2025 00:49
…tions.

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.
@alexrp alexrp force-pushed the sparc-gotdata-relocs branch from 5bb8af1 to 9192761 Compare May 4, 2025 08:14
@alexrp alexrp requested a review from MaskRay May 4, 2025 08:14
@MaskRay MaskRay merged commit c3ff3b2 into llvm:main May 4, 2025
11 checks passed
@alexrp alexrp deleted the sparc-gotdata-relocs branch May 5, 2025 15:39
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…locations (llvm#137915)

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:

```asm
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.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…locations (llvm#137915)

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:

```asm
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.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…locations (llvm#137915)

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:

```asm
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.
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
…locations (llvm#137915)

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:

```asm
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:Sparc mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants