brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · c702064 Raw
168 lines · cpp
1//===-- VEELFObjectWriter.cpp - VE 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 "MCTargetDesc/VEMCAsmInfo.h"10#include "VEFixupKinds.h"11#include "VEMCAsmInfo.h"12#include "VEMCTargetDesc.h"13#include "llvm/MC/MCContext.h"14#include "llvm/MC/MCELFObjectWriter.h"15#include "llvm/MC/MCExpr.h"16#include "llvm/MC/MCObjectWriter.h"17#include "llvm/MC/MCValue.h"18#include "llvm/Support/ErrorHandling.h"19 20using namespace llvm;21 22namespace {23class VEELFObjectWriter : public MCELFObjectTargetWriter {24public:25  VEELFObjectWriter(uint8_t OSABI)26      : MCELFObjectTargetWriter(/* Is64Bit */ true, OSABI, ELF::EM_VE,27                                /* HasRelocationAddend */ true) {}28 29  ~VEELFObjectWriter() override = default;30 31protected:32  unsigned getRelocType(const MCFixup &, const MCValue &,33                        bool IsPCRel) const override;34 35  bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override;36};37} // namespace38 39unsigned VEELFObjectWriter::getRelocType(const MCFixup &Fixup,40                                         const MCValue &Target,41                                         bool IsPCRel) const {42  switch (Target.getSpecifier()) {43  case VE::S_TLS_GD_HI32:44  case VE::S_TLS_GD_LO32:45  case VE::S_TPOFF_HI32:46  case VE::S_TPOFF_LO32:47    if (auto *SA = const_cast<MCSymbol *>(Target.getAddSym()))48      static_cast<MCSymbolELF *>(SA)->setType(ELF::STT_TLS);49    break;50  default:51    break;52  }53  if (auto *SExpr = dyn_cast<MCSpecifierExpr>(Fixup.getValue())) {54    if (SExpr->getSpecifier() == VE::S_PC_LO32)55      return ELF::R_VE_PC_LO32;56  }57 58  if (IsPCRel) {59    switch (Fixup.getKind()) {60    default:61      reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind");62      return ELF::R_VE_NONE;63    case FK_Data_1:64      reportError(Fixup.getLoc(),65                  "1-byte pc-relative data relocation is not supported");66      return ELF::R_VE_NONE;67    case FK_Data_2:68      reportError(Fixup.getLoc(),69                  "2-byte pc-relative data relocation is not supported");70      return ELF::R_VE_NONE;71    case FK_Data_4:72      return ELF::R_VE_SREL32;73    case FK_Data_8:74      reportError(Fixup.getLoc(),75                  "8-byte pc-relative data relocation is not supported");76      return ELF::R_VE_NONE;77    case VE::fixup_ve_reflong:78    case VE::fixup_ve_srel32:79      return ELF::R_VE_SREL32;80    case VE::fixup_ve_pc_hi32:81      return ELF::R_VE_PC_HI32;82    case VE::fixup_ve_pc_lo32:83      return ELF::R_VE_PC_LO32;84    }85  }86 87  switch (Fixup.getKind()) {88  default:89    reportError(Fixup.getLoc(), "Unknown ELF relocation type");90    return ELF::R_VE_NONE;91  case FK_Data_1:92    reportError(Fixup.getLoc(), "1-byte data relocation is not supported");93    return ELF::R_VE_NONE;94  case FK_Data_2:95    reportError(Fixup.getLoc(), "2-byte data relocation is not supported");96    return ELF::R_VE_NONE;97  case FK_Data_4:98    return ELF::R_VE_REFLONG;99  case FK_Data_8:100    return ELF::R_VE_REFQUAD;101  case VE::fixup_ve_reflong:102    return ELF::R_VE_REFLONG;103  case VE::fixup_ve_srel32:104    reportError(Fixup.getLoc(),105                "A non pc-relative srel32 relocation is not supported");106    return ELF::R_VE_NONE;107  case VE::fixup_ve_hi32:108    return ELF::R_VE_HI32;109  case VE::fixup_ve_lo32:110    return ELF::R_VE_LO32;111  case VE::fixup_ve_pc_hi32:112    reportError(Fixup.getLoc(),113                "A non pc-relative pc_hi32 relocation is not supported");114    return ELF::R_VE_NONE;115  case VE::fixup_ve_pc_lo32:116    reportError(Fixup.getLoc(),117                "A non pc-relative pc_lo32 relocation is not supported");118    return ELF::R_VE_NONE;119  case VE::fixup_ve_got_hi32:120    return ELF::R_VE_GOT_HI32;121  case VE::fixup_ve_got_lo32:122    return ELF::R_VE_GOT_LO32;123  case VE::fixup_ve_gotoff_hi32:124    return ELF::R_VE_GOTOFF_HI32;125  case VE::fixup_ve_gotoff_lo32:126    return ELF::R_VE_GOTOFF_LO32;127  case VE::fixup_ve_plt_hi32:128    return ELF::R_VE_PLT_HI32;129  case VE::fixup_ve_plt_lo32:130    return ELF::R_VE_PLT_LO32;131  case VE::fixup_ve_tls_gd_hi32:132    return ELF::R_VE_TLS_GD_HI32;133  case VE::fixup_ve_tls_gd_lo32:134    return ELF::R_VE_TLS_GD_LO32;135  case VE::fixup_ve_tpoff_hi32:136    return ELF::R_VE_TPOFF_HI32;137  case VE::fixup_ve_tpoff_lo32:138    return ELF::R_VE_TPOFF_LO32;139  }140 141  return ELF::R_VE_NONE;142}143 144bool VEELFObjectWriter::needsRelocateWithSymbol(const MCValue &,145                                                unsigned Type) const {146  switch (Type) {147  default:148    return false;149 150  // All relocations that use a GOT need a symbol, not an offset, as151  // the offset of the symbol within the section is irrelevant to152  // where the GOT entry is. Don't need to list all the TLS entries,153  // as they're all marked as requiring a symbol anyways.154  case ELF::R_VE_GOT_HI32:155  case ELF::R_VE_GOT_LO32:156  case ELF::R_VE_GOTOFF_HI32:157  case ELF::R_VE_GOTOFF_LO32:158  case ELF::R_VE_TLS_GD_HI32:159  case ELF::R_VE_TLS_GD_LO32:160    return true;161  }162}163 164std::unique_ptr<MCObjectTargetWriter>165llvm::createVEELFObjectWriter(uint8_t OSABI) {166  return std::make_unique<VEELFObjectWriter>(OSABI);167}168