From 228e0afcfd0d5f167a95c6ddbec2c6a4a90b6d2b Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Mon, 1 Jul 2013 23:33:29 +0000 Subject: [PATCH] [PowerPC] Add support for TLS data relocations This adds support for TLS data relocations and modifiers: .quad target@dtpmod .quad target@tprel .quad target@dtprel Currently exploited by the asm parser only. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185394 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCExpr.h | 1 + include/llvm/Object/ELF.h | 6 ++++++ include/llvm/Support/ELF.h | 6 ++++++ lib/MC/MCELFStreamer.cpp | 1 + lib/MC/MCExpr.cpp | 3 +++ .../MCTargetDesc/PPCELFObjectWriter.cpp | 9 ++++++++ test/MC/PowerPC/ppc64-fixups.s | 21 +++++++++++++++++-- 7 files changed, 45 insertions(+), 2 deletions(-) diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 6ac4f94e829..5d559744da9 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -186,6 +186,7 @@ public: VK_PPC_TOC_LO, // symbol@toc@l VK_PPC_TOC_HI, // symbol@toc@h VK_PPC_TOC_HA, // symbol@toc@ha + VK_PPC_DTPMOD, // symbol@dtpmod VK_PPC_TPREL, // symbol@tprel VK_PPC_TPREL_LO, // symbol@tprel@l VK_PPC_TPREL_HI, // symbol@tprel@h diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index d14f96fd64d..9ab0973c1f5 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -2034,14 +2034,17 @@ StringRef ELFObjectFile::getRelocationTypeName(uint32_t Type) const { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_HA); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL32); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TLS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPMOD32); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_LO); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL32); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16_LO); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL32); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSGD16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSGD16_LO); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSGD16_HI); @@ -2106,14 +2109,17 @@ StringRef ELFObjectFile::getRelocationTypeName(uint32_t Type) const { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_DS); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO_DS); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPMOD64); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_LO); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL64); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_LO); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL64); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_LO); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_HI); diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 0b1337fab75..d53ebdbfb91 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -466,14 +466,17 @@ enum { R_PPC_GOT16_HA = 17, R_PPC_REL32 = 26, R_PPC_TLS = 67, + R_PPC_DTPMOD32 = 68, R_PPC_TPREL16 = 69, R_PPC_TPREL16_LO = 70, R_PPC_TPREL16_HI = 71, R_PPC_TPREL16_HA = 72, + R_PPC_TPREL32 = 73, R_PPC_DTPREL16 = 74, R_PPC_DTPREL16_LO = 75, R_PPC_DTPREL16_HI = 76, R_PPC_DTPREL16_HA = 77, + R_PPC_DTPREL32 = 78, R_PPC_GOT_TLSGD16 = 79, R_PPC_GOT_TLSGD16_LO = 80, R_PPC_GOT_TLSGD16_HI = 81, @@ -537,14 +540,17 @@ enum { R_PPC64_TOC16_DS = 63, R_PPC64_TOC16_LO_DS = 64, R_PPC64_TLS = 67, + R_PPC64_DTPMOD64 = 68, R_PPC64_TPREL16 = 69, R_PPC64_TPREL16_LO = 70, R_PPC64_TPREL16_HI = 71, R_PPC64_TPREL16_HA = 72, + R_PPC64_TPREL64 = 73, R_PPC64_DTPREL16 = 74, R_PPC64_DTPREL16_LO = 75, R_PPC64_DTPREL16_HI = 76, R_PPC64_DTPREL16_HA = 77, + R_PPC64_DTPREL64 = 78, R_PPC64_GOT_TLSGD16 = 79, R_PPC64_GOT_TLSGD16_LO = 80, R_PPC64_GOT_TLSGD16_HI = 81, diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 687ddfc18f6..a89e8a66561 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -363,6 +363,7 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { case MCSymbolRefExpr::VK_Mips_GOTTPREL: case MCSymbolRefExpr::VK_Mips_TPREL_HI: case MCSymbolRefExpr::VK_Mips_TPREL_LO: + case MCSymbolRefExpr::VK_PPC_DTPMOD: case MCSymbolRefExpr::VK_PPC_TPREL: case MCSymbolRefExpr::VK_PPC_TPREL_LO: case MCSymbolRefExpr::VK_PPC_TPREL_HI: diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 0b0fb797280..c777e648bdc 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -211,6 +211,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_PPC_TOC_LO: return "toc@l"; case VK_PPC_TOC_HI: return "toc@h"; case VK_PPC_TOC_HA: return "toc@ha"; + case VK_PPC_DTPMOD: return "dtpmod"; case VK_PPC_TPREL: return "tprel"; case VK_PPC_TPREL_LO: return "tprel@l"; case VK_PPC_TPREL_HI: return "tprel@h"; @@ -342,6 +343,8 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) { .Case("toc@ha", VK_PPC_TOC_HA) .Case("TLS", VK_PPC_TLS) .Case("tls", VK_PPC_TLS) + .Case("DTPMOD", VK_PPC_DTPMOD) + .Case("dtpmod", VK_PPC_DTPMOD) .Case("TPREL", VK_PPC_TPREL) .Case("tprel", VK_PPC_TPREL) .Case("TPREL@L", VK_PPC_TPREL_LO) diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp index c26b5458d38..13cd0997b2a 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -312,6 +312,15 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_None: Type = ELF::R_PPC64_ADDR64; break; + case MCSymbolRefExpr::VK_PPC_DTPMOD: + Type = ELF::R_PPC64_DTPMOD64; + break; + case MCSymbolRefExpr::VK_PPC_TPREL: + Type = ELF::R_PPC64_TPREL64; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL: + Type = ELF::R_PPC64_DTPREL64; + break; } break; case FK_Data_4: diff --git a/test/MC/PowerPC/ppc64-fixups.s b/test/MC/PowerPC/ppc64-fixups.s index 18811fa4118..612c899b06d 100644 --- a/test/MC/PowerPC/ppc64-fixups.s +++ b/test/MC/PowerPC/ppc64-fixups.s @@ -25,8 +25,6 @@ beqa target -# FIXME: .TOC.@tocbase - # CHECK: li 3, target@l # encoding: [0x38,0x60,A,A] # CHECK-NEXT: # fixup A - offset: 2, value: target@l, kind: fixup_ppc_half16 # CHECK-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_ADDR16_LO target 0x0 @@ -393,3 +391,22 @@ base: # CHECK-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_GOT_TLSLD16 target 0x0 addi 3, 3, target@got@tlsld + +# Data relocs +# llvm-mc does not show any "encoding" string for data, so we just check the relocs + +# CHECK-REL: .rela.data + .data + +# CHECK-REL: 0x{{[0-9A-F]*[08]}} R_PPC64_TOC - 0x0 + .quad .TOC.@tocbase + +# CHECK-REL: 0x{{[0-9A-F]*[08]}} R_PPC64_DTPMOD64 target 0x0 + .quad target@dtpmod + +# CHECK-REL: 0x{{[0-9A-F]*[08]}} R_PPC64_TPREL64 target 0x0 + .quad target@tprel + +# CHECK-REL: 0x{{[0-9A-F]*[08]}} R_PPC64_DTPREL64 target 0x0 + .quad target@dtprel +