182 lines · cpp
1//===-- M68kELFObjectWriter.cpp - M68k ELF Writer ---------------*- C++ -*-===//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/// \file10/// This file contains definitions for M68k ELF Writers11///12//===----------------------------------------------------------------------===//13 14#include "MCTargetDesc/M68kFixupKinds.h"15#include "MCTargetDesc/M68kMCAsmInfo.h"16#include "MCTargetDesc/M68kMCTargetDesc.h"17 18#include "llvm/BinaryFormat/ELF.h"19#include "llvm/MC/MCAsmInfo.h"20#include "llvm/MC/MCContext.h"21#include "llvm/MC/MCELFObjectWriter.h"22#include "llvm/MC/MCExpr.h"23#include "llvm/MC/MCValue.h"24#include "llvm/Support/ErrorHandling.h"25 26using namespace llvm;27 28namespace {29class M68kELFObjectWriter : public MCELFObjectTargetWriter {30public:31 M68kELFObjectWriter(uint8_t OSABI);32 33 ~M68kELFObjectWriter() override;34 35protected:36 unsigned getRelocType(const MCFixup &, const MCValue &,37 bool IsPCRel) const override;38};39} // namespace40 41M68kELFObjectWriter::M68kELFObjectWriter(uint8_t OSABI)42 : MCELFObjectTargetWriter(false, OSABI, ELF::EM_68K, /* RELA */ true) {}43 44M68kELFObjectWriter::~M68kELFObjectWriter() {}45 46enum M68kRelType { RT_32, RT_16, RT_8 };47 48static M68kRelType getType(unsigned Kind, M68k::Specifier &Modifier,49 bool &IsPCRel) {50 switch (Kind) {51 case FK_Data_4:52 return RT_32;53 case FK_Data_2:54 return RT_16;55 case FK_Data_1:56 return RT_8;57 }58 llvm_unreachable("Unimplemented");59}60 61unsigned M68kELFObjectWriter::getRelocType(const MCFixup &Fixup,62 const MCValue &Target,63 bool IsPCRel) const {64 auto Specifier = M68k::Specifier(Target.getSpecifier());65 unsigned Kind = Fixup.getKind();66 M68kRelType Type = getType(Kind, Specifier, IsPCRel);67 switch (Specifier) {68 case M68k::S_GOTTPOFF:69 case M68k::S_TLSGD:70 case M68k::S_TLSLD:71 case M68k::S_TLSLDM:72 case M68k::S_TPOFF:73 if (auto *SA = const_cast<MCSymbol *>(Target.getAddSym()))74 static_cast<MCSymbolELF *>(SA)->setType(ELF::STT_TLS);75 break;76 default:77 break;78 }79 80 switch (Specifier) {81 default:82 llvm_unreachable("Unimplemented");83 84 case M68k::S_TLSGD:85 switch (Type) {86 case RT_32:87 return ELF::R_68K_TLS_GD32;88 case RT_16:89 return ELF::R_68K_TLS_GD16;90 case RT_8:91 return ELF::R_68K_TLS_GD8;92 }93 llvm_unreachable("Unrecognized size");94 case M68k::S_TLSLDM:95 switch (Type) {96 case RT_32:97 return ELF::R_68K_TLS_LDM32;98 case RT_16:99 return ELF::R_68K_TLS_LDM16;100 case RT_8:101 return ELF::R_68K_TLS_LDM8;102 }103 llvm_unreachable("Unrecognized size");104 case M68k::S_TLSLD:105 switch (Type) {106 case RT_32:107 return ELF::R_68K_TLS_LDO32;108 case RT_16:109 return ELF::R_68K_TLS_LDO16;110 case RT_8:111 return ELF::R_68K_TLS_LDO8;112 }113 llvm_unreachable("Unrecognized size");114 case M68k::S_GOTTPOFF:115 switch (Type) {116 case RT_32:117 return ELF::R_68K_TLS_IE32;118 case RT_16:119 return ELF::R_68K_TLS_IE16;120 case RT_8:121 return ELF::R_68K_TLS_IE8;122 }123 llvm_unreachable("Unrecognized size");124 case M68k::S_TPOFF:125 switch (Type) {126 case RT_32:127 return ELF::R_68K_TLS_LE32;128 case RT_16:129 return ELF::R_68K_TLS_LE16;130 case RT_8:131 return ELF::R_68K_TLS_LE8;132 }133 llvm_unreachable("Unrecognized size");134 case M68k::S_None:135 switch (Type) {136 case RT_32:137 return IsPCRel ? ELF::R_68K_PC32 : ELF::R_68K_32;138 case RT_16:139 return IsPCRel ? ELF::R_68K_PC16 : ELF::R_68K_16;140 case RT_8:141 return IsPCRel ? ELF::R_68K_PC8 : ELF::R_68K_8;142 }143 llvm_unreachable("Unrecognized size");144 case M68k::S_GOTPCREL:145 switch (Type) {146 case RT_32:147 return ELF::R_68K_GOTPCREL32;148 case RT_16:149 return ELF::R_68K_GOTPCREL16;150 case RT_8:151 return ELF::R_68K_GOTPCREL8;152 }153 llvm_unreachable("Unrecognized size");154 case M68k::S_GOTOFF:155 assert(!IsPCRel);156 switch (Type) {157 case RT_32:158 return ELF::R_68K_GOTOFF32;159 case RT_16:160 return ELF::R_68K_GOTOFF16;161 case RT_8:162 return ELF::R_68K_GOTOFF8;163 }164 llvm_unreachable("Unrecognized size");165 case M68k::S_PLT:166 switch (Type) {167 case RT_32:168 return ELF::R_68K_PLT32;169 case RT_16:170 return ELF::R_68K_PLT16;171 case RT_8:172 return ELF::R_68K_PLT8;173 }174 llvm_unreachable("Unrecognized size");175 }176}177 178std::unique_ptr<MCObjectTargetWriter>179llvm::createM68kELFObjectWriter(uint8_t OSABI) {180 return std::make_unique<M68kELFObjectWriter>(OSABI);181}182