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