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; 3138a400dfSRafael Espindola virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 3238a400dfSRafael Espindola bool IsPCRel, bool IsRelocWithSymbol, 3338a400dfSRafael Espindola int64_t Addend) const; 343a75861bSUlrich Weigand virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, 353a75861bSUlrich Weigand const MCValue &Target, 363a75861bSUlrich Weigand const MCFragment &F, 373a75861bSUlrich Weigand const MCFixup &Fixup, 383a75861bSUlrich Weigand bool IsPCRel) const; 39f2aceda8SAdhemerval Zanella virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, 40f2aceda8SAdhemerval Zanella const MCFixup &Fixup, 41f2aceda8SAdhemerval Zanella bool IsPCRel) const; 4238a400dfSRafael Espindola }; 4338a400dfSRafael Espindola } 4438a400dfSRafael Espindola 4538a400dfSRafael Espindola PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) 4638a400dfSRafael Espindola : MCELFObjectTargetWriter(Is64Bit, OSABI, 4738a400dfSRafael Espindola Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC, 4825009623SRafael Espindola /*HasRelocationAddend*/ true) {} 4938a400dfSRafael Espindola 5038a400dfSRafael Espindola PPCELFObjectWriter::~PPCELFObjectWriter() { 5138a400dfSRafael Espindola } 5238a400dfSRafael Espindola 537fadc0eaSRafael Espindola static MCSymbolRefExpr::VariantKind getAccessVariant(const MCFixup &Fixup) { 547fadc0eaSRafael Espindola const MCExpr *Expr = Fixup.getValue(); 557fadc0eaSRafael Espindola 567fadc0eaSRafael Espindola if (Expr->getKind() != MCExpr::Target) 577fadc0eaSRafael Espindola return Fixup.getAccessVariant(); 587fadc0eaSRafael Espindola 597fadc0eaSRafael Espindola switch (cast<PPCMCExpr>(Expr)->getKind()) { 607fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_None: 617fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_None; 627fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_LO: 637fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_LO; 647fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HI: 657fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HI; 667fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HA: 677fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HA; 687fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HIGHERA: 697fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HIGHERA; 707fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HIGHER: 717fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HIGHER; 727fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HIGHEST: 737fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HIGHEST; 747fadc0eaSRafael Espindola case PPCMCExpr::VK_PPC_HIGHESTA: 757fadc0eaSRafael Espindola return MCSymbolRefExpr::VK_PPC_HIGHESTA; 767fadc0eaSRafael Espindola } 7794bc422dSAlexey Samsonov llvm_unreachable("unknown PPCMCExpr kind"); 787fadc0eaSRafael Espindola } 797fadc0eaSRafael Espindola 80f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, 8138a400dfSRafael Espindola const MCFixup &Fixup, 82f2aceda8SAdhemerval Zanella bool IsPCRel) const 83f2aceda8SAdhemerval Zanella { 847fadc0eaSRafael Espindola MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Fixup); 85f2aceda8SAdhemerval Zanella 8638a400dfSRafael Espindola // determine the type of the relocation 8738a400dfSRafael Espindola unsigned Type; 8838a400dfSRafael Espindola if (IsPCRel) { 8938a400dfSRafael Espindola switch ((unsigned)Fixup.getKind()) { 9038a400dfSRafael Espindola default: 9138a400dfSRafael Espindola llvm_unreachable("Unimplemented"); 9238a400dfSRafael Espindola case PPC::fixup_ppc_br24: 93b6a30d15SUlrich Weigand case PPC::fixup_ppc_br24abs: 9438a400dfSRafael Espindola Type = ELF::R_PPC_REL24; 9538a400dfSRafael Espindola break; 9672a7dc0dSUlrich Weigand case PPC::fixup_ppc_brcond14: 97b6a30d15SUlrich Weigand case PPC::fixup_ppc_brcond14abs: 9872a7dc0dSUlrich Weigand Type = ELF::R_PPC_REL14; 9972a7dc0dSUlrich Weigand break; 10091add7dfSUlrich Weigand case PPC::fixup_ppc_half16: 10191add7dfSUlrich Weigand switch (Modifier) { 10291add7dfSUlrich Weigand default: llvm_unreachable("Unsupported Modifier"); 10391add7dfSUlrich Weigand case MCSymbolRefExpr::VK_None: 10491add7dfSUlrich Weigand Type = ELF::R_PPC_REL16; 10591add7dfSUlrich Weigand break; 10691add7dfSUlrich Weigand case MCSymbolRefExpr::VK_PPC_LO: 10791add7dfSUlrich Weigand Type = ELF::R_PPC_REL16_LO; 10891add7dfSUlrich Weigand break; 10991add7dfSUlrich Weigand case MCSymbolRefExpr::VK_PPC_HI: 11091add7dfSUlrich Weigand Type = ELF::R_PPC_REL16_HI; 11191add7dfSUlrich Weigand break; 11291add7dfSUlrich Weigand case MCSymbolRefExpr::VK_PPC_HA: 11391add7dfSUlrich Weigand Type = ELF::R_PPC_REL16_HA; 11491add7dfSUlrich Weigand break; 11591add7dfSUlrich Weigand } 11691add7dfSUlrich Weigand break; 1179b0b7813SAdhemerval Zanella case FK_Data_4: 11838a400dfSRafael Espindola case FK_PCRel_4: 11938a400dfSRafael Espindola Type = ELF::R_PPC_REL32; 12038a400dfSRafael Espindola break; 1219b0b7813SAdhemerval Zanella case FK_Data_8: 1229b0b7813SAdhemerval Zanella case FK_PCRel_8: 1239b0b7813SAdhemerval Zanella Type = ELF::R_PPC64_REL64; 1249b0b7813SAdhemerval Zanella break; 12538a400dfSRafael Espindola } 12638a400dfSRafael Espindola } else { 12738a400dfSRafael Espindola switch ((unsigned)Fixup.getKind()) { 12838a400dfSRafael Espindola default: llvm_unreachable("invalid fixup kind!"); 129b6a30d15SUlrich Weigand case PPC::fixup_ppc_br24abs: 13038a400dfSRafael Espindola Type = ELF::R_PPC_ADDR24; 13138a400dfSRafael Espindola break; 132b6a30d15SUlrich Weigand case PPC::fixup_ppc_brcond14abs: 133f2aceda8SAdhemerval Zanella Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_ 13438a400dfSRafael Espindola break; 1356e23ac60SUlrich Weigand case PPC::fixup_ppc_half16: 13685578500SUlrich Weigand switch (Modifier) { 13785578500SUlrich Weigand default: llvm_unreachable("Unsupported Modifier"); 13885578500SUlrich Weigand case MCSymbolRefExpr::VK_None: 139e462053fSUlrich Weigand Type = ELF::R_PPC_ADDR16; 140e462053fSUlrich Weigand break; 141d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_LO: 14238a400dfSRafael Espindola Type = ELF::R_PPC_ADDR16_LO; 14338a400dfSRafael Espindola break; 144e67c565dSUlrich Weigand case MCSymbolRefExpr::VK_PPC_HI: 145e67c565dSUlrich Weigand Type = ELF::R_PPC_ADDR16_HI; 146e67c565dSUlrich Weigand break; 147d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_HA: 1489e90b3c8SUlrich Weigand Type = ELF::R_PPC_ADDR16_HA; 1499e90b3c8SUlrich Weigand break; 150e9126f55SUlrich Weigand case MCSymbolRefExpr::VK_PPC_HIGHER: 151e9126f55SUlrich Weigand Type = ELF::R_PPC64_ADDR16_HIGHER; 152e9126f55SUlrich Weigand break; 153e9126f55SUlrich Weigand case MCSymbolRefExpr::VK_PPC_HIGHERA: 154e9126f55SUlrich Weigand Type = ELF::R_PPC64_ADDR16_HIGHERA; 155e9126f55SUlrich Weigand break; 156e9126f55SUlrich Weigand case MCSymbolRefExpr::VK_PPC_HIGHEST: 157e9126f55SUlrich Weigand Type = ELF::R_PPC64_ADDR16_HIGHEST; 158e9126f55SUlrich Weigand break; 159e9126f55SUlrich Weigand case MCSymbolRefExpr::VK_PPC_HIGHESTA: 160e9126f55SUlrich Weigand Type = ELF::R_PPC64_ADDR16_HIGHESTA; 161e9126f55SUlrich Weigand break; 16293372b45SUlrich Weigand case MCSymbolRefExpr::VK_GOT: 16393372b45SUlrich Weigand Type = ELF::R_PPC_GOT16; 16493372b45SUlrich Weigand break; 16593372b45SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_LO: 16693372b45SUlrich Weigand Type = ELF::R_PPC_GOT16_LO; 16793372b45SUlrich Weigand break; 16893372b45SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_HI: 16993372b45SUlrich Weigand Type = ELF::R_PPC_GOT16_HI; 17093372b45SUlrich Weigand break; 17193372b45SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_HA: 17293372b45SUlrich Weigand Type = ELF::R_PPC_GOT16_HA; 17393372b45SUlrich Weigand break; 174d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC: 1753e186015SUlrich Weigand Type = ELF::R_PPC64_TOC16; 1763e186015SUlrich Weigand break; 177d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC_LO: 17834627e34SBill Schmidt Type = ELF::R_PPC64_TOC16_LO; 17934627e34SBill Schmidt break; 18072ddbd65SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC_HI: 18172ddbd65SUlrich Weigand Type = ELF::R_PPC64_TOC16_HI; 18272ddbd65SUlrich Weigand break; 183d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC_HA: 1849e90b3c8SUlrich Weigand Type = ELF::R_PPC64_TOC16_HA; 1859e90b3c8SUlrich Weigand break; 186876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL: 187876a0d01SUlrich Weigand Type = ELF::R_PPC_TPREL16; 188876a0d01SUlrich Weigand break; 189d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_LO: 1909e90b3c8SUlrich Weigand Type = ELF::R_PPC_TPREL16_LO; 1919e90b3c8SUlrich Weigand break; 192876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HI: 193876a0d01SUlrich Weigand Type = ELF::R_PPC_TPREL16_HI; 194876a0d01SUlrich Weigand break; 195d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HA: 1969e90b3c8SUlrich Weigand Type = ELF::R_PPC_TPREL16_HA; 1979e90b3c8SUlrich Weigand break; 198876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: 199876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_HIGHER; 200876a0d01SUlrich Weigand break; 201876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: 202876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_HIGHERA; 203876a0d01SUlrich Weigand break; 204876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: 205876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_HIGHEST; 206876a0d01SUlrich Weigand break; 207876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: 208876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_HIGHESTA; 209876a0d01SUlrich Weigand break; 210876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL: 211876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16; 212876a0d01SUlrich Weigand break; 213d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 2149e90b3c8SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_LO; 2159e90b3c8SUlrich Weigand break; 216876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HI: 217876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HI; 218876a0d01SUlrich Weigand break; 219d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HA: 2209e90b3c8SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HA; 2219e90b3c8SUlrich Weigand break; 222876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: 223876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HIGHER; 224876a0d01SUlrich Weigand break; 225876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: 226876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HIGHERA; 227876a0d01SUlrich Weigand break; 228876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: 229876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HIGHEST; 230876a0d01SUlrich Weigand break; 231876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: 232876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_HIGHESTA; 233876a0d01SUlrich Weigand break; 234876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: 235876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSGD16; 236876a0d01SUlrich Weigand break; 237d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: 238c56f1d34SBill Schmidt Type = ELF::R_PPC64_GOT_TLSGD16_LO; 239c56f1d34SBill Schmidt break; 240876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: 241876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSGD16_HI; 242876a0d01SUlrich Weigand break; 243d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: 2449e90b3c8SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSGD16_HA; 2459e90b3c8SUlrich Weigand break; 246876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: 247876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSLD16; 248876a0d01SUlrich Weigand break; 249d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: 25024b8dd6eSBill Schmidt Type = ELF::R_PPC64_GOT_TLSLD16_LO; 25124b8dd6eSBill Schmidt break; 252876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: 253876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSLD16_HI; 254876a0d01SUlrich Weigand break; 255d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: 2569e90b3c8SUlrich Weigand Type = ELF::R_PPC64_GOT_TLSLD16_HA; 2579e90b3c8SUlrich Weigand break; 258b2044311SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 259b2044311SUlrich Weigand /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets 260b2044311SUlrich Weigand are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */ 261b2044311SUlrich Weigand Type = ELF::R_PPC64_GOT_TPREL16_DS; 262b2044311SUlrich Weigand break; 263b2044311SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 264b2044311SUlrich Weigand /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets 265b2044311SUlrich Weigand are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */ 266b2044311SUlrich Weigand Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 267b2044311SUlrich Weigand break; 268876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: 269876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TPREL16_HI; 270876a0d01SUlrich Weigand break; 271b2044311SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 272b2044311SUlrich Weigand /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets 273b2044311SUlrich Weigand are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */ 274b2044311SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_DS; 275b2044311SUlrich Weigand break; 276b2044311SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 277b2044311SUlrich Weigand /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets 278b2044311SUlrich Weigand are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */ 279b2044311SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 280b2044311SUlrich Weigand break; 281d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: 2829e90b3c8SUlrich Weigand Type = ELF::R_PPC64_GOT_TPREL16_HA; 2839e90b3c8SUlrich Weigand break; 284876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: 285876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_HI; 286876a0d01SUlrich Weigand break; 287876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: 288876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_HA; 289876a0d01SUlrich Weigand break; 29085578500SUlrich Weigand } 29185578500SUlrich Weigand break; 2926e23ac60SUlrich Weigand case PPC::fixup_ppc_half16ds: 2933822ef2cSBill Schmidt switch (Modifier) { 2943822ef2cSBill Schmidt default: llvm_unreachable("Unsupported Modifier"); 2953822ef2cSBill Schmidt case MCSymbolRefExpr::VK_None: 2963e186015SUlrich Weigand Type = ELF::R_PPC64_ADDR16_DS; 297f2aceda8SAdhemerval Zanella break; 298d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_LO: 299e462053fSUlrich Weigand Type = ELF::R_PPC64_ADDR16_LO_DS; 300e462053fSUlrich Weigand break; 30193372b45SUlrich Weigand case MCSymbolRefExpr::VK_GOT: 30293372b45SUlrich Weigand Type = ELF::R_PPC64_GOT16_DS; 30393372b45SUlrich Weigand break; 30493372b45SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_LO: 30593372b45SUlrich Weigand Type = ELF::R_PPC64_GOT16_LO_DS; 30693372b45SUlrich Weigand break; 307d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC: 308f2aceda8SAdhemerval Zanella Type = ELF::R_PPC64_TOC16_DS; 309f2aceda8SAdhemerval Zanella break; 310d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOC_LO: 31134627e34SBill Schmidt Type = ELF::R_PPC64_TOC16_LO_DS; 31234627e34SBill Schmidt break; 313876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL: 314876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_DS; 315876a0d01SUlrich Weigand break; 316876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL_LO: 317876a0d01SUlrich Weigand Type = ELF::R_PPC64_TPREL16_LO_DS; 318876a0d01SUlrich Weigand break; 319876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL: 320876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_DS; 321876a0d01SUlrich Weigand break; 322876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 323876a0d01SUlrich Weigand Type = ELF::R_PPC64_DTPREL16_LO_DS; 324876a0d01SUlrich Weigand break; 325876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 326876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_TPREL16_DS; 327876a0d01SUlrich Weigand break; 328d51c09f5SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 3299f0b4ec0SBill Schmidt Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 330ca4a0c9dSBill Schmidt break; 331876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 332876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_DS; 333876a0d01SUlrich Weigand break; 334876a0d01SUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 335876a0d01SUlrich Weigand Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 336876a0d01SUlrich Weigand break; 33734627e34SBill Schmidt } 33834627e34SBill Schmidt break; 33924b8dd6eSBill Schmidt case PPC::fixup_ppc_nofixup: 34024b8dd6eSBill Schmidt switch (Modifier) { 34124b8dd6eSBill Schmidt default: llvm_unreachable("Unsupported Modifier"); 34252cf8e44SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TLSGD: 343c56f1d34SBill Schmidt Type = ELF::R_PPC64_TLSGD; 344c56f1d34SBill Schmidt break; 34552cf8e44SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TLSLD: 34624b8dd6eSBill Schmidt Type = ELF::R_PPC64_TLSLD; 34724b8dd6eSBill Schmidt break; 3485b427591SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TLS: 3495b427591SUlrich Weigand Type = ELF::R_PPC64_TLS; 3505b427591SUlrich Weigand break; 35124b8dd6eSBill Schmidt } 35224b8dd6eSBill Schmidt break; 353f2aceda8SAdhemerval Zanella case FK_Data_8: 354f2aceda8SAdhemerval Zanella switch (Modifier) { 355f2aceda8SAdhemerval Zanella default: llvm_unreachable("Unsupported Modifier"); 35668e2e1b3SUlrich Weigand case MCSymbolRefExpr::VK_PPC_TOCBASE: 357f2aceda8SAdhemerval Zanella Type = ELF::R_PPC64_TOC; 358f2aceda8SAdhemerval Zanella break; 359f2aceda8SAdhemerval Zanella case MCSymbolRefExpr::VK_None: 360f2aceda8SAdhemerval Zanella Type = ELF::R_PPC64_ADDR64; 361f2aceda8SAdhemerval Zanella break; 362f11efe7fSUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPMOD: 363f11efe7fSUlrich Weigand Type = ELF::R_PPC64_DTPMOD64; 364f11efe7fSUlrich Weigand break; 365f11efe7fSUlrich Weigand case MCSymbolRefExpr::VK_PPC_TPREL: 366f11efe7fSUlrich Weigand Type = ELF::R_PPC64_TPREL64; 367f11efe7fSUlrich Weigand break; 368f11efe7fSUlrich Weigand case MCSymbolRefExpr::VK_PPC_DTPREL: 369f11efe7fSUlrich Weigand Type = ELF::R_PPC64_DTPREL64; 370f11efe7fSUlrich Weigand break; 371f2aceda8SAdhemerval Zanella } 372f2aceda8SAdhemerval Zanella break; 37338a400dfSRafael Espindola case FK_Data_4: 37438a400dfSRafael Espindola Type = ELF::R_PPC_ADDR32; 37538a400dfSRafael Espindola break; 37638a400dfSRafael Espindola case FK_Data_2: 37738a400dfSRafael Espindola Type = ELF::R_PPC_ADDR16; 37838a400dfSRafael Espindola break; 37938a400dfSRafael Espindola } 38038a400dfSRafael Espindola } 38138a400dfSRafael Espindola return Type; 38238a400dfSRafael Espindola } 38338a400dfSRafael Espindola 384f2aceda8SAdhemerval Zanella unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, 385f2aceda8SAdhemerval Zanella const MCFixup &Fixup, 386f2aceda8SAdhemerval Zanella bool IsPCRel, 387f2aceda8SAdhemerval Zanella bool IsRelocWithSymbol, 388f2aceda8SAdhemerval Zanella int64_t Addend) const { 389f2aceda8SAdhemerval Zanella return getRelocTypeInner(Target, Fixup, IsPCRel); 390f2aceda8SAdhemerval Zanella } 391f2aceda8SAdhemerval Zanella 3923a75861bSUlrich Weigand const MCSymbol *PPCELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, 3933a75861bSUlrich Weigand const MCValue &Target, 3943a75861bSUlrich Weigand const MCFragment &F, 3953a75861bSUlrich Weigand const MCFixup &Fixup, 3963a75861bSUlrich Weigand bool IsPCRel) const { 3973a75861bSUlrich Weigand assert(Target.getSymA() && "SymA cannot be 0"); 3987fadc0eaSRafael Espindola MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant(); 3993a75861bSUlrich Weigand 4003a75861bSUlrich Weigand bool EmitThisSym; 4013a75861bSUlrich Weigand switch (Modifier) { 4023a75861bSUlrich Weigand // GOT references always need a relocation, even if the 4033a75861bSUlrich Weigand // target symbol is local. 4043a75861bSUlrich Weigand case MCSymbolRefExpr::VK_GOT: 4053a75861bSUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_LO: 4063a75861bSUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_HI: 4073a75861bSUlrich Weigand case MCSymbolRefExpr::VK_PPC_GOT_HA: 4083a75861bSUlrich Weigand EmitThisSym = true; 4093a75861bSUlrich Weigand break; 4103a75861bSUlrich Weigand default: 4113a75861bSUlrich Weigand EmitThisSym = false; 4123a75861bSUlrich Weigand break; 4133a75861bSUlrich Weigand } 4143a75861bSUlrich Weigand 4153a75861bSUlrich Weigand if (EmitThisSym) 4163a75861bSUlrich Weigand return &Target.getSymA()->getSymbol().AliasedSymbol(); 4173a75861bSUlrich Weigand return NULL; 4183a75861bSUlrich Weigand } 4193a75861bSUlrich Weigand 420f2aceda8SAdhemerval Zanella const MCSymbol *PPCELFObjectWriter::undefinedExplicitRelSym(const MCValue &Target, 421f2aceda8SAdhemerval Zanella const MCFixup &Fixup, 422f2aceda8SAdhemerval Zanella bool IsPCRel) const { 423f2aceda8SAdhemerval Zanella assert(Target.getSymA() && "SymA cannot be 0"); 424f2aceda8SAdhemerval Zanella const MCSymbol &Symbol = Target.getSymA()->getSymbol().AliasedSymbol(); 425f2aceda8SAdhemerval Zanella 426f2aceda8SAdhemerval Zanella unsigned RelocType = getRelocTypeInner(Target, Fixup, IsPCRel); 427f2aceda8SAdhemerval Zanella 428f2aceda8SAdhemerval Zanella // The .odp creation emits a relocation against the symbol ".TOC." which 429f2aceda8SAdhemerval Zanella // create a R_PPC64_TOC relocation. However the relocation symbol name 430f2aceda8SAdhemerval Zanella // in final object creation should be NULL, since the symbol does not 431f2aceda8SAdhemerval Zanella // really exist, it is just the reference to TOC base for the current 432f2aceda8SAdhemerval Zanella // object file. 433f2aceda8SAdhemerval Zanella bool EmitThisSym = RelocType != ELF::R_PPC64_TOC; 434f2aceda8SAdhemerval Zanella 435f2aceda8SAdhemerval Zanella if (EmitThisSym && !Symbol.isTemporary()) 436f2aceda8SAdhemerval Zanella return &Symbol; 437f2aceda8SAdhemerval Zanella return NULL; 438f2aceda8SAdhemerval Zanella } 439f2aceda8SAdhemerval Zanella 44038a400dfSRafael Espindola MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS, 44138a400dfSRafael Espindola bool Is64Bit, 442*cae3a17aSUlrich Weigand bool IsLittleEndian, 44338a400dfSRafael Espindola uint8_t OSABI) { 44438a400dfSRafael Espindola MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI); 445*cae3a17aSUlrich Weigand return createELFObjectWriter(MOTW, OS, IsLittleEndian); 44638a400dfSRafael Espindola } 447