138a400dfSRafael Espindola //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===// 238a400dfSRafael Espindola // 338a400dfSRafael Espindola // The LLVM Compiler Infrastructure 438a400dfSRafael Espindola // 538a400dfSRafael Espindola // This file is distributed under the University of Illinois Open Source 638a400dfSRafael Espindola // License. See LICENSE.TXT for details. 738a400dfSRafael Espindola // 838a400dfSRafael Espindola //===----------------------------------------------------------------------===// 938a400dfSRafael Espindola 1038a400dfSRafael Espindola #include "MCTargetDesc/PPCMCTargetDesc.h" 11ed0881b2SChandler Carruth #include "MCTargetDesc/PPCFixupKinds.h" 127fadc0eaSRafael Espindola #include "MCTargetDesc/PPCMCExpr.h" 13a4f89844SBill Schmidt #include "llvm/ADT/STLExtras.h" 1438a400dfSRafael Espindola #include "llvm/MC/MCELFObjectWriter.h" 15f2aceda8SAdhemerval Zanella #include "llvm/MC/MCExpr.h" 16f2aceda8SAdhemerval Zanella #include "llvm/MC/MCValue.h" 17ed0881b2SChandler Carruth #include "llvm/Support/ErrorHandling.h" 1838a400dfSRafael Espindola 1938a400dfSRafael Espindola using namespace llvm; 2038a400dfSRafael Espindola 2138a400dfSRafael Espindola namespace { 2238a400dfSRafael Espindola class PPCELFObjectWriter : public MCELFObjectTargetWriter { 2338a400dfSRafael Espindola public: 2438a400dfSRafael Espindola PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI); 2538a400dfSRafael Espindola 2638a400dfSRafael Espindola virtual ~PPCELFObjectWriter(); 2738a400dfSRafael Espindola protected: 28f2aceda8SAdhemerval Zanella virtual unsigned getRelocTypeInner(const MCValue &Target, 29f2aceda8SAdhemerval Zanella const MCFixup &Fixup, 30f2aceda8SAdhemerval Zanella bool IsPCRel) const; 31*9ab38012SRafael Espindola unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 32*9ab38012SRafael Espindola bool IsPCRel, bool IsRelocWithSymbol) const override; 333a75861bSUlrich Weigand virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, 343a75861bSUlrich Weigand const MCValue &Target, 353a75861bSUlrich Weigand const MCFragment &F, 363a75861bSUlrich Weigand const MCFixup &Fixup, 373a75861bSUlrich Weigand bool IsPCRel) const; 38f2aceda8SAdhemerval Zanella virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, 39f2aceda8SAdhemerval Zanella const MCFixup &Fixup, 40f2aceda8SAdhemerval Zanella bool IsPCRel) const; 4138a400dfSRafael Espindola }; 4238a400dfSRafael Espindola } 4338a400dfSRafael Espindola 4438a400dfSRafael Espindola PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) 4538a400dfSRafael Espindola : MCELFObjectTargetWriter(Is64Bit, OSABI, 4638a400dfSRafael Espindola Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC, 4725009623SRafael Espindola /*HasRelocationAddend*/ true) {} 4838a400dfSRafael Espindola 4938a400dfSRafael Espindola PPCELFObjectWriter::~PPCELFObjectWriter() { 5038a400dfSRafael Espindola } 5138a400dfSRafael Espindola 527fadc0eaSRafael Espindola static MCSymbolRefExpr::VariantKind getAccessVariant(const MCFixup &Fixup) { 537fadc0eaSRafael Espindola const MCExpr *Expr = Fixup.getValue(); 547fadc0eaSRafael Espindola 557fadc0eaSRafael Espindola if (Expr->getKind() != MCExpr::Target) 567fadc0eaSRafael Espindola return Fixup.getAccessVariant(); 577fadc0eaSRafael Espindola 587fadc0eaSRafael Espindola switch (cast<PPCMCExpr>(Expr)->getKind()) { 597fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_None: 607fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_None; 617fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_LO: 627fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_LO; 637fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HI: 647fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HI; 657fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HA: 667fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HA; 677fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HIGHERA: 687fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HIGHERA; 697fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HIGHER: 707fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HIGHER; 717fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HIGHEST: 727fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HIGHEST; 737fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HIGHESTA: 747fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HIGHESTA; 757fadc0eaSRafael Espindola } 7694bc422dSAlexey Samsonov llvm_unreachable("unknown PPCMCExpr kind"); 777fadc0eaSRafael Espindola } 787fadc0eaSRafael Espindola 79f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, 8038a400dfSRafael Espindola const MCFixup &Fixup, 81f2aceda8SAdhemerval Zanella bool IsPCRel) const 82f2aceda8SAdhemerval Zanella { 837fadc0eaSRafael Espindola MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Fixup); 84f2aceda8SAdhemerval Zanella 8538a400dfSRafael Espindola // determine the type of the relocation 8638a400dfSRafael Espindola unsigned Type; 8738a400dfSRafael Espindola if (IsPCRel) { 8838a400dfSRafael Espindola switch ((unsigned)Fixup.getKind()) { 8938a400dfSRafael Espindola default: 9038a400dfSRafael Espindola llvm_unreachable("Unimplemented"); 9138a400dfSRafael Espindola case PPC::fixup_ppc_br24: 92b6a30d15SUlrich Weigand case PPC::fixup_ppc_br24abs: 9338a400dfSRafael Espindola Type = ELF::R_PPC_REL24; 9438a400dfSRafael Espindola break; 9572a7dc0dSUlrich Weigand case PPC::fixup_ppc_brcond14: 96b6a30d15SUlrich Weigand case PPC::fixup_ppc_brcond14abs: 9772a7dc0dSUlrich Weigand Type = ELF::R_PPC_REL14; 9872a7dc0dSUlrich Weigand break; 9991add7dfSUlrich Weigand case PPC::fixup_ppc_half16: 10091add7dfSUlrich Weigand switch (Modifier) { 10191add7dfSUlrich Weigand default: llvm_unreachable("Unsupported Modifier"); 10291add7dfSUlrich Weigand case MCSymbolRefExpr::VK_None: 10391add7dfSUlrich Weigand Type = ELF::R_PPC_REL16; 10491add7dfSUlrich Weigand break; 10591add7dfSUlrich Weigand case MCSymbolRefExpr::VK_PPC_LO: 10691add7dfSUlrich Weigand Type = ELF::R_PPC_REL16_LO; 10791add7dfSUlrich Weigand break; 10891add7dfSUlrich Weigand case MCSymbolRefExpr::VK_PPC_HI: 10991add7dfSUlrich Weigand Type = ELF::R_PPC_REL16_HI; 11091add7dfSUlrich Weigand break; 11191add7dfSUlrich Weigand case MCSymbolRefExpr::VK_PPC_HA: 11291add7dfSUlrich Weigand Type = ELF::R_PPC_REL16_HA; 11391add7dfSUlrich Weigand break; 11491add7dfSUlrich Weigand } 11591add7dfSUlrich Weigand break; 1169b0b7813SAdhemerval Zanella case FK_Data_4: 11738a400dfSRafael Espindola case FK_PCRel_4: 11838a400dfSRafael Espindola Type = ELF::R_PPC_REL32; 11938a400dfSRafael Espindola break; 1209b0b7813SAdhemerval Zanella case FK_Data_8: 1219b0b7813SAdhemerval Zanella case FK_PCRel_8: 1229b0b7813SAdhemerval Zanella Type = ELF::R_PPC64_REL64; 1239b0b7813SAdhemerval Zanella break; 12438a400dfSRafael Espindola } 12538a400dfSRafael Espindola } else { 12638a400dfSRafael Espindola switch ((unsigned)Fixup.getKind()) { 12738a400dfSRafael Espindola default: llvm_unreachable("invalid fixup kind!"); 128b6a30d15SUlrich Weigand case PPC::fixup_ppc_br24abs: 12938a400dfSRafael Espindola Type = ELF::R_PPC_ADDR24; 13038a400dfSRafael Espindola break; 131b6a30d15SUlrich Weigand case PPC::fixup_ppc_brcond14abs: 132f2aceda8SAdhemerval Zanella Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_ 13338a400dfSRafael Espindola break; 1346e23ac60SUlrich Weigand case PPC::fixup_ppc_half16: 13585578500SUlrich Weigand switch (Modifier) { 13685578500SUlrich Weigand default: llvm_unreachable("Unsupported Modifier"); 13785578500SUlrich Weigand case MCSymbolRefExpr::VK_None: 138e462053fSUlrich Weigand Type = ELF::R_PPC_ADDR16; 139e462053fSUlrich Weigand break; 140d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_LO: 14138a400dfSRafael Espindola Type = ELF::R_PPC_ADDR16_LO; 14238a400dfSRafael Espindola break; 143e67c565dSUlrich Weigand case MCSymbolRefExpr::VK_PPC_HI: 144e67c565dSUlrich Weigand Type = ELF::R_PPC_ADDR16_HI; 145e67c565dSUlrich Weigand break; 146d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_HA: 1479e90b3c8SUlrich Weigand Type = ELF::R_PPC_ADDR16_HA; 1489e90b3c8SUlrich Weigand break; 149e9126f55SUlrich Weigand case MCSymbolRefExpr::VK_PPC_HIGHER: 150e9126f55SUlrich Weigand Type = ELF::R_PPC64_ADDR16_HIGHER; 151e9126f55SUlrich Weigand break; 152e9126f55SUlrich Weigand case MCSymbolRefExpr::VK_PPC_HIGHERA: 153e9126f55SUlrich Weigand Type = ELF::R_PPC64_ADDR16_HIGHERA; 154e9126f55SUlrich Weigand break; 155e9126f55SUlrich Weigand case MCSymbolRefExpr::VK_PPC_HIGHEST: 156e9126f55SUlrich Weigand Type = ELF::R_PPC64_ADDR16_HIGHEST; 157e9126f55SUlrich Weigand break; 158e9126f55SUlrich Weigand case MCSymbolRefExpr::VK_PPC_HIGHESTA: 159e9126f55SUlrich Weigand Type = ELF::R_PPC64_ADDR16_HIGHESTA; 160e9126f55SUlrich Weigand break; 16193372b45SUlrich Weigand case MCSymbolRefExpr::VK_GOT: 16293372b45SUlrich Weigand Type = ELF::R_PPC_GOT16; 16393372b45SUlrich Weigand break; 16493372b45SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_LO: 16593372b45SUlrich Weigand Type = ELF::R_PPC_GOT16_LO; 16693372b45SUlrich Weigand break; 16793372b45SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_HI: 16893372b45SUlrich Weigand Type = ELF::R_PPC_GOT16_HI; 16993372b45SUlrich Weigand break; 17093372b45SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_HA: 17193372b45SUlrich Weigand Type = ELF::R_PPC_GOT16_HA; 17293372b45SUlrich Weigand break; 173d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC: 1743e186015SUlrich Weigand Type = ELF::R_PPC64_TOC16; 1753e186015SUlrich Weigand break; 176d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC_LO: 17734627e34SBill Schmidt Type = ELF::R_PPC64_TOC16_LO; 17834627e34SBill Schmidt break; 17972ddbd65SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC_HI: 18072ddbd65SUlrich Weigand Type = ELF::R_PPC64_TOC16_HI; 18172ddbd65SUlrich Weigand break; 182d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC_HA: 1839e90b3c8SUlrich Weigand Type = ELF::R_PPC64_TOC16_HA; 1849e90b3c8SUlrich Weigand break; 185876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL: 186876a0d01SUlrich Weigand Type = ELF::R_PPC_TPREL16; 187876a0d01SUlrich Weigand break; 188d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_LO: 1899e90b3c8SUlrich Weigand Type = ELF::R_PPC_TPREL16_LO; 1909e90b3c8SUlrich Weigand break; 191876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HI: 192876a0d01SUlrich Weigand Type = ELF::R_PPC_TPREL16_HI; 193876a0d01SUlrich Weigand break; 194d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HA: 1959e90b3c8SUlrich Weigand Type = ELF::R_PPC_TPREL16_HA; 1969e90b3c8SUlrich Weigand break; 197876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: 198876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_HIGHER; 199876a0d01SUlrich Weigand break; 200876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: 201876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_HIGHERA; 202876a0d01SUlrich Weigand break; 203876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: 204876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_HIGHEST; 205876a0d01SUlrich Weigand break; 206876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: 207876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_HIGHESTA; 208876a0d01SUlrich Weigand break; 209876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL: 210876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16; 211876a0d01SUlrich Weigand break; 212d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 2139e90b3c8SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_LO; 2149e90b3c8SUlrich Weigand break; 215876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HI: 216876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HI; 217876a0d01SUlrich Weigand break; 218d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HA: 2199e90b3c8SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HA; 2209e90b3c8SUlrich Weigand break; 221876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: 222876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HIGHER; 223876a0d01SUlrich Weigand break; 224876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: 225876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HIGHERA; 226876a0d01SUlrich Weigand break; 227876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: 228876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HIGHEST; 229876a0d01SUlrich Weigand break; 230876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: 231876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HIGHESTA; 232876a0d01SUlrich Weigand break; 233876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: 234876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSGD16; 235876a0d01SUlrich Weigand break; 236d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: 237c56f1d34SBill Schmidt Type = ELF::R_PPC64_GOT_TLSGD16_LO; 238c56f1d34SBill Schmidt break; 239876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: 240876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSGD16_HI; 241876a0d01SUlrich Weigand break; 242d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: 2439e90b3c8SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSGD16_HA; 2449e90b3c8SUlrich Weigand break; 245876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: 246876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSLD16; 247876a0d01SUlrich Weigand break; 248d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: 24924b8dd6eSBill Schmidt Type = ELF::R_PPC64_GOT_TLSLD16_LO; 25024b8dd6eSBill Schmidt break; 251876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: 252876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSLD16_HI; 253876a0d01SUlrich Weigand break; 254d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: 2559e90b3c8SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSLD16_HA; 2569e90b3c8SUlrich Weigand break; 257b2044311SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 258b2044311SUlrich Weigand /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets 259b2044311SUlrich Weigand are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */ 260b2044311SUlrich Weigand Type = ELF::R_PPC64_GOT_TPREL16_DS; 261b2044311SUlrich Weigand break; 262b2044311SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 263b2044311SUlrich Weigand /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets 264b2044311SUlrich Weigand are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */ 265b2044311SUlrich Weigand Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 266b2044311SUlrich Weigand break; 267876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: 268876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TPREL16_HI; 269876a0d01SUlrich Weigand break; 270b2044311SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 271b2044311SUlrich Weigand /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets 272b2044311SUlrich Weigand are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */ 273b2044311SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_DS; 274b2044311SUlrich Weigand break; 275b2044311SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 276b2044311SUlrich Weigand /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets 277b2044311SUlrich Weigand are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */ 278b2044311SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 279b2044311SUlrich Weigand break; 280d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: 2819e90b3c8SUlrich Weigand Type = ELF::R_PPC64_GOT_TPREL16_HA; 2829e90b3c8SUlrich Weigand break; 283876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: 284876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_HI; 285876a0d01SUlrich Weigand break; 286876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: 287876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_HA; 288876a0d01SUlrich Weigand break; 28985578500SUlrich Weigand } 29085578500SUlrich Weigand break; 2916e23ac60SUlrich Weigand case PPC::fixup_ppc_half16ds: 2923822ef2cSBill Schmidt switch (Modifier) { 2933822ef2cSBill Schmidt default: llvm_unreachable("Unsupported Modifier"); 2943822ef2cSBill Schmidt case MCSymbolRefExpr::VK_None: 2953e186015SUlrich Weigand Type = ELF::R_PPC64_ADDR16_DS; 296f2aceda8SAdhemerval Zanella break; 297d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_LO: 298e462053fSUlrich Weigand Type = ELF::R_PPC64_ADDR16_LO_DS; 299e462053fSUlrich Weigand break; 30093372b45SUlrich Weigand case MCSymbolRefExpr::VK_GOT: 30193372b45SUlrich Weigand Type = ELF::R_PPC64_GOT16_DS; 30293372b45SUlrich Weigand break; 30393372b45SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_LO: 30493372b45SUlrich Weigand Type = ELF::R_PPC64_GOT16_LO_DS; 30593372b45SUlrich Weigand break; 306d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC: 307f2aceda8SAdhemerval Zanella Type = ELF::R_PPC64_TOC16_DS; 308f2aceda8SAdhemerval Zanella break; 309d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC_LO: 31034627e34SBill Schmidt Type = ELF::R_PPC64_TOC16_LO_DS; 31134627e34SBill Schmidt break; 312876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL: 313876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_DS; 314876a0d01SUlrich Weigand break; 315876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_LO: 316876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_LO_DS; 317876a0d01SUlrich Weigand break; 318876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL: 319876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_DS; 320876a0d01SUlrich Weigand break; 321876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 322876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_LO_DS; 323876a0d01SUlrich Weigand break; 324876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 325876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TPREL16_DS; 326876a0d01SUlrich Weigand break; 327d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 3289f0b4ec0SBill Schmidt Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 329ca4a0c9dSBill Schmidt break; 330876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 331876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_DS; 332876a0d01SUlrich Weigand break; 333876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 334876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 335876a0d01SUlrich Weigand break; 33634627e34SBill Schmidt } 33734627e34SBill Schmidt break; 33824b8dd6eSBill Schmidt case PPC::fixup_ppc_nofixup: 33924b8dd6eSBill Schmidt switch (Modifier) { 34024b8dd6eSBill Schmidt default: llvm_unreachable("Unsupported Modifier"); 34152cf8e44SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TLSGD: 342c56f1d34SBill Schmidt Type = ELF::R_PPC64_TLSGD; 343c56f1d34SBill Schmidt break; 34452cf8e44SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TLSLD: 34524b8dd6eSBill Schmidt Type = ELF::R_PPC64_TLSLD; 34624b8dd6eSBill Schmidt break; 3475b427591SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TLS: 3485b427591SUlrich Weigand Type = ELF::R_PPC64_TLS; 3495b427591SUlrich Weigand break; 35024b8dd6eSBill Schmidt } 35124b8dd6eSBill Schmidt break; 352f2aceda8SAdhemerval Zanella case FK_Data_8: 353f2aceda8SAdhemerval Zanella switch (Modifier) { 354f2aceda8SAdhemerval Zanella default: llvm_unreachable("Unsupported Modifier"); 35568e2e1b3SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOCBASE: 356f2aceda8SAdhemerval Zanella Type = ELF::R_PPC64_TOC; 357f2aceda8SAdhemerval Zanella break; 358f2aceda8SAdhemerval Zanella case MCSymbolRefExpr::VK_None: 359f2aceda8SAdhemerval Zanella Type = ELF::R_PPC64_ADDR64; 360f2aceda8SAdhemerval Zanella break; 361f11efe7fSUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPMOD: 362f11efe7fSUlrich Weigand Type = ELF::R_PPC64_DTPMOD64; 363f11efe7fSUlrich Weigand break; 364f11efe7fSUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL: 365f11efe7fSUlrich Weigand Type = ELF::R_PPC64_TPREL64; 366f11efe7fSUlrich Weigand break; 367f11efe7fSUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL: 368f11efe7fSUlrich Weigand Type = ELF::R_PPC64_DTPREL64; 369f11efe7fSUlrich Weigand break; 370f2aceda8SAdhemerval Zanella } 371f2aceda8SAdhemerval Zanella break; 37238a400dfSRafael Espindola case FK_Data_4: 37338a400dfSRafael Espindola Type = ELF::R_PPC_ADDR32; 37438a400dfSRafael Espindola break; 37538a400dfSRafael Espindola case FK_Data_2: 37638a400dfSRafael Espindola Type = ELF::R_PPC_ADDR16; 37738a400dfSRafael Espindola break; 37838a400dfSRafael Espindola } 37938a400dfSRafael Espindola } 38038a400dfSRafael Espindola return Type; 38138a400dfSRafael Espindola } 38238a400dfSRafael Espindola 383f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, 384f2aceda8SAdhemerval Zanella const MCFixup &Fixup, 385f2aceda8SAdhemerval Zanella bool IsPCRel, 386*9ab38012SRafael Espindola bool IsRelocWithSymbol) const { 387f2aceda8SAdhemerval Zanella return getRelocTypeInner(Target, Fixup, IsPCRel); 388f2aceda8SAdhemerval Zanella } 389f2aceda8SAdhemerval Zanella 3903a75861bSUlrich Weigand const MCSymbol *PPCELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, 3913a75861bSUlrich Weigand const MCValue &Target, 3923a75861bSUlrich Weigand const MCFragment &F, 3933a75861bSUlrich Weigand const MCFixup &Fixup, 3943a75861bSUlrich Weigand bool IsPCRel) const { 3953a75861bSUlrich Weigand assert(Target.getSymA() && "SymA cannot be 0"); 3967fadc0eaSRafael Espindola MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant(); 3973a75861bSUlrich Weigand 3983a75861bSUlrich Weigand bool EmitThisSym; 3993a75861bSUlrich Weigand switch (Modifier) { 4003a75861bSUlrich Weigand // GOT references always need a relocation, even if the 4013a75861bSUlrich Weigand // target symbol is local. 4023a75861bSUlrich Weigand case MCSymbolRefExpr::VK_GOT: 4033a75861bSUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_LO: 4043a75861bSUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_HI: 4053a75861bSUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_HA: 4063a75861bSUlrich Weigand EmitThisSym = true; 4073a75861bSUlrich Weigand break; 4083a75861bSUlrich Weigand default: 4093a75861bSUlrich Weigand EmitThisSym = false; 4103a75861bSUlrich Weigand break; 4113a75861bSUlrich Weigand } 4123a75861bSUlrich Weigand 4133a75861bSUlrich Weigand if (EmitThisSym) 4143a75861bSUlrich Weigand return &Target.getSymA()->getSymbol().AliasedSymbol(); 4153a75861bSUlrich Weigand return NULL; 4163a75861bSUlrich Weigand } 4173a75861bSUlrich Weigand 418f2aceda8SAdhemerval Zanella const MCSymbol *PPCELFObjectWriter::undefinedExplicitRelSym(const MCValue &Target, 419f2aceda8SAdhemerval Zanella const MCFixup &Fixup, 420f2aceda8SAdhemerval Zanella bool IsPCRel) const { 421f2aceda8SAdhemerval Zanella assert(Target.getSymA() && "SymA cannot be 0"); 422f2aceda8SAdhemerval Zanella const MCSymbol &Symbol = Target.getSymA()->getSymbol().AliasedSymbol(); 423f2aceda8SAdhemerval Zanella 424f2aceda8SAdhemerval Zanella unsigned RelocType = getRelocTypeInner(Target, Fixup, IsPCRel); 425f2aceda8SAdhemerval Zanella 426f2aceda8SAdhemerval Zanella // The .odp creation emits a relocation against the symbol ".TOC." which 427f2aceda8SAdhemerval Zanella // create a R_PPC64_TOC relocation. However the relocation symbol name 428f2aceda8SAdhemerval Zanella // in final object creation should be NULL, since the symbol does not 429f2aceda8SAdhemerval Zanella // really exist, it is just the reference to TOC base for the current 430f2aceda8SAdhemerval Zanella // object file. 431f2aceda8SAdhemerval Zanella bool EmitThisSym = RelocType != ELF::R_PPC64_TOC; 432f2aceda8SAdhemerval Zanella 433f2aceda8SAdhemerval Zanella if (EmitThisSym && !Symbol.isTemporary()) 434f2aceda8SAdhemerval Zanella return &Symbol; 435f2aceda8SAdhemerval Zanella return NULL; 436f2aceda8SAdhemerval Zanella } 437f2aceda8SAdhemerval Zanella 43838a400dfSRafael Espindola MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS, 43938a400dfSRafael Espindola bool Is64Bit, 440cae3a17aSUlrich Weigand bool IsLittleEndian, 44138a400dfSRafael Espindola uint8_t OSABI) { 44238a400dfSRafael Espindola MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI); 443cae3a17aSUlrich Weigand return createELFObjectWriter(MOTW, OS, IsLittleEndian); 44438a400dfSRafael Espindola } 445