From fc93787d7e88cb0ff4139b3d9017f76a0dc2bf10 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 28 Mar 2020 16:48:59 -0700 Subject: [PATCH] [MC][PowerPC] Make .reloc support arbitrary relocation types Generalizes ad7199f3e60a49db023099dcb879fcc9cdf94a2e (R_PPC_NONE/R_PPC64_NONE). --- .../Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp | 47 ++++++++++++++-------- .../PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp | 6 +-- llvm/test/MC/PowerPC/ppc32-reloc-directive.s | 9 +++++ llvm/test/MC/PowerPC/ppc64-reloc-directive.s | 9 +++++ 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp index 93418b9..7320c1e 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -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 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 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(Name) +#define ELF_RELOC(X, Y) .Case(#X, Y) +#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def" +#undef ELF_RELOC + .Default(-1u); + } else { + Type = llvm::StringSwitch(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(FirstLiteralRelocationKind + Type); } - return MCAsmBackend::getFixupKind(Name); + return None; } MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp index 20f752c..c037962 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -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; diff --git a/llvm/test/MC/PowerPC/ppc32-reloc-directive.s b/llvm/test/MC/PowerPC/ppc32-reloc-directive.s index 1563dd2..6beeabd 100644 --- a/llvm/test/MC/PowerPC/ppc32-reloc-directive.s +++ b/llvm/test/MC/PowerPC/ppc32-reloc-directive.s @@ -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 diff --git a/llvm/test/MC/PowerPC/ppc64-reloc-directive.s b/llvm/test/MC/PowerPC/ppc64-reloc-directive.s index 2442b08..2a03a92 100644 --- a/llvm/test/MC/PowerPC/ppc64-reloc-directive.s +++ b/llvm/test/MC/PowerPC/ppc64-reloc-directive.s @@ -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 -- 2.7.4