From: Ulrich Weigand Date: Fri, 21 Jun 2013 14:44:37 +0000 (+0000) Subject: [PowerPC] Support R_PPC_REL16 family of relocations X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=84569698f01bcb49afe5b6140bf0d61cf4f3cf5a;p=oota-llvm.git [PowerPC] Support R_PPC_REL16 family of relocations The GNU assembler supports (as extension to the ABI) use of PC-relative relocations in half16 fields, which allows writing code like: li 1, base-. This patch adds support for those relocation types in the assembler. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184552 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 2a9065280c4..93c676b0d3f 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -2053,6 +2053,10 @@ StringRef ELFObjectFile::getRelocationTypeName(uint32_t Type) const { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_DTPREL16_LO_DS); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_DTPREL16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_DTPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16_HA); default: break; } break; @@ -2127,6 +2131,10 @@ StringRef ELFObjectFile::getRelocationTypeName(uint32_t Type) const { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HIGHESTA); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSGD); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSLD); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16_HA); default: break; } break; diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 53cf261d26f..785ce732f77 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -484,7 +484,11 @@ enum { R_PPC_GOT_DTPREL16_DS = 91, R_PPC_GOT_DTPREL16_LO_DS = 92, R_PPC_GOT_DTPREL16_HI = 93, - R_PPC_GOT_DTPREL16_HA = 94 + R_PPC_GOT_DTPREL16_HA = 94, + R_PPC_REL16 = 249, + R_PPC_REL16_LO = 250, + R_PPC_REL16_HI = 251, + R_PPC_REL16_HA = 252 }; // ELF Relocation types for PPC64 @@ -557,7 +561,11 @@ enum { R_PPC64_DTPREL16_HIGHEST = 105, R_PPC64_DTPREL16_HIGHESTA = 106, R_PPC64_TLSGD = 107, - R_PPC64_TLSLD = 108 + R_PPC64_TLSLD = 108, + R_PPC64_REL16 = 249, + R_PPC64_REL16_LO = 250, + R_PPC64_REL16_HI = 251, + R_PPC64_REL16_HA = 252 }; // ELF Relocation types for AArch64 diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp index 0155a89945d..69e84a18a38 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -63,6 +63,23 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, case PPC::fixup_ppc_brcond14: Type = ELF::R_PPC_REL14; break; + case PPC::fixup_ppc_half16: + switch (Modifier) { + default: llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_None: + Type = ELF::R_PPC_REL16; + break; + case MCSymbolRefExpr::VK_PPC_LO: + Type = ELF::R_PPC_REL16_LO; + break; + case MCSymbolRefExpr::VK_PPC_HI: + Type = ELF::R_PPC_REL16_HI; + break; + case MCSymbolRefExpr::VK_PPC_HA: + Type = ELF::R_PPC_REL16_HA; + break; + } + break; case FK_Data_4: case FK_PCRel_4: Type = ELF::R_PPC_REL32; diff --git a/test/MC/PowerPC/ppc64-fixups.s b/test/MC/PowerPC/ppc64-fixups.s index 1c16a97a287..b99bc6202fa 100644 --- a/test/MC/PowerPC/ppc64-fixups.s +++ b/test/MC/PowerPC/ppc64-fixups.s @@ -87,6 +87,32 @@ # CHECK-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_ADDR16_LO_DS target 0x0 ld 1, target@l(3) +# CHECK: ld 1, target(3) # encoding: [0xe8,0x23,A,0bAAAAAA00] +# CHECK-NEXT: # fixup A - offset: 2, value: target, kind: fixup_ppc_half16ds +# CHECK-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_ADDR16_DS target 0x0 + ld 1, target(3) + +base: +# CHECK: li 3, target-base # encoding: [0x38,0x60,A,A] +# CHECK-NEXT: # fixup A - offset: 2, value: target-base, kind: fixup_ppc_half16 +# CHECK-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_REL16 target 0x2 + li 3, target-base + +# CHECK: li 3, target-base@h # encoding: [0x38,0x60,A,A] +# CHECK-NEXT: # fixup A - offset: 2, value: target-base@h, kind: fixup_ppc_half16 +# CHECK-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_REL16_HI target 0x6 + li 3, target-base@h + +# CHECK: li 3, target-base@l # encoding: [0x38,0x60,A,A] +# CHECK-NEXT: # fixup A - offset: 2, value: target-base@l, kind: fixup_ppc_half16 +# CHECK-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_REL16_LO target 0xA + li 3, target-base@l + +# CHECK: li 3, target-base@ha # encoding: [0x38,0x60,A,A] +# CHECK-NEXT: # fixup A - offset: 2, value: target-base@ha, kind: fixup_ppc_half16 +# CHECK-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_REL16_HA target 0xE + li 3, target-base@ha + # CHECK: ld 1, target@toc(2) # encoding: [0xe8,0x22,A,0bAAAAAA00] # CHECK-NEXT: # fixup A - offset: 2, value: target@toc, kind: fixup_ppc_half16ds # CHECK-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_TOC16_DS target 0x0