[MC][PowerPC] Make .reloc support arbitrary relocation types
authorFangrui Song <maskray@google.com>
Sat, 28 Mar 2020 23:48:59 +0000 (16:48 -0700)
committerFangrui Song <maskray@google.com>
Sun, 29 Mar 2020 00:04:31 +0000 (17:04 -0700)
Generalizes ad7199f3e60a49db023099dcb879fcc9cdf94a2e (R_PPC_NONE/R_PPC64_NONE).

llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
llvm/test/MC/PowerPC/ppc32-reloc-directive.s
llvm/test/MC/PowerPC/ppc64-reloc-directive.s

index 93418b9..7320c1e 100644 (file)
@@ -28,7 +28,6 @@ static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) {
   switch (Kind) {
   default:
     llvm_unreachable("Unknown fixup kind!");
-  case FK_NONE:
   case FK_Data_1:
   case FK_Data_2:
   case FK_Data_4:
@@ -52,8 +51,6 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
   switch (Kind) {
   default:
     llvm_unreachable("Unknown fixup kind!");
-  case FK_NONE:
-    return 0;
   case FK_Data_1:
     return 1;
   case FK_Data_2:
@@ -109,6 +106,11 @@ public:
       { "fixup_ppc_nofixup",     0,       0,   0 }
     };
 
+    // Fixup kinds from .reloc directive are like R_PPC_NONE/R_PPC64_NONE. They
+    // do not require any extra processing.
+    if (Kind >= FirstLiteralRelocationKind)
+      return MCAsmBackend::getFixupKindInfo(FK_NONE);
+
     if (Kind < FirstTargetFixupKind)
       return MCAsmBackend::getFixupKindInfo(Kind);
 
@@ -123,11 +125,14 @@ public:
                   const MCValue &Target, MutableArrayRef<char> Data,
                   uint64_t Value, bool IsResolved,
                   const MCSubtargetInfo *STI) const override {
-    Value = adjustFixupValue(Fixup.getKind(), Value);
+    MCFixupKind Kind = Fixup.getKind();
+    if (Kind >= FirstLiteralRelocationKind)
+      return;
+    Value = adjustFixupValue(Kind, Value);
     if (!Value) return;           // Doesn't change encoding.
 
     unsigned Offset = Fixup.getOffset();
-    unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
+    unsigned NumBytes = getFixupKindNumBytes(Kind);
 
     // For each byte of the fragment that the fixup touches, mask in the bits
     // from the fixup value. The Value has been "split up" into the appropriate
@@ -140,11 +145,10 @@ public:
 
   bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
                              const MCValue &Target) override {
-    switch ((unsigned)Fixup.getKind()) {
+    MCFixupKind Kind = Fixup.getKind();
+    switch ((unsigned)Kind) {
     default:
-      return false;
-    case FK_NONE:
-      return true;
+      return Kind >= FirstLiteralRelocationKind;
     case PPC::fixup_ppc_br24:
     case PPC::fixup_ppc_br24abs:
       // If the target symbol has a local entry point we must not attempt
@@ -228,14 +232,25 @@ public:
 } // end anonymous namespace
 
 Optional<MCFixupKind> ELFPPCAsmBackend::getFixupKind(StringRef Name) const {
-  if (TT.isPPC64()) {
-    if (Name == "R_PPC64_NONE")
-      return FK_NONE;
-  } else {
-    if (Name == "R_PPC_NONE")
-      return FK_NONE;
+  if (TT.isOSBinFormatELF()) {
+    unsigned Type;
+    if (TT.isPPC64()) {
+      Type = llvm::StringSwitch<unsigned>(Name)
+#define ELF_RELOC(X, Y) .Case(#X, Y)
+#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
+#undef ELF_RELOC
+                 .Default(-1u);
+    } else {
+      Type = llvm::StringSwitch<unsigned>(Name)
+#define ELF_RELOC(X, Y) .Case(#X, Y)
+#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
+#undef ELF_RELOC
+                 .Default(-1u);
+    }
+    if (Type != -1u)
+      return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
   }
-  return MCAsmBackend::getFixupKind(Name);
+  return None;
 }
 
 MCAsmBackend *llvm::createPPCAsmBackend(const Target &T,
index 20f752c..c037962 100644 (file)
@@ -73,6 +73,9 @@ static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
 unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
                                           const MCFixup &Fixup,
                                           bool IsPCRel) const {
+  MCFixupKind Kind = Fixup.getKind();
+  if (Kind >= FirstLiteralRelocationKind)
+    return Kind - FirstLiteralRelocationKind;
   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
 
   // determine the type of the relocation
@@ -133,9 +136,6 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
   } else {
     switch (Fixup.getTargetKind()) {
       default: llvm_unreachable("invalid fixup kind!");
-    case FK_NONE:
-      Type = ELF::R_PPC_NONE;
-      break;
     case PPC::fixup_ppc_br24abs:
       Type = ELF::R_PPC_ADDR24;
       break;
index 1563dd2..6beeabd 100644 (file)
@@ -5,10 +5,16 @@
 # PRINT: .reloc 8, R_PPC_NONE, .data
 # PRINT: .reloc 4, R_PPC_NONE, foo+4
 # PRINT: .reloc 0, R_PPC_NONE, 8
+# PRINT: .reloc 0, R_PPC_ADDR32, .data+2
+# PRINT: .reloc 0, R_PPC_REL16_HI, foo+3
+# PRINT: .reloc 0, R_PPC_REL16_HA, 5
 
 # CHECK:      0x8 R_PPC_NONE .data 0x0
 # CHECK-NEXT: 0x4 R_PPC_NONE foo 0x4
 # CHECK-NEXT: 0x0 R_PPC_NONE - 0x8
+# CHECK-NEXT: 0x0 R_PPC_ADDR32 .data 0x2
+# CHECK-NEXT: 0x0 R_PPC_REL16_HI foo 0x3
+# CHECK-NEXT: 0x0 R_PPC_REL16_HA - 0x5
 
 .text
   blr
@@ -17,6 +23,9 @@
   .reloc 8, R_PPC_NONE, .data
   .reloc 4, R_PPC_NONE, foo+4
   .reloc 0, R_PPC_NONE, 8
+  .reloc 0, R_PPC_ADDR32, .data+2
+  .reloc 0, R_PPC_REL16_HI, foo+3
+  .reloc 0, R_PPC_REL16_HA, 5
 
 .data
 .globl foo
index 2442b08..2a03a92 100644 (file)
@@ -7,10 +7,16 @@
 # PRINT: .reloc 8, R_PPC64_NONE, .data
 # PRINT: .reloc 4, R_PPC64_NONE, foo+4
 # PRINT: .reloc 0, R_PPC64_NONE, 8
+# PRINT: .reloc 0, R_PPC64_ADDR32, .data+2
+# PRINT: .reloc 0, R_PPC64_REL16_HI, foo+3
+# PRINT: .reloc 0, R_PPC64_REL16_HA, 5
 
 # CHECK:      0x8 R_PPC64_NONE .data 0x0
 # CHECK-NEXT: 0x4 R_PPC64_NONE foo 0x4
 # CHECK-NEXT: 0x0 R_PPC64_NONE - 0x8
+# CHECK-NEXT: 0x0 R_PPC64_ADDR32 .data 0x2
+# CHECK-NEXT: 0x0 R_PPC64_REL16_HI foo 0x3
+# CHECK-NEXT: 0x0 R_PPC64_REL16_HA - 0x5
 
 .text
   blr
@@ -19,6 +25,9 @@
   .reloc 8, R_PPC64_NONE, .data
   .reloc 4, R_PPC64_NONE, foo+4
   .reloc 0, R_PPC64_NONE, 8
+  .reloc 0, R_PPC64_ADDR32, .data+2
+  .reloc 0, R_PPC64_REL16_HI, foo+3
+  .reloc 0, R_PPC64_REL16_HA, 5
 
 .data
 .globl foo