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 74 case MCSymbolRefExpr::VK_TLSGD: 75 switch (Type) { 76 case RT_32: 77 return ELF::R_68K_TLS_GD32; 78 case RT_16: 79 return ELF::R_68K_TLS_GD16; 80 case RT_8: 81 return ELF::R_68K_TLS_GD8; 82 } 83 llvm_unreachable("Unrecognized size"); 84 case MCSymbolRefExpr::VK_TLSLDM: 85 switch (Type) { 86 case RT_32: 87 return ELF::R_68K_TLS_LDM32; 88 case RT_16: 89 return ELF::R_68K_TLS_LDM16; 90 case RT_8: 91 return ELF::R_68K_TLS_LDM8; 92 } 93 llvm_unreachable("Unrecognized size"); 94 case MCSymbolRefExpr::VK_TLSLD: 95 switch (Type) { 96 case RT_32: 97 return ELF::R_68K_TLS_LDO32; 98 case RT_16: 99 return ELF::R_68K_TLS_LDO16; 100 case RT_8: 101 return ELF::R_68K_TLS_LDO8; 102 } 103 llvm_unreachable("Unrecognized size"); 104 case MCSymbolRefExpr::VK_GOTTPOFF: 105 switch (Type) { 106 case RT_32: 107 return ELF::R_68K_TLS_IE32; 108 case RT_16: 109 return ELF::R_68K_TLS_IE16; 110 case RT_8: 111 return ELF::R_68K_TLS_IE8; 112 } 113 llvm_unreachable("Unrecognized size"); 114 case MCSymbolRefExpr::VK_TPOFF: 115 switch (Type) { 116 case RT_32: 117 return ELF::R_68K_TLS_LE32; 118 case RT_16: 119 return ELF::R_68K_TLS_LE16; 120 case RT_8: 121 return ELF::R_68K_TLS_LE8; 122 } 123 llvm_unreachable("Unrecognized size"); 124 case MCSymbolRefExpr::VK_None: 125 switch (Type) { 126 case RT_32: 127 return IsPCRel ? ELF::R_68K_PC32 : ELF::R_68K_32; 128 case RT_16: 129 return IsPCRel ? ELF::R_68K_PC16 : ELF::R_68K_16; 130 case RT_8: 131 return IsPCRel ? ELF::R_68K_PC8 : ELF::R_68K_8; 132 } 133 llvm_unreachable("Unrecognized size"); 134 case MCSymbolRefExpr::VK_GOTPCREL: 135 switch (Type) { 136 case RT_32: 137 return ELF::R_68K_GOTPCREL32; 138 case RT_16: 139 return ELF::R_68K_GOTPCREL16; 140 case RT_8: 141 return ELF::R_68K_GOTPCREL8; 142 } 143 llvm_unreachable("Unrecognized size"); 144 case MCSymbolRefExpr::VK_GOTOFF: 145 assert(!IsPCRel); 146 switch (Type) { 147 case RT_32: 148 return ELF::R_68K_GOTOFF32; 149 case RT_16: 150 return ELF::R_68K_GOTOFF16; 151 case RT_8: 152 return ELF::R_68K_GOTOFF8; 153 } 154 llvm_unreachable("Unrecognized size"); 155 case MCSymbolRefExpr::VK_PLT: 156 switch (Type) { 157 case RT_32: 158 return ELF::R_68K_PLT32; 159 case RT_16: 160 return ELF::R_68K_PLT16; 161 case RT_8: 162 return ELF::R_68K_PLT8; 163 } 164 llvm_unreachable("Unrecognized size"); 165 } 166 } 167 168 std::unique_ptr<MCObjectTargetWriter> 169 llvm::createM68kELFObjectWriter(uint8_t OSABI) { 170 return std::make_unique<M68kELFObjectWriter>(OSABI); 171 } 172