brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 4667975 Raw
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