1e8d8bef9SDimitry Andric //===-- CSKYELFObjectWriter.cpp - CSKY ELF Writer -------------------------===// 2e8d8bef9SDimitry Andric // 3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e8d8bef9SDimitry Andric // 7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 8e8d8bef9SDimitry Andric 9*81ad6265SDimitry Andric #include "CSKYFixupKinds.h" 10*81ad6265SDimitry Andric #include "CSKYMCExpr.h" 11e8d8bef9SDimitry Andric #include "CSKYMCTargetDesc.h" 12e8d8bef9SDimitry Andric #include "llvm/MC/MCContext.h" 13e8d8bef9SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h" 14e8d8bef9SDimitry Andric #include "llvm/MC/MCObjectWriter.h" 15e8d8bef9SDimitry Andric 16e8d8bef9SDimitry Andric #define DEBUG_TYPE "csky-elf-object-writer" 17e8d8bef9SDimitry Andric 18e8d8bef9SDimitry Andric using namespace llvm; 19e8d8bef9SDimitry Andric 20e8d8bef9SDimitry Andric namespace { 21e8d8bef9SDimitry Andric 22e8d8bef9SDimitry Andric class CSKYELFObjectWriter : public MCELFObjectTargetWriter { 23e8d8bef9SDimitry Andric public: 24e8d8bef9SDimitry Andric CSKYELFObjectWriter(uint8_t OSABI = 0) 25e8d8bef9SDimitry Andric : MCELFObjectTargetWriter(false, OSABI, ELF::EM_CSKY, true){}; 26e8d8bef9SDimitry Andric ~CSKYELFObjectWriter() {} 27e8d8bef9SDimitry Andric 28e8d8bef9SDimitry Andric unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 29e8d8bef9SDimitry Andric const MCFixup &Fixup, bool IsPCRel) const override; 30e8d8bef9SDimitry Andric }; 31e8d8bef9SDimitry Andric 32e8d8bef9SDimitry Andric } // namespace 33e8d8bef9SDimitry Andric 34e8d8bef9SDimitry Andric unsigned CSKYELFObjectWriter::getRelocType(MCContext &Ctx, 35e8d8bef9SDimitry Andric const MCValue &Target, 36e8d8bef9SDimitry Andric const MCFixup &Fixup, 37e8d8bef9SDimitry Andric bool IsPCRel) const { 38*81ad6265SDimitry Andric const MCExpr *Expr = Fixup.getValue(); 39*81ad6265SDimitry Andric // Determine the type of the relocation 40*81ad6265SDimitry Andric unsigned Kind = Fixup.getTargetKind(); 41*81ad6265SDimitry Andric MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); 42*81ad6265SDimitry Andric 43*81ad6265SDimitry Andric if (IsPCRel) { 44*81ad6265SDimitry Andric switch (Kind) { 45e8d8bef9SDimitry Andric default: 46*81ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Unknown Kind1 = " << Kind); 47*81ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type"); 48*81ad6265SDimitry Andric return ELF::R_CKCORE_NONE; 49*81ad6265SDimitry Andric case FK_Data_4: 50*81ad6265SDimitry Andric case FK_PCRel_4: 51*81ad6265SDimitry Andric return ELF::R_CKCORE_PCREL32; 52*81ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_uimm16_scale4: 53*81ad6265SDimitry Andric return ELF::R_CKCORE_PCREL_IMM16_4; 54*81ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_uimm8_scale4: 55*81ad6265SDimitry Andric return ELF::R_CKCORE_PCREL_IMM8_4; 56*81ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_imm26_scale2: 57*81ad6265SDimitry Andric return ELF::R_CKCORE_PCREL_IMM26_2; 58*81ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_imm18_scale2: 59*81ad6265SDimitry Andric return ELF::R_CKCORE_PCREL_IMM18_2; 60*81ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_imm16_scale2: 61*81ad6265SDimitry Andric return ELF::R_CKCORE_PCREL_IMM16_2; 62*81ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_imm10_scale2: 63*81ad6265SDimitry Andric return ELF::R_CKCORE_PCREL_IMM10_2; 64*81ad6265SDimitry Andric case CSKY::fixup_csky_pcrel_uimm7_scale4: 65*81ad6265SDimitry Andric return ELF::R_CKCORE_PCREL_IMM7_4; 66*81ad6265SDimitry Andric } 67*81ad6265SDimitry Andric } 68*81ad6265SDimitry Andric 69*81ad6265SDimitry Andric switch (Kind) { 70*81ad6265SDimitry Andric default: 71*81ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Unknown Kind2 = " << Kind); 72*81ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type"); 73*81ad6265SDimitry Andric return ELF::R_CKCORE_NONE; 74*81ad6265SDimitry Andric case FK_Data_1: 75*81ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); 76*81ad6265SDimitry Andric return ELF::R_CKCORE_NONE; 77*81ad6265SDimitry Andric case FK_Data_2: 78*81ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported"); 79*81ad6265SDimitry Andric return ELF::R_CKCORE_NONE; 80*81ad6265SDimitry Andric case FK_Data_4: 81*81ad6265SDimitry Andric if (Expr->getKind() == MCExpr::Target) { 82*81ad6265SDimitry Andric auto TK = cast<CSKYMCExpr>(Expr)->getKind(); 83*81ad6265SDimitry Andric if (TK == CSKYMCExpr::VK_CSKY_ADDR) 84*81ad6265SDimitry Andric return ELF::R_CKCORE_ADDR32; 85*81ad6265SDimitry Andric if (TK == CSKYMCExpr::VK_CSKY_GOT) 86*81ad6265SDimitry Andric return ELF::R_CKCORE_GOT32; 87*81ad6265SDimitry Andric if (TK == CSKYMCExpr::VK_CSKY_GOTOFF) 88*81ad6265SDimitry Andric return ELF::R_CKCORE_GOTOFF; 89*81ad6265SDimitry Andric if (TK == CSKYMCExpr::VK_CSKY_PLT) 90*81ad6265SDimitry Andric return ELF::R_CKCORE_PLT32; 91*81ad6265SDimitry Andric if (TK == CSKYMCExpr::VK_CSKY_TLSIE) 92*81ad6265SDimitry Andric return ELF::R_CKCORE_TLS_IE32; 93*81ad6265SDimitry Andric if (TK == CSKYMCExpr::VK_CSKY_TLSLE) 94*81ad6265SDimitry Andric return ELF::R_CKCORE_TLS_LE32; 95*81ad6265SDimitry Andric if (TK == CSKYMCExpr::VK_CSKY_TLSGD) 96*81ad6265SDimitry Andric return ELF::R_CKCORE_TLS_GD32; 97*81ad6265SDimitry Andric if (TK == CSKYMCExpr::VK_CSKY_TLSLDM) 98*81ad6265SDimitry Andric return ELF::R_CKCORE_TLS_LDM32; 99*81ad6265SDimitry Andric if (TK == CSKYMCExpr::VK_CSKY_TLSLDO) 100*81ad6265SDimitry Andric return ELF::R_CKCORE_TLS_LDO32; 101*81ad6265SDimitry Andric if (TK == CSKYMCExpr::VK_CSKY_GOTPC) 102*81ad6265SDimitry Andric return ELF::R_CKCORE_GOTPC; 103*81ad6265SDimitry Andric if (TK == CSKYMCExpr::VK_CSKY_None) 104*81ad6265SDimitry Andric return ELF::R_CKCORE_ADDR32; 105*81ad6265SDimitry Andric 106*81ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Unknown FK_Data_4 TK = " << TK); 107*81ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "unknown target FK_Data_4"); 108*81ad6265SDimitry Andric } else { 109*81ad6265SDimitry Andric switch (Modifier) { 110*81ad6265SDimitry Andric default: 111*81ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), 112*81ad6265SDimitry Andric "invalid fixup for 4-byte data relocation"); 113*81ad6265SDimitry Andric return ELF::R_CKCORE_NONE; 114*81ad6265SDimitry Andric case MCSymbolRefExpr::VK_GOT: 115*81ad6265SDimitry Andric return ELF::R_CKCORE_GOT32; 116*81ad6265SDimitry Andric case MCSymbolRefExpr::VK_GOTOFF: 117*81ad6265SDimitry Andric return ELF::R_CKCORE_GOTOFF; 118*81ad6265SDimitry Andric case MCSymbolRefExpr::VK_PLT: 119*81ad6265SDimitry Andric return ELF::R_CKCORE_PLT32; 120*81ad6265SDimitry Andric case MCSymbolRefExpr::VK_None: 121*81ad6265SDimitry Andric return ELF::R_CKCORE_ADDR32; 122*81ad6265SDimitry Andric } 123*81ad6265SDimitry Andric } 124*81ad6265SDimitry Andric return ELF::R_CKCORE_NONE; 125*81ad6265SDimitry Andric case FK_Data_8: 126*81ad6265SDimitry Andric Ctx.reportError(Fixup.getLoc(), "8-byte data relocations not supported"); 127*81ad6265SDimitry Andric return ELF::R_CKCORE_NONE; 128*81ad6265SDimitry Andric case CSKY::fixup_csky_addr32: 129*81ad6265SDimitry Andric return ELF::R_CKCORE_ADDR32; 130*81ad6265SDimitry Andric case CSKY::fixup_csky_addr_hi16: 131*81ad6265SDimitry Andric return ELF::R_CKCORE_ADDR_HI16; 132*81ad6265SDimitry Andric case CSKY::fixup_csky_addr_lo16: 133*81ad6265SDimitry Andric return ELF::R_CKCORE_ADDR_LO16; 134*81ad6265SDimitry Andric case CSKY::fixup_csky_doffset_imm18: 135*81ad6265SDimitry Andric return ELF::R_CKCORE_DOFFSET_IMM18; 136*81ad6265SDimitry Andric case CSKY::fixup_csky_doffset_imm18_scale2: 137*81ad6265SDimitry Andric return ELF::R_CKCORE_DOFFSET_IMM18_2; 138*81ad6265SDimitry Andric case CSKY::fixup_csky_doffset_imm18_scale4: 139*81ad6265SDimitry Andric return ELF::R_CKCORE_DOFFSET_IMM18_4; 140*81ad6265SDimitry Andric case CSKY::fixup_csky_got_imm18_scale4: 141*81ad6265SDimitry Andric return ELF::R_CKCORE_GOT_IMM18_4; 142*81ad6265SDimitry Andric case CSKY::fixup_csky_plt_imm18_scale4: 143*81ad6265SDimitry Andric return ELF::R_CKCORE_PLT_IMM18_4; 144e8d8bef9SDimitry Andric } 145e8d8bef9SDimitry Andric } 146e8d8bef9SDimitry Andric 147e8d8bef9SDimitry Andric std::unique_ptr<MCObjectTargetWriter> llvm::createCSKYELFObjectWriter() { 148e8d8bef9SDimitry Andric return std::make_unique<CSKYELFObjectWriter>(); 149e8d8bef9SDimitry Andric } 150