180 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "CSKYFixupKinds.h"10#include "CSKYMCAsmInfo.h"11#include "CSKYMCTargetDesc.h"12#include "MCTargetDesc/CSKYMCAsmInfo.h"13#include "llvm/MC/MCContext.h"14#include "llvm/MC/MCELFObjectWriter.h"15#include "llvm/MC/MCObjectWriter.h"16#include "llvm/MC/MCSymbolELF.h"17 18#define DEBUG_TYPE "csky-elf-object-writer"19 20using namespace llvm;21 22namespace {23 24class CSKYELFObjectWriter : public MCELFObjectTargetWriter {25public:26 CSKYELFObjectWriter(uint8_t OSABI = 0)27 : MCELFObjectTargetWriter(false, OSABI, ELF::EM_CSKY, true){};28 ~CSKYELFObjectWriter() {}29 30 unsigned getRelocType(const MCFixup &, const MCValue &,31 bool IsPCRel) const override;32 bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override;33};34 35} // namespace36 37unsigned CSKYELFObjectWriter::getRelocType(const MCFixup &Fixup,38 const MCValue &Target,39 bool IsPCRel) const {40 const MCExpr *Expr = Fixup.getValue();41 // Determine the type of the relocation42 auto Kind = Fixup.getKind();43 uint8_t Modifier = Target.getSpecifier();44 45 switch (Target.getSpecifier()) {46 case CSKY::S_TLSIE:47 case CSKY::S_TLSLE:48 case CSKY::S_TLSGD:49 case CSKY::S_TLSLDM:50 case CSKY::S_TLSLDO:51 if (auto *SA = const_cast<MCSymbol *>(Target.getAddSym()))52 static_cast<MCSymbolELF *>(SA)->setType(ELF::STT_TLS);53 break;54 default:55 break;56 }57 58 if (IsPCRel) {59 switch (Kind) {60 default:61 LLVM_DEBUG(dbgs() << "Unknown Kind1 = " << Kind);62 reportError(Fixup.getLoc(), "Unsupported relocation type");63 return ELF::R_CKCORE_NONE;64 case FK_Data_4:65 return ELF::R_CKCORE_PCREL32;66 case CSKY::fixup_csky_pcrel_uimm16_scale4:67 return ELF::R_CKCORE_PCREL_IMM16_4;68 case CSKY::fixup_csky_pcrel_uimm8_scale4:69 return ELF::R_CKCORE_PCREL_IMM8_4;70 case CSKY::fixup_csky_pcrel_imm26_scale2:71 return ELF::R_CKCORE_PCREL_IMM26_2;72 case CSKY::fixup_csky_pcrel_imm18_scale2:73 return ELF::R_CKCORE_PCREL_IMM18_2;74 case CSKY::fixup_csky_pcrel_imm16_scale2:75 return ELF::R_CKCORE_PCREL_IMM16_2;76 case CSKY::fixup_csky_pcrel_imm10_scale2:77 return ELF::R_CKCORE_PCREL_IMM10_2;78 case CSKY::fixup_csky_pcrel_uimm7_scale4:79 return ELF::R_CKCORE_PCREL_IMM7_4;80 }81 }82 83 switch (Kind) {84 default:85 LLVM_DEBUG(dbgs() << "Unknown Kind2 = " << Kind);86 reportError(Fixup.getLoc(), "Unsupported relocation type");87 return ELF::R_CKCORE_NONE;88 case FK_Data_1:89 reportError(Fixup.getLoc(), "1-byte data relocations not supported");90 return ELF::R_CKCORE_NONE;91 case FK_Data_2:92 reportError(Fixup.getLoc(), "2-byte data relocations not supported");93 return ELF::R_CKCORE_NONE;94 case FK_Data_4:95 if (Expr->getKind() == MCExpr::Specifier) {96 auto TK = cast<MCSpecifierExpr>(Expr)->getSpecifier();97 if (TK == CSKY::S_ADDR)98 return ELF::R_CKCORE_ADDR32;99 if (TK == CSKY::S_GOT)100 return ELF::R_CKCORE_GOT32;101 if (TK == CSKY::S_GOTOFF)102 return ELF::R_CKCORE_GOTOFF;103 if (TK == CSKY::S_PLT)104 return ELF::R_CKCORE_PLT32;105 if (TK == CSKY::S_TLSIE)106 return ELF::R_CKCORE_TLS_IE32;107 if (TK == CSKY::S_TLSLE)108 return ELF::R_CKCORE_TLS_LE32;109 if (TK == CSKY::S_TLSGD)110 return ELF::R_CKCORE_TLS_GD32;111 if (TK == CSKY::S_TLSLDM)112 return ELF::R_CKCORE_TLS_LDM32;113 if (TK == CSKY::S_TLSLDO)114 return ELF::R_CKCORE_TLS_LDO32;115 if (TK == CSKY::S_GOTPC)116 return ELF::R_CKCORE_GOTPC;117 if (TK == CSKY::S_None)118 return ELF::R_CKCORE_ADDR32;119 120 LLVM_DEBUG(dbgs() << "Unknown FK_Data_4 TK = " << TK);121 reportError(Fixup.getLoc(), "unknown target FK_Data_4");122 } else {123 switch (Modifier) {124 default:125 reportError(Fixup.getLoc(), "invalid fixup for 4-byte data relocation");126 return ELF::R_CKCORE_NONE;127 case CSKY::S_GOT:128 return ELF::R_CKCORE_GOT32;129 case CSKY::S_GOTOFF:130 return ELF::R_CKCORE_GOTOFF;131 case CSKY::S_PLT:132 return ELF::R_CKCORE_PLT32;133 case CSKY::S_TLSGD:134 return ELF::R_CKCORE_TLS_GD32;135 case CSKY::S_TLSLDM:136 return ELF::R_CKCORE_TLS_LDM32;137 case CSKY::S_TPOFF:138 return ELF::R_CKCORE_TLS_LE32;139 case CSKY::S_None:140 return ELF::R_CKCORE_ADDR32;141 }142 }143 return ELF::R_CKCORE_NONE;144 case FK_Data_8:145 reportError(Fixup.getLoc(), "8-byte data relocations not supported");146 return ELF::R_CKCORE_NONE;147 case CSKY::fixup_csky_addr32:148 return ELF::R_CKCORE_ADDR32;149 case CSKY::fixup_csky_addr_hi16:150 return ELF::R_CKCORE_ADDR_HI16;151 case CSKY::fixup_csky_addr_lo16:152 return ELF::R_CKCORE_ADDR_LO16;153 case CSKY::fixup_csky_doffset_imm18:154 return ELF::R_CKCORE_DOFFSET_IMM18;155 case CSKY::fixup_csky_doffset_imm18_scale2:156 return ELF::R_CKCORE_DOFFSET_IMM18_2;157 case CSKY::fixup_csky_doffset_imm18_scale4:158 return ELF::R_CKCORE_DOFFSET_IMM18_4;159 case CSKY::fixup_csky_got_imm18_scale4:160 return ELF::R_CKCORE_GOT_IMM18_4;161 case CSKY::fixup_csky_plt_imm18_scale4:162 return ELF::R_CKCORE_PLT_IMM18_4;163 }164}165 166bool CSKYELFObjectWriter::needsRelocateWithSymbol(const MCValue &V,167 unsigned Type) const {168 switch (V.getSpecifier()) {169 case CSKY::S_PLT:170 case CSKY::S_GOT:171 return true;172 default:173 return false;174 }175}176 177std::unique_ptr<MCObjectTargetWriter> llvm::createCSKYELFObjectWriter() {178 return std::make_unique<CSKYELFObjectWriter>();179}180