brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.6 KiB · 1bca5c7 Raw
224 lines · cpp
1//===-- SystemZELFObjectWriter.cpp - SystemZ 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/SystemZMCAsmInfo.h"10#include "MCTargetDesc/SystemZMCFixups.h"11#include "MCTargetDesc/SystemZMCTargetDesc.h"12#include "llvm/BinaryFormat/ELF.h"13#include "llvm/MC/MCContext.h"14#include "llvm/MC/MCELFObjectWriter.h"15#include "llvm/MC/MCExpr.h"16#include "llvm/MC/MCFixup.h"17#include "llvm/MC/MCObjectWriter.h"18#include "llvm/MC/MCValue.h"19#include "llvm/Support/ErrorHandling.h"20#include <cassert>21#include <cstdint>22#include <memory>23 24using namespace llvm;25 26namespace {27 28class SystemZELFObjectWriter : public MCELFObjectTargetWriter {29public:30  SystemZELFObjectWriter(uint8_t OSABI);31  ~SystemZELFObjectWriter() override = default;32 33protected:34  // Override MCELFObjectTargetWriter.35  unsigned getRelocType(const MCFixup &, const MCValue &,36                        bool IsPCRel) const override;37  bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override;38  unsigned getAbsoluteReloc(SMLoc Loc, unsigned Kind) const;39  unsigned getPCRelReloc(SMLoc Loc, unsigned Kind) const;40};41 42} // end anonymous namespace43 44SystemZELFObjectWriter::SystemZELFObjectWriter(uint8_t OSABI)45    : MCELFObjectTargetWriter(/*Is64Bit_=*/true, OSABI, ELF::EM_S390,46                              /*HasRelocationAddend_=*/true) {}47 48// Return the relocation type for an absolute value of MCFixupKind Kind.49unsigned SystemZELFObjectWriter::getAbsoluteReloc(SMLoc Loc,50                                                  unsigned Kind) const {51  switch (Kind) {52  case FK_Data_1:53  case SystemZ::FK_390_U8Imm:54  case SystemZ::FK_390_S8Imm:55    return ELF::R_390_8;56  case SystemZ::FK_390_U12Imm:57    return ELF::R_390_12;58  case FK_Data_2:59  case SystemZ::FK_390_U16Imm:60  case SystemZ::FK_390_S16Imm:61    return ELF::R_390_16;62  case SystemZ::FK_390_S20Imm:63    return ELF::R_390_20;64  case FK_Data_4:65  case SystemZ::FK_390_U32Imm:66  case SystemZ::FK_390_S32Imm:67    return ELF::R_390_32;68  case FK_Data_8:69    return ELF::R_390_64;70  }71  reportError(Loc, "Unsupported absolute address");72  return 0;73}74 75// Return the relocation type for a PC-relative value of MCFixupKind Kind.76unsigned SystemZELFObjectWriter::getPCRelReloc(SMLoc Loc, unsigned Kind) const {77  switch (Kind) {78  case FK_Data_2:79  case SystemZ::FK_390_U16Imm:80  case SystemZ::FK_390_S16Imm:81    return ELF::R_390_PC16;82  case FK_Data_4:83  case SystemZ::FK_390_U32Imm:84  case SystemZ::FK_390_S32Imm:85    return ELF::R_390_PC32;86  case FK_Data_8:87    return ELF::R_390_PC64;88  case SystemZ::FK_390_PC12DBL:89    return ELF::R_390_PC12DBL;90  case SystemZ::FK_390_PC16DBL:91    return ELF::R_390_PC16DBL;92  case SystemZ::FK_390_PC24DBL:93    return ELF::R_390_PC24DBL;94  case SystemZ::FK_390_PC32DBL:95    return ELF::R_390_PC32DBL;96  }97  reportError(Loc, "Unsupported PC-relative address");98  return 0;99}100 101unsigned SystemZELFObjectWriter::getRelocType(const MCFixup &Fixup,102                                              const MCValue &Target,103                                              bool IsPCRel) const {104  SMLoc Loc = Fixup.getLoc();105  unsigned Kind = Fixup.getKind();106  auto Specifier = SystemZ::Specifier(Target.getSpecifier());107  switch (Specifier) {108  case SystemZ::S_INDNTPOFF:109  case SystemZ::S_NTPOFF:110  case SystemZ::S_TLSGD:111  case SystemZ::S_TLSLD:112  case SystemZ::S_TLSLDM:113  case SystemZ::S_DTPOFF:114    if (auto *SA = const_cast<MCSymbol *>(Target.getAddSym()))115      static_cast<MCSymbolELF *>(SA)->setType(ELF::STT_TLS);116    break;117  default:118    break;119  }120 121  switch (Specifier) {122  case SystemZ::S_None:123    if (IsPCRel)124      return getPCRelReloc(Loc, Kind);125    return getAbsoluteReloc(Loc, Kind);126 127  case SystemZ::S_NTPOFF:128    assert(!IsPCRel && "NTPOFF shouldn't be PC-relative");129    switch (Kind) {130    case FK_Data_4:131      return ELF::R_390_TLS_LE32;132    case FK_Data_8:133      return ELF::R_390_TLS_LE64;134    }135    reportError(Loc, "Unsupported thread-local address (local-exec)");136    return 0;137 138  case SystemZ::S_INDNTPOFF:139    if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL)140      return ELF::R_390_TLS_IEENT;141    reportError(Loc,142                "Only PC-relative INDNTPOFF accesses are supported for now");143    return 0;144 145  case SystemZ::S_DTPOFF:146    assert(!IsPCRel && "DTPOFF shouldn't be PC-relative");147    switch (Kind) {148    case FK_Data_4:149      return ELF::R_390_TLS_LDO32;150    case FK_Data_8:151      return ELF::R_390_TLS_LDO64;152    }153    reportError(Loc, "Unsupported thread-local address (local-dynamic)");154    return 0;155 156  case SystemZ::S_TLSLDM:157    assert(!IsPCRel && "TLSLDM shouldn't be PC-relative");158    switch (Kind) {159    case FK_Data_4:160      return ELF::R_390_TLS_LDM32;161    case FK_Data_8:162      return ELF::R_390_TLS_LDM64;163    case SystemZ::FK_390_TLS_CALL:164      return ELF::R_390_TLS_LDCALL;165    }166    reportError(Loc, "Unsupported thread-local address (local-dynamic)");167    return 0;168 169  case SystemZ::S_TLSGD:170    assert(!IsPCRel && "TLSGD shouldn't be PC-relative");171    switch (Kind) {172    case FK_Data_4:173      return ELF::R_390_TLS_GD32;174    case FK_Data_8:175      return ELF::R_390_TLS_GD64;176    case SystemZ::FK_390_TLS_CALL:177      return ELF::R_390_TLS_GDCALL;178    }179    reportError(Loc, "Unsupported thread-local address (general-dynamic)");180    return 0;181 182  case SystemZ::S_GOT:183  case SystemZ::S_GOTENT:184    if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL)185      return ELF::R_390_GOTENT;186    reportError(Loc, "Only PC-relative GOT accesses are supported for now");187    return 0;188 189  case SystemZ::S_PLT:190    assert(IsPCRel && "@PLT shouldn't be PC-relative");191    switch (Kind) {192    case SystemZ::FK_390_PC12DBL:193      return ELF::R_390_PLT12DBL;194    case SystemZ::FK_390_PC16DBL:195      return ELF::R_390_PLT16DBL;196    case SystemZ::FK_390_PC24DBL:197      return ELF::R_390_PLT24DBL;198    case SystemZ::FK_390_PC32DBL:199      return ELF::R_390_PLT32DBL;200    }201    reportError(Loc, "Unsupported PC-relative PLT address");202    return 0;203 204  default:205    llvm_unreachable("Modifier not supported");206  }207}208 209bool SystemZELFObjectWriter::needsRelocateWithSymbol(const MCValue &V,210                                                     unsigned Type) const {211  switch (V.getSpecifier()) {212  case SystemZ::S_GOT:213  case SystemZ::S_PLT:214    return true;215  default:216    return false;217  }218}219 220std::unique_ptr<MCObjectTargetWriter>221llvm::createSystemZELFObjectWriter(uint8_t OSABI) {222  return std::make_unique<SystemZELFObjectWriter>(OSABI);223}224