1*fe6060f1SDimitry Andric //===---------- M68kELFObjectWriter.cpp - M68k ELF Writer ---*- C++ -*-===// 2*fe6060f1SDimitry Andric // 3*fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*fe6060f1SDimitry Andric // 7*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8*fe6060f1SDimitry Andric /// 9*fe6060f1SDimitry Andric /// \file 10*fe6060f1SDimitry Andric /// This file contains definitions for M68k ELF Writers 11*fe6060f1SDimitry Andric /// 12*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 13*fe6060f1SDimitry Andric 14*fe6060f1SDimitry Andric #include "MCTargetDesc/M68kFixupKinds.h" 15*fe6060f1SDimitry Andric #include "MCTargetDesc/M68kMCTargetDesc.h" 16*fe6060f1SDimitry Andric 17*fe6060f1SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 18*fe6060f1SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 19*fe6060f1SDimitry Andric #include "llvm/MC/MCContext.h" 20*fe6060f1SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h" 21*fe6060f1SDimitry Andric #include "llvm/MC/MCExpr.h" 22*fe6060f1SDimitry Andric #include "llvm/MC/MCValue.h" 23*fe6060f1SDimitry Andric #include "llvm/Support/ErrorHandling.h" 24*fe6060f1SDimitry Andric 25*fe6060f1SDimitry Andric using namespace llvm; 26*fe6060f1SDimitry Andric 27*fe6060f1SDimitry Andric namespace { 28*fe6060f1SDimitry Andric class M68kELFObjectWriter : public MCELFObjectTargetWriter { 29*fe6060f1SDimitry Andric public: 30*fe6060f1SDimitry Andric M68kELFObjectWriter(uint8_t OSABI); 31*fe6060f1SDimitry Andric 32*fe6060f1SDimitry Andric ~M68kELFObjectWriter() override; 33*fe6060f1SDimitry Andric 34*fe6060f1SDimitry Andric protected: 35*fe6060f1SDimitry Andric unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 36*fe6060f1SDimitry Andric const MCFixup &Fixup, bool IsPCRel) const override; 37*fe6060f1SDimitry Andric }; 38*fe6060f1SDimitry Andric } // namespace 39*fe6060f1SDimitry Andric 40*fe6060f1SDimitry Andric M68kELFObjectWriter::M68kELFObjectWriter(uint8_t OSABI) 41*fe6060f1SDimitry Andric : MCELFObjectTargetWriter(false, OSABI, ELF::EM_68K, /* RELA */ true) {} 42*fe6060f1SDimitry Andric 43*fe6060f1SDimitry Andric M68kELFObjectWriter::~M68kELFObjectWriter() {} 44*fe6060f1SDimitry Andric 45*fe6060f1SDimitry Andric enum M68kRelType { RT_32, RT_16, RT_8 }; 46*fe6060f1SDimitry Andric 47*fe6060f1SDimitry Andric static M68kRelType 48*fe6060f1SDimitry Andric getType(unsigned Kind, MCSymbolRefExpr::VariantKind &Modifier, bool &IsPCRel) { 49*fe6060f1SDimitry Andric switch (Kind) { 50*fe6060f1SDimitry Andric case FK_Data_4: 51*fe6060f1SDimitry Andric case FK_PCRel_4: 52*fe6060f1SDimitry Andric return RT_32; 53*fe6060f1SDimitry Andric case FK_PCRel_2: 54*fe6060f1SDimitry Andric case FK_Data_2: 55*fe6060f1SDimitry Andric return RT_16; 56*fe6060f1SDimitry Andric case FK_PCRel_1: 57*fe6060f1SDimitry Andric case FK_Data_1: 58*fe6060f1SDimitry Andric return RT_8; 59*fe6060f1SDimitry Andric } 60*fe6060f1SDimitry Andric llvm_unreachable("Unimplemented"); 61*fe6060f1SDimitry Andric } 62*fe6060f1SDimitry Andric 63*fe6060f1SDimitry Andric unsigned M68kELFObjectWriter::getRelocType(MCContext &Ctx, 64*fe6060f1SDimitry Andric const MCValue &Target, 65*fe6060f1SDimitry Andric const MCFixup &Fixup, 66*fe6060f1SDimitry Andric bool IsPCRel) const { 67*fe6060f1SDimitry Andric MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); 68*fe6060f1SDimitry Andric unsigned Kind = Fixup.getKind(); 69*fe6060f1SDimitry Andric M68kRelType Type = getType(Kind, Modifier, IsPCRel); 70*fe6060f1SDimitry Andric switch (Modifier) { 71*fe6060f1SDimitry Andric default: 72*fe6060f1SDimitry Andric llvm_unreachable("Unimplemented"); 73*fe6060f1SDimitry Andric case MCSymbolRefExpr::VK_None: 74*fe6060f1SDimitry Andric switch (Type) { 75*fe6060f1SDimitry Andric case RT_32: 76*fe6060f1SDimitry Andric return IsPCRel ? ELF::R_68K_PC32 : ELF::R_68K_32; 77*fe6060f1SDimitry Andric case RT_16: 78*fe6060f1SDimitry Andric return IsPCRel ? ELF::R_68K_PC16 : ELF::R_68K_16; 79*fe6060f1SDimitry Andric case RT_8: 80*fe6060f1SDimitry Andric return IsPCRel ? ELF::R_68K_PC8 : ELF::R_68K_8; 81*fe6060f1SDimitry Andric } 82*fe6060f1SDimitry Andric llvm_unreachable("Unrecognized size"); 83*fe6060f1SDimitry Andric case MCSymbolRefExpr::VK_GOTPCREL: 84*fe6060f1SDimitry Andric switch (Type) { 85*fe6060f1SDimitry Andric case RT_32: 86*fe6060f1SDimitry Andric return ELF::R_68K_GOTPCREL32; 87*fe6060f1SDimitry Andric case RT_16: 88*fe6060f1SDimitry Andric return ELF::R_68K_GOTPCREL16; 89*fe6060f1SDimitry Andric case RT_8: 90*fe6060f1SDimitry Andric return ELF::R_68K_GOTPCREL8; 91*fe6060f1SDimitry Andric } 92*fe6060f1SDimitry Andric llvm_unreachable("Unrecognized size"); 93*fe6060f1SDimitry Andric case MCSymbolRefExpr::VK_GOTOFF: 94*fe6060f1SDimitry Andric assert(!IsPCRel); 95*fe6060f1SDimitry Andric switch (Type) { 96*fe6060f1SDimitry Andric case RT_32: 97*fe6060f1SDimitry Andric return ELF::R_68K_GOTOFF32; 98*fe6060f1SDimitry Andric case RT_16: 99*fe6060f1SDimitry Andric return ELF::R_68K_GOTOFF16; 100*fe6060f1SDimitry Andric case RT_8: 101*fe6060f1SDimitry Andric return ELF::R_68K_GOTOFF8; 102*fe6060f1SDimitry Andric } 103*fe6060f1SDimitry Andric llvm_unreachable("Unrecognized size"); 104*fe6060f1SDimitry Andric case MCSymbolRefExpr::VK_PLT: 105*fe6060f1SDimitry Andric switch (Type) { 106*fe6060f1SDimitry Andric case RT_32: 107*fe6060f1SDimitry Andric return ELF::R_68K_PLT32; 108*fe6060f1SDimitry Andric case RT_16: 109*fe6060f1SDimitry Andric return ELF::R_68K_PLT16; 110*fe6060f1SDimitry Andric case RT_8: 111*fe6060f1SDimitry Andric return ELF::R_68K_PLT8; 112*fe6060f1SDimitry Andric } 113*fe6060f1SDimitry Andric llvm_unreachable("Unrecognized size"); 114*fe6060f1SDimitry Andric } 115*fe6060f1SDimitry Andric } 116*fe6060f1SDimitry Andric 117*fe6060f1SDimitry Andric std::unique_ptr<MCObjectTargetWriter> 118*fe6060f1SDimitry Andric llvm::createM68kELFObjectWriter(uint8_t OSABI) { 119*fe6060f1SDimitry Andric return std::make_unique<M68kELFObjectWriter>(OSABI); 120*fe6060f1SDimitry Andric } 121