xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "MCTargetDesc/PPCFixupKinds.h"
100b57cec5SDimitry Andric #include "MCTargetDesc/PPCMCExpr.h"
110b57cec5SDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h"
120b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
130b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCValue.h"
180b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric using namespace llvm;
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric namespace {
230b57cec5SDimitry Andric   class PPCELFObjectWriter : public MCELFObjectTargetWriter {
240b57cec5SDimitry Andric   public:
250b57cec5SDimitry Andric     PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric   protected:
280b57cec5SDimitry Andric     unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
290b57cec5SDimitry Andric                           const MCFixup &Fixup, bool IsPCRel) const override;
300b57cec5SDimitry Andric 
31*5f757f3fSDimitry Andric     bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
320b57cec5SDimitry Andric                                  unsigned Type) const override;
330b57cec5SDimitry Andric   };
340b57cec5SDimitry Andric }
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
370b57cec5SDimitry Andric   : MCELFObjectTargetWriter(Is64Bit, OSABI,
380b57cec5SDimitry Andric                             Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
390b57cec5SDimitry Andric                             /*HasRelocationAddend*/ true) {}
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
420b57cec5SDimitry Andric                                                      const MCFixup &Fixup) {
430b57cec5SDimitry Andric   const MCExpr *Expr = Fixup.getValue();
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric   if (Expr->getKind() != MCExpr::Target)
460b57cec5SDimitry Andric     return Target.getAccessVariant();
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   switch (cast<PPCMCExpr>(Expr)->getKind()) {
490b57cec5SDimitry Andric   case PPCMCExpr::VK_PPC_None:
500b57cec5SDimitry Andric     return MCSymbolRefExpr::VK_None;
510b57cec5SDimitry Andric   case PPCMCExpr::VK_PPC_LO:
520b57cec5SDimitry Andric     return MCSymbolRefExpr::VK_PPC_LO;
530b57cec5SDimitry Andric   case PPCMCExpr::VK_PPC_HI:
540b57cec5SDimitry Andric     return MCSymbolRefExpr::VK_PPC_HI;
550b57cec5SDimitry Andric   case PPCMCExpr::VK_PPC_HA:
560b57cec5SDimitry Andric     return MCSymbolRefExpr::VK_PPC_HA;
570b57cec5SDimitry Andric   case PPCMCExpr::VK_PPC_HIGH:
580b57cec5SDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGH;
590b57cec5SDimitry Andric   case PPCMCExpr::VK_PPC_HIGHA:
600b57cec5SDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGHA;
610b57cec5SDimitry Andric   case PPCMCExpr::VK_PPC_HIGHERA:
620b57cec5SDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGHERA;
630b57cec5SDimitry Andric   case PPCMCExpr::VK_PPC_HIGHER:
640b57cec5SDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGHER;
650b57cec5SDimitry Andric   case PPCMCExpr::VK_PPC_HIGHEST:
660b57cec5SDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGHEST;
670b57cec5SDimitry Andric   case PPCMCExpr::VK_PPC_HIGHESTA:
680b57cec5SDimitry Andric     return MCSymbolRefExpr::VK_PPC_HIGHESTA;
690b57cec5SDimitry Andric   }
700b57cec5SDimitry Andric   llvm_unreachable("unknown PPCMCExpr kind");
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
740b57cec5SDimitry Andric                                           const MCFixup &Fixup,
750b57cec5SDimitry Andric                                           bool IsPCRel) const {
765ffd83dbSDimitry Andric   MCFixupKind Kind = Fixup.getKind();
775ffd83dbSDimitry Andric   if (Kind >= FirstLiteralRelocationKind)
785ffd83dbSDimitry Andric     return Kind - FirstLiteralRelocationKind;
790b57cec5SDimitry Andric   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   // determine the type of the relocation
820b57cec5SDimitry Andric   unsigned Type;
830b57cec5SDimitry Andric   if (IsPCRel) {
848bcb0991SDimitry Andric     switch (Fixup.getTargetKind()) {
850b57cec5SDimitry Andric     default:
860b57cec5SDimitry Andric       llvm_unreachable("Unimplemented");
870b57cec5SDimitry Andric     case PPC::fixup_ppc_br24:
880b57cec5SDimitry Andric     case PPC::fixup_ppc_br24abs:
895ffd83dbSDimitry Andric     case PPC::fixup_ppc_br24_notoc:
900b57cec5SDimitry Andric       switch (Modifier) {
910b57cec5SDimitry Andric       default: llvm_unreachable("Unsupported Modifier");
920b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_None:
930b57cec5SDimitry Andric         Type = ELF::R_PPC_REL24;
940b57cec5SDimitry Andric         break;
950b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PLT:
960b57cec5SDimitry Andric         Type = ELF::R_PPC_PLTREL24;
970b57cec5SDimitry Andric         break;
980b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_LOCAL:
990b57cec5SDimitry Andric         Type = ELF::R_PPC_LOCAL24PC;
1000b57cec5SDimitry Andric         break;
1015ffd83dbSDimitry Andric       case MCSymbolRefExpr::VK_PPC_NOTOC:
1025ffd83dbSDimitry Andric         Type = ELF::R_PPC64_REL24_NOTOC;
1035ffd83dbSDimitry Andric         break;
1040b57cec5SDimitry Andric       }
1050b57cec5SDimitry Andric       break;
1060b57cec5SDimitry Andric     case PPC::fixup_ppc_brcond14:
1070b57cec5SDimitry Andric     case PPC::fixup_ppc_brcond14abs:
1080b57cec5SDimitry Andric       Type = ELF::R_PPC_REL14;
1090b57cec5SDimitry Andric       break;
1100b57cec5SDimitry Andric     case PPC::fixup_ppc_half16:
1110b57cec5SDimitry Andric       switch (Modifier) {
1120b57cec5SDimitry Andric       default: llvm_unreachable("Unsupported Modifier");
1130b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_None:
1140b57cec5SDimitry Andric         Type = ELF::R_PPC_REL16;
1150b57cec5SDimitry Andric         break;
1160b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_LO:
1170b57cec5SDimitry Andric         Type = ELF::R_PPC_REL16_LO;
1180b57cec5SDimitry Andric         break;
1190b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HI:
1200b57cec5SDimitry Andric         Type = ELF::R_PPC_REL16_HI;
1210b57cec5SDimitry Andric         break;
1220b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HA:
1230b57cec5SDimitry Andric         Type = ELF::R_PPC_REL16_HA;
1240b57cec5SDimitry Andric         break;
1250b57cec5SDimitry Andric       }
1260b57cec5SDimitry Andric       break;
1270b57cec5SDimitry Andric     case PPC::fixup_ppc_half16ds:
1283a9a9c0cSDimitry Andric     case PPC::fixup_ppc_half16dq:
1290b57cec5SDimitry Andric       Target.print(errs());
1300b57cec5SDimitry Andric       errs() << '\n';
1310b57cec5SDimitry Andric       report_fatal_error("Invalid PC-relative half16ds relocation");
1325ffd83dbSDimitry Andric     case PPC::fixup_ppc_pcrel34:
1335ffd83dbSDimitry Andric       switch (Modifier) {
1345ffd83dbSDimitry Andric       default:
1355ffd83dbSDimitry Andric         llvm_unreachable("Unsupported Modifier for fixup_ppc_pcrel34");
1365ffd83dbSDimitry Andric       case MCSymbolRefExpr::VK_PCREL:
1375ffd83dbSDimitry Andric         Type = ELF::R_PPC64_PCREL34;
1385ffd83dbSDimitry Andric         break;
1395ffd83dbSDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_PCREL:
1405ffd83dbSDimitry Andric         Type = ELF::R_PPC64_GOT_PCREL34;
1415ffd83dbSDimitry Andric         break;
142e8d8bef9SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL:
143e8d8bef9SDimitry Andric         Type = ELF::R_PPC64_GOT_TLSGD_PCREL34;
144e8d8bef9SDimitry Andric         break;
145e8d8bef9SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL:
146e8d8bef9SDimitry Andric         Type = ELF::R_PPC64_GOT_TLSLD_PCREL34;
147e8d8bef9SDimitry Andric         break;
148e8d8bef9SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL:
149e8d8bef9SDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL_PCREL34;
150e8d8bef9SDimitry Andric         break;
1515ffd83dbSDimitry Andric       }
1525ffd83dbSDimitry Andric       break;
1530b57cec5SDimitry Andric     case FK_Data_4:
1540b57cec5SDimitry Andric     case FK_PCRel_4:
1550b57cec5SDimitry Andric       Type = ELF::R_PPC_REL32;
1560b57cec5SDimitry Andric       break;
1570b57cec5SDimitry Andric     case FK_Data_8:
1580b57cec5SDimitry Andric     case FK_PCRel_8:
1590b57cec5SDimitry Andric       Type = ELF::R_PPC64_REL64;
1600b57cec5SDimitry Andric       break;
1610b57cec5SDimitry Andric     }
1620b57cec5SDimitry Andric   } else {
1638bcb0991SDimitry Andric     switch (Fixup.getTargetKind()) {
1640b57cec5SDimitry Andric       default: llvm_unreachable("invalid fixup kind!");
1650b57cec5SDimitry Andric     case PPC::fixup_ppc_br24abs:
1660b57cec5SDimitry Andric       Type = ELF::R_PPC_ADDR24;
1670b57cec5SDimitry Andric       break;
1680b57cec5SDimitry Andric     case PPC::fixup_ppc_brcond14abs:
1690b57cec5SDimitry Andric       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
1700b57cec5SDimitry Andric       break;
1710b57cec5SDimitry Andric     case PPC::fixup_ppc_half16:
1720b57cec5SDimitry Andric       switch (Modifier) {
1730b57cec5SDimitry Andric       default: llvm_unreachable("Unsupported Modifier");
1740b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_None:
1750b57cec5SDimitry Andric         Type = ELF::R_PPC_ADDR16;
1760b57cec5SDimitry Andric         break;
1770b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_LO:
1780b57cec5SDimitry Andric         Type = ELF::R_PPC_ADDR16_LO;
1790b57cec5SDimitry Andric         break;
1800b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HI:
1810b57cec5SDimitry Andric         Type = ELF::R_PPC_ADDR16_HI;
1820b57cec5SDimitry Andric         break;
1830b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HA:
1840b57cec5SDimitry Andric         Type = ELF::R_PPC_ADDR16_HA;
1850b57cec5SDimitry Andric         break;
1860b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGH:
1870b57cec5SDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGH;
1880b57cec5SDimitry Andric         break;
1890b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGHA:
1900b57cec5SDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGHA;
1910b57cec5SDimitry Andric         break;
1920b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGHER:
1930b57cec5SDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGHER;
1940b57cec5SDimitry Andric         break;
1950b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGHERA:
1960b57cec5SDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGHERA;
1970b57cec5SDimitry Andric         break;
1980b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGHEST:
1990b57cec5SDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGHEST;
2000b57cec5SDimitry Andric         break;
2010b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
2020b57cec5SDimitry Andric         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
2030b57cec5SDimitry Andric         break;
2040b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_GOT:
2050b57cec5SDimitry Andric         Type = ELF::R_PPC_GOT16;
2060b57cec5SDimitry Andric         break;
2070b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_LO:
2080b57cec5SDimitry Andric         Type = ELF::R_PPC_GOT16_LO;
2090b57cec5SDimitry Andric         break;
2100b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_HI:
2110b57cec5SDimitry Andric         Type = ELF::R_PPC_GOT16_HI;
2120b57cec5SDimitry Andric         break;
2130b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_HA:
2140b57cec5SDimitry Andric         Type = ELF::R_PPC_GOT16_HA;
2150b57cec5SDimitry Andric         break;
2160b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC:
2170b57cec5SDimitry Andric         Type = ELF::R_PPC64_TOC16;
2180b57cec5SDimitry Andric         break;
2190b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC_LO:
2200b57cec5SDimitry Andric         Type = ELF::R_PPC64_TOC16_LO;
2210b57cec5SDimitry Andric         break;
2220b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC_HI:
2230b57cec5SDimitry Andric         Type = ELF::R_PPC64_TOC16_HI;
2240b57cec5SDimitry Andric         break;
2250b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC_HA:
2260b57cec5SDimitry Andric         Type = ELF::R_PPC64_TOC16_HA;
2270b57cec5SDimitry Andric         break;
2280b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_TPREL:
2290b57cec5SDimitry Andric         Type = ELF::R_PPC_TPREL16;
2300b57cec5SDimitry Andric         break;
2310b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
2320b57cec5SDimitry Andric         Type = ELF::R_PPC_TPREL16_LO;
2330b57cec5SDimitry Andric         break;
2340b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
2350b57cec5SDimitry Andric         Type = ELF::R_PPC_TPREL16_HI;
2360b57cec5SDimitry Andric         break;
2370b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
2380b57cec5SDimitry Andric         Type = ELF::R_PPC_TPREL16_HA;
2390b57cec5SDimitry Andric         break;
2400b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGH:
2410b57cec5SDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGH;
2420b57cec5SDimitry Andric         break;
2430b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA:
2440b57cec5SDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGHA;
2450b57cec5SDimitry Andric         break;
2460b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
2470b57cec5SDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGHER;
2480b57cec5SDimitry Andric         break;
2490b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
2500b57cec5SDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGHERA;
2510b57cec5SDimitry Andric         break;
2520b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
2530b57cec5SDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGHEST;
2540b57cec5SDimitry Andric         break;
2550b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
2560b57cec5SDimitry Andric         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
2570b57cec5SDimitry Andric         break;
2580b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_DTPREL:
2590b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16;
2600b57cec5SDimitry Andric         break;
2610b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
2620b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_LO;
2630b57cec5SDimitry Andric         break;
2640b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
2650b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HI;
2660b57cec5SDimitry Andric         break;
2670b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
2680b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HA;
2690b57cec5SDimitry Andric         break;
2700b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH:
2710b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGH;
2720b57cec5SDimitry Andric         break;
2730b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA:
2740b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGHA;
2750b57cec5SDimitry Andric         break;
2760b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
2770b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGHER;
2780b57cec5SDimitry Andric         break;
2790b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
2800b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
2810b57cec5SDimitry Andric         break;
2820b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
2830b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
2840b57cec5SDimitry Andric         break;
2850b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
2860b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
2870b57cec5SDimitry Andric         break;
2880b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
2890b57cec5SDimitry Andric         if (is64Bit())
2900b57cec5SDimitry Andric           Type = ELF::R_PPC64_GOT_TLSGD16;
2910b57cec5SDimitry Andric         else
2920b57cec5SDimitry Andric           Type = ELF::R_PPC_GOT_TLSGD16;
2930b57cec5SDimitry Andric         break;
2940b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
2950b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
2960b57cec5SDimitry Andric         break;
2970b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
2980b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
2990b57cec5SDimitry Andric         break;
3000b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
3010b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
3020b57cec5SDimitry Andric         break;
3030b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
3040b57cec5SDimitry Andric         if (is64Bit())
3050b57cec5SDimitry Andric           Type = ELF::R_PPC64_GOT_TLSLD16;
3060b57cec5SDimitry Andric         else
3070b57cec5SDimitry Andric           Type = ELF::R_PPC_GOT_TLSLD16;
3080b57cec5SDimitry Andric         break;
3090b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
3100b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
3110b57cec5SDimitry Andric         break;
3120b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
3130b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
3140b57cec5SDimitry Andric         break;
3150b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
3160b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
3170b57cec5SDimitry Andric         break;
3180b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
3190b57cec5SDimitry Andric         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
3200b57cec5SDimitry Andric            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
3210b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_DS;
3220b57cec5SDimitry Andric         break;
3230b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
3240b57cec5SDimitry Andric         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
3250b57cec5SDimitry Andric            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
3260b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
3270b57cec5SDimitry Andric         break;
3280b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
3290b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_HI;
3300b57cec5SDimitry Andric         break;
3310b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
3320b57cec5SDimitry Andric         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
3330b57cec5SDimitry Andric            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
3340b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
3350b57cec5SDimitry Andric         break;
3360b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
3370b57cec5SDimitry Andric         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
3380b57cec5SDimitry Andric            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
3390b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
3400b57cec5SDimitry Andric         break;
3410b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
3420b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_HA;
3430b57cec5SDimitry Andric         break;
3440b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
3450b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
3460b57cec5SDimitry Andric         break;
3470b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
3480b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
3490b57cec5SDimitry Andric         break;
3500b57cec5SDimitry Andric       }
3510b57cec5SDimitry Andric       break;
3520b57cec5SDimitry Andric     case PPC::fixup_ppc_half16ds:
3533a9a9c0cSDimitry Andric     case PPC::fixup_ppc_half16dq:
3540b57cec5SDimitry Andric       switch (Modifier) {
3550b57cec5SDimitry Andric       default: llvm_unreachable("Unsupported Modifier");
3560b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_None:
3570b57cec5SDimitry Andric         Type = ELF::R_PPC64_ADDR16_DS;
3580b57cec5SDimitry Andric         break;
3590b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_LO:
3600b57cec5SDimitry Andric         Type = ELF::R_PPC64_ADDR16_LO_DS;
3610b57cec5SDimitry Andric         break;
3620b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_GOT:
3630b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT16_DS;
3640b57cec5SDimitry Andric         break;
3650b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_LO:
3660b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT16_LO_DS;
3670b57cec5SDimitry Andric         break;
3680b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC:
3690b57cec5SDimitry Andric         Type = ELF::R_PPC64_TOC16_DS;
3700b57cec5SDimitry Andric         break;
3710b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOC_LO:
3720b57cec5SDimitry Andric         Type = ELF::R_PPC64_TOC16_LO_DS;
3730b57cec5SDimitry Andric         break;
3740b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_TPREL:
3750b57cec5SDimitry Andric         Type = ELF::R_PPC64_TPREL16_DS;
3760b57cec5SDimitry Andric         break;
3770b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
3780b57cec5SDimitry Andric         Type = ELF::R_PPC64_TPREL16_LO_DS;
3790b57cec5SDimitry Andric         break;
3800b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_DTPREL:
3810b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_DS;
3820b57cec5SDimitry Andric         break;
3830b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
3840b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL16_LO_DS;
3850b57cec5SDimitry Andric         break;
3860b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
3870b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_DS;
3880b57cec5SDimitry Andric         break;
3890b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
3900b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
3910b57cec5SDimitry Andric         break;
3920b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
3930b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
3940b57cec5SDimitry Andric         break;
3950b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
3960b57cec5SDimitry Andric         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
3970b57cec5SDimitry Andric         break;
3980b57cec5SDimitry Andric       }
3990b57cec5SDimitry Andric       break;
4000b57cec5SDimitry Andric     case PPC::fixup_ppc_nofixup:
4010b57cec5SDimitry Andric       switch (Modifier) {
4020b57cec5SDimitry Andric       default: llvm_unreachable("Unsupported Modifier");
4030b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TLSGD:
4040b57cec5SDimitry Andric         if (is64Bit())
4050b57cec5SDimitry Andric           Type = ELF::R_PPC64_TLSGD;
4060b57cec5SDimitry Andric         else
4070b57cec5SDimitry Andric           Type = ELF::R_PPC_TLSGD;
4080b57cec5SDimitry Andric         break;
4090b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TLSLD:
4100b57cec5SDimitry Andric         if (is64Bit())
4110b57cec5SDimitry Andric           Type = ELF::R_PPC64_TLSLD;
4120b57cec5SDimitry Andric         else
4130b57cec5SDimitry Andric           Type = ELF::R_PPC_TLSLD;
4140b57cec5SDimitry Andric         break;
4150b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TLS:
4160b57cec5SDimitry Andric         if (is64Bit())
4170b57cec5SDimitry Andric           Type = ELF::R_PPC64_TLS;
4180b57cec5SDimitry Andric         else
4190b57cec5SDimitry Andric           Type = ELF::R_PPC_TLS;
4200b57cec5SDimitry Andric         break;
421e8d8bef9SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TLS_PCREL:
422e8d8bef9SDimitry Andric         Type = ELF::R_PPC64_TLS;
423e8d8bef9SDimitry Andric         break;
424e8d8bef9SDimitry Andric       }
425e8d8bef9SDimitry Andric       break;
426e8d8bef9SDimitry Andric     case PPC::fixup_ppc_imm34:
427e8d8bef9SDimitry Andric       switch (Modifier) {
428e8d8bef9SDimitry Andric       default:
429e8d8bef9SDimitry Andric         report_fatal_error("Unsupported Modifier for fixup_ppc_imm34.");
430e8d8bef9SDimitry Andric       case MCSymbolRefExpr::VK_DTPREL:
431e8d8bef9SDimitry Andric         Type = ELF::R_PPC64_DTPREL34;
432e8d8bef9SDimitry Andric         break;
433e8d8bef9SDimitry Andric       case MCSymbolRefExpr::VK_TPREL:
434e8d8bef9SDimitry Andric         Type = ELF::R_PPC64_TPREL34;
435e8d8bef9SDimitry Andric         break;
4360b57cec5SDimitry Andric       }
4370b57cec5SDimitry Andric       break;
4380b57cec5SDimitry Andric     case FK_Data_8:
4390b57cec5SDimitry Andric       switch (Modifier) {
4400b57cec5SDimitry Andric       default: llvm_unreachable("Unsupported Modifier");
4410b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_TOCBASE:
4420b57cec5SDimitry Andric         Type = ELF::R_PPC64_TOC;
4430b57cec5SDimitry Andric         break;
4440b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_None:
4450b57cec5SDimitry Andric         Type = ELF::R_PPC64_ADDR64;
4460b57cec5SDimitry Andric         break;
4470b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_PPC_DTPMOD:
4480b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPMOD64;
4490b57cec5SDimitry Andric         break;
4500b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_TPREL:
4510b57cec5SDimitry Andric         Type = ELF::R_PPC64_TPREL64;
4520b57cec5SDimitry Andric         break;
4530b57cec5SDimitry Andric       case MCSymbolRefExpr::VK_DTPREL:
4540b57cec5SDimitry Andric         Type = ELF::R_PPC64_DTPREL64;
4550b57cec5SDimitry Andric         break;
4560b57cec5SDimitry Andric       }
4570b57cec5SDimitry Andric       break;
4580b57cec5SDimitry Andric     case FK_Data_4:
459*5f757f3fSDimitry Andric       switch (Modifier) {
460*5f757f3fSDimitry Andric       case MCSymbolRefExpr::VK_DTPREL:
461*5f757f3fSDimitry Andric         Type = ELF::R_PPC_DTPREL32;
462*5f757f3fSDimitry Andric         break;
463*5f757f3fSDimitry Andric       default:
4640b57cec5SDimitry Andric         Type = ELF::R_PPC_ADDR32;
465*5f757f3fSDimitry Andric       }
4660b57cec5SDimitry Andric       break;
4670b57cec5SDimitry Andric     case FK_Data_2:
4680b57cec5SDimitry Andric       Type = ELF::R_PPC_ADDR16;
4690b57cec5SDimitry Andric       break;
4700b57cec5SDimitry Andric     }
4710b57cec5SDimitry Andric   }
4720b57cec5SDimitry Andric   return Type;
4730b57cec5SDimitry Andric }
4740b57cec5SDimitry Andric 
475*5f757f3fSDimitry Andric bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCValue &,
476*5f757f3fSDimitry Andric                                                  const MCSymbol &Sym,
4770b57cec5SDimitry Andric                                                  unsigned Type) const {
4780b57cec5SDimitry Andric   switch (Type) {
4790b57cec5SDimitry Andric     default:
4800b57cec5SDimitry Andric       return false;
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric     case ELF::R_PPC_REL24:
4835ffd83dbSDimitry Andric     case ELF::R_PPC64_REL24_NOTOC:
4840b57cec5SDimitry Andric       // If the target symbol has a local entry point, we must keep the
4850b57cec5SDimitry Andric       // target symbol to preserve that information for the linker.
4860b57cec5SDimitry Andric       // The "other" values are stored in the last 6 bits of the second byte.
4870b57cec5SDimitry Andric       // The traditional defines for STO values assume the full byte and thus
4880b57cec5SDimitry Andric       // the shift to pack it.
4890b57cec5SDimitry Andric       unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2;
4900b57cec5SDimitry Andric       return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
4910b57cec5SDimitry Andric   }
4920b57cec5SDimitry Andric }
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter>
4950b57cec5SDimitry Andric llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
4968bcb0991SDimitry Andric   return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI);
4970b57cec5SDimitry Andric }
498