brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · d2071c3 Raw
144 lines · cpp
1//===-- SparcELFObjectWriter.cpp - Sparc 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/SparcFixupKinds.h"10#include "MCTargetDesc/SparcMCTargetDesc.h"11#include "llvm/MC/MCContext.h"12#include "llvm/MC/MCELFObjectWriter.h"13#include "llvm/MC/MCExpr.h"14#include "llvm/MC/MCObjectFileInfo.h"15#include "llvm/MC/MCObjectWriter.h"16#include "llvm/MC/MCValue.h"17#include "llvm/Support/ErrorHandling.h"18 19using namespace llvm;20 21namespace {22  class SparcELFObjectWriter : public MCELFObjectTargetWriter {23  public:24    SparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI)25        : MCELFObjectTargetWriter(26              Is64Bit, OSABI,27              Is64Bit ? ELF::EM_SPARCV928                      : (IsV8Plus ? ELF::EM_SPARC32PLUS : ELF::EM_SPARC),29              /*HasRelocationAddend*/ true) {}30 31    ~SparcELFObjectWriter() override = default;32 33  protected:34    unsigned getRelocType(const MCFixup &Fixup, const MCValue &Target,35                          bool IsPCRel) const override;36 37    bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override;38  };39}40 41unsigned SparcELFObjectWriter::getRelocType(const MCFixup &Fixup,42                                            const MCValue &Target,43                                            bool IsPCRel) const {44  switch (Target.getSpecifier()) {45  case ELF::R_SPARC_TLS_GD_HI22:46  case ELF::R_SPARC_TLS_GD_LO10:47  case ELF::R_SPARC_TLS_GD_ADD:48  case ELF::R_SPARC_TLS_LDM_HI22:49  case ELF::R_SPARC_TLS_LDM_LO10:50  case ELF::R_SPARC_TLS_LDM_ADD:51  case ELF::R_SPARC_TLS_LDO_HIX22:52  case ELF::R_SPARC_TLS_LDO_LOX10:53  case ELF::R_SPARC_TLS_LDO_ADD:54  case ELF::R_SPARC_TLS_IE_HI22:55  case ELF::R_SPARC_TLS_IE_LO10:56  case ELF::R_SPARC_TLS_IE_LD:57  case ELF::R_SPARC_TLS_IE_LDX:58  case ELF::R_SPARC_TLS_IE_ADD:59  case ELF::R_SPARC_TLS_LE_HIX22:60  case ELF::R_SPARC_TLS_LE_LOX10:61    if (auto *SA = const_cast<MCSymbol *>(Target.getAddSym()))62      static_cast<MCSymbolELF *>(SA)->setType(ELF::STT_TLS);63    break;64  default:65    break;66  }67 68  // Extract the relocation type from the fixup kind, after applying STT_TLS as69  // needed.70  auto Kind = Fixup.getKind();71  if (mc::isRelocation(Fixup.getKind()))72    return Kind;73 74  if (const auto *SExpr = dyn_cast<MCSpecifierExpr>(Fixup.getValue())) {75    if (SExpr->getSpecifier() == ELF::R_SPARC_DISP32)76      return ELF::R_SPARC_DISP32;77  }78 79  if (IsPCRel) {80    switch (Kind) {81    default:82      llvm_unreachable("Unimplemented fixup -> relocation");83    case FK_Data_1:                  return ELF::R_SPARC_DISP8;84    case FK_Data_2:                  return ELF::R_SPARC_DISP16;85    case FK_Data_4:                  return ELF::R_SPARC_DISP32;86    case FK_Data_8:                  return ELF::R_SPARC_DISP64;87    case Sparc::fixup_sparc_call30:88      if (getContext().getObjectFileInfo()->isPositionIndependent())89        return ELF::R_SPARC_WPLT30;90      return ELF::R_SPARC_WDISP30;91    }92  }93 94  // clang-format off95  switch(Fixup.getKind()) {96  default:97    llvm_unreachable("Unimplemented fixup -> relocation");98  case FK_NONE:                  return ELF::R_SPARC_NONE;99  case FK_Data_1:                return ELF::R_SPARC_8;100  case FK_Data_2:                return ((Fixup.getOffset() % 2)101                                         ? ELF::R_SPARC_UA16102                                         : ELF::R_SPARC_16);103  case FK_Data_4:                return ((Fixup.getOffset() % 4)104                                         ? ELF::R_SPARC_UA32105                                         : ELF::R_SPARC_32);106  case FK_Data_8:                return ((Fixup.getOffset() % 8)107                                         ? ELF::R_SPARC_UA64108                                         : ELF::R_SPARC_64);109  case Sparc::fixup_sparc_13:110    if (getContext().getObjectFileInfo()->isPositionIndependent())111      return ELF::R_SPARC_GOT13;112    return ELF::R_SPARC_13;113  }114  // clang-format on115 116  return ELF::R_SPARC_NONE;117}118 119bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCValue &,120                                                   unsigned Type) const {121  switch (Type) {122    default:123      return false;124 125    // All relocations that use a GOT need a symbol, not an offset, as126    // the offset of the symbol within the section is irrelevant to127    // where the GOT entry is. Don't need to list all the TLS entries,128    // as they're all marked as requiring a symbol anyways.129    case ELF::R_SPARC_GOT10:130    case ELF::R_SPARC_GOT13:131    case ELF::R_SPARC_GOT22:132    case ELF::R_SPARC_GOTDATA_HIX22:133    case ELF::R_SPARC_GOTDATA_LOX10:134    case ELF::R_SPARC_GOTDATA_OP_HIX22:135    case ELF::R_SPARC_GOTDATA_OP_LOX10:136      return true;137  }138}139 140std::unique_ptr<MCObjectTargetWriter>141llvm::createSparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI) {142  return std::make_unique<SparcELFObjectWriter>(Is64Bit, IsV8Plus, OSABI);143}144