diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -8,6 +8,7 @@ #include "MCTargetDesc/SparcFixupKinds.h" #include "MCTargetDesc/SparcMCTargetDesc.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" @@ -131,6 +132,23 @@ return Sparc::NumTargetFixupKinds; } + Optional getFixupKind(StringRef Name) const override { + unsigned Type; + Type = llvm::StringSwitch(Name) +#define ELF_RELOC(X, Y) .Case(#X, Y) +#include "llvm/BinaryFormat/ELFRelocs/Sparc.def" +#undef ELF_RELOC + .Case("BFD_RELOC_NONE", ELF::R_SPARC_NONE) + .Case("BFD_RELOC_8", ELF::R_SPARC_8) + .Case("BFD_RELOC_16", ELF::R_SPARC_16) + .Case("BFD_RELOC_32", ELF::R_SPARC_32) + .Case("BFD_RELOC_64", ELF::R_SPARC_64) + .Default(-1u); + if (Type == -1u) + return None; + return static_cast(FirstLiteralRelocationKind + Type); + } + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = { // name offset bits flags @@ -216,6 +234,11 @@ { "fixup_sparc_tls_le_lox10", 0, 0, 0 } }; + // Fixup kinds from .reloc directive are like R_SPARC_NONE. They do + // not require any extra processing. + if (Kind >= FirstLiteralRelocationKind) + return MCAsmBackend::getFixupKindInfo(FK_NONE); + if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); @@ -229,6 +252,8 @@ bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) override { + if (Fixup.getKind() >= FirstLiteralRelocationKind) + return true; switch ((Sparc::Fixups)Fixup.getKind()) { default: return false; @@ -299,6 +324,8 @@ uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const override { + if (Fixup.getKind() >= FirstLiteralRelocationKind) + return; Value = adjustFixupValue(Fixup.getKind(), Value); if (!Value) return; // Doesn't change encoding. diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp @@ -42,6 +42,9 @@ const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { + MCFixupKind Kind = Fixup.getKind(); + if (Kind >= FirstLiteralRelocationKind) + return Kind - FirstLiteralRelocationKind; if (const SparcMCExpr *SExpr = dyn_cast(Fixup.getValue())) { if (SExpr->getKind() == SparcMCExpr::VK_Sparc_R_DISP32) @@ -68,6 +71,7 @@ switch(Fixup.getTargetKind()) { default: llvm_unreachable("Unimplemented fixup -> relocation"); + case FK_NONE: return ELF::R_SPARC_NONE; case FK_Data_1: return ELF::R_SPARC_8; case FK_Data_2: return ((Fixup.getOffset() % 2) ? ELF::R_SPARC_UA16 diff --git a/llvm/test/MC/Sparc/reloc-directive.s b/llvm/test/MC/Sparc/reloc-directive.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Sparc/reloc-directive.s @@ -0,0 +1,46 @@ +# RUN: llvm-mc -triple=sparc %s | FileCheck --check-prefix=PRINT %s +# RUN: llvm-mc -triple=sparcv9 %s | FileCheck --check-prefix=PRINT %s +# RUN: llvm-mc -filetype=obj -triple=sparc %s | llvm-readobj -r - | FileCheck %s +# RUN: llvm-mc -filetype=obj -triple=sparcv9 %s | llvm-readobj -r - | FileCheck %s + +# PRINT: .reloc 8, R_SPARC_NONE, .data +# PRINT: .reloc 4, R_SPARC_NONE, foo+4 +# PRINT: .reloc 0, R_SPARC_NONE, 8 +# PRINT: .reloc 0, R_SPARC_32, .data+2 +# PRINT: .reloc 0, R_SPARC_UA16, foo+3 +# PRINT: .reloc 0, R_SPARC_DISP32, foo+5 +# PRINT: .reloc 0, BFD_RELOC_NONE, 9 +# PRINT-NEXT: .reloc 0, BFD_RELOC_32, foo+2 +# PRINT-NEXT: .reloc 0, BFD_RELOC_64, foo+3 + +# CHECK: 0x8 R_SPARC_NONE .data 0x0 +# CHECK-NEXT: 0x4 R_SPARC_NONE foo 0x4 +# CHECK-NEXT: 0x0 R_SPARC_NONE - 0x8 +# CHECK-NEXT: 0x0 R_SPARC_32 .data 0x2 +# CHECK-NEXT: 0x0 R_SPARC_UA16 foo 0x3 +# CHECK-NEXT: 0x0 R_SPARC_DISP32 foo 0x5 +# CHECK-NEXT: 0x0 R_SPARC_NONE - 0x9 +# CHECK-NEXT: 0x0 R_SPARC_32 foo 0x2 +# CHECK-NEXT: 0x0 R_SPARC_64 foo 0x3 +.text + ret + nop + nop + .reloc 8, R_SPARC_NONE, .data + .reloc 4, R_SPARC_NONE, foo+4 + .reloc 0, R_SPARC_NONE, 8 + + .reloc 0, R_SPARC_32, .data+2 + .reloc 0, R_SPARC_UA16, foo+3 + .reloc 0, R_SPARC_DISP32, foo+5 + + .reloc 0, BFD_RELOC_NONE, 9 + .reloc 0, BFD_RELOC_32, foo+2 + .reloc 0, BFD_RELOC_64, foo+3 + +.data +.globl foo +foo: + .word 0 + .word 0 + .word 0