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