1 //===-- MipsELFObjectWriter.cpp - Mips ELF Writer -------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MCTargetDesc/MipsBaseInfo.h" 11 #include "MCTargetDesc/MipsFixupKinds.h" 12 #include "MCTargetDesc/MipsMCTargetDesc.h" 13 #include "llvm/MC/MCAssembler.h" 14 #include "llvm/MC/MCELF.h" 15 #include "llvm/MC/MCELFObjectWriter.h" 16 #include "llvm/MC/MCExpr.h" 17 #include "llvm/MC/MCSection.h" 18 #include "llvm/MC/MCValue.h" 19 #include "llvm/Support/ErrorHandling.h" 20 #include <list> 21 22 using namespace llvm; 23 24 namespace { 25 class MipsELFObjectWriter : public MCELFObjectTargetWriter { 26 public: 27 MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI, 28 bool _isN64, bool IsLittleEndian); 29 30 virtual ~MipsELFObjectWriter(); 31 32 unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 33 bool IsPCRel) const override; 34 bool needsRelocateWithSymbol(const MCSymbolData &SD, 35 unsigned Type) const override; 36 }; 37 } 38 39 MipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI, 40 bool _isN64, bool IsLittleEndian) 41 : MCELFObjectTargetWriter(_is64Bit, OSABI, ELF::EM_MIPS, 42 /*HasRelocationAddend*/ (_isN64) ? true : false, 43 /*IsN64*/ _isN64) {} 44 45 MipsELFObjectWriter::~MipsELFObjectWriter() {} 46 47 unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, 48 const MCFixup &Fixup, 49 bool IsPCRel) const { 50 // determine the type of the relocation 51 unsigned Type = (unsigned)ELF::R_MIPS_NONE; 52 unsigned Kind = (unsigned)Fixup.getKind(); 53 54 switch (Kind) { 55 default: 56 llvm_unreachable("invalid fixup kind!"); 57 case FK_Data_4: 58 Type = ELF::R_MIPS_32; 59 break; 60 case FK_Data_8: 61 Type = ELF::R_MIPS_64; 62 break; 63 case FK_GPRel_4: 64 if (isN64()) { 65 Type = setRType((unsigned)ELF::R_MIPS_GPREL32, Type); 66 Type = setRType2((unsigned)ELF::R_MIPS_64, Type); 67 Type = setRType3((unsigned)ELF::R_MIPS_NONE, Type); 68 } 69 else 70 Type = ELF::R_MIPS_GPREL32; 71 break; 72 case Mips::fixup_Mips_GPREL16: 73 Type = ELF::R_MIPS_GPREL16; 74 break; 75 case Mips::fixup_Mips_26: 76 Type = ELF::R_MIPS_26; 77 break; 78 case Mips::fixup_Mips_CALL16: 79 Type = ELF::R_MIPS_CALL16; 80 break; 81 case Mips::fixup_Mips_GOT_Global: 82 case Mips::fixup_Mips_GOT_Local: 83 Type = ELF::R_MIPS_GOT16; 84 break; 85 case Mips::fixup_Mips_HI16: 86 Type = ELF::R_MIPS_HI16; 87 break; 88 case Mips::fixup_Mips_LO16: 89 Type = ELF::R_MIPS_LO16; 90 break; 91 case Mips::fixup_Mips_TLSGD: 92 Type = ELF::R_MIPS_TLS_GD; 93 break; 94 case Mips::fixup_Mips_GOTTPREL: 95 Type = ELF::R_MIPS_TLS_GOTTPREL; 96 break; 97 case Mips::fixup_Mips_TPREL_HI: 98 Type = ELF::R_MIPS_TLS_TPREL_HI16; 99 break; 100 case Mips::fixup_Mips_TPREL_LO: 101 Type = ELF::R_MIPS_TLS_TPREL_LO16; 102 break; 103 case Mips::fixup_Mips_TLSLDM: 104 Type = ELF::R_MIPS_TLS_LDM; 105 break; 106 case Mips::fixup_Mips_DTPREL_HI: 107 Type = ELF::R_MIPS_TLS_DTPREL_HI16; 108 break; 109 case Mips::fixup_Mips_DTPREL_LO: 110 Type = ELF::R_MIPS_TLS_DTPREL_LO16; 111 break; 112 case Mips::fixup_Mips_Branch_PCRel: 113 case Mips::fixup_Mips_PC16: 114 Type = ELF::R_MIPS_PC16; 115 break; 116 case Mips::fixup_Mips_GOT_PAGE: 117 Type = ELF::R_MIPS_GOT_PAGE; 118 break; 119 case Mips::fixup_Mips_GOT_OFST: 120 Type = ELF::R_MIPS_GOT_OFST; 121 break; 122 case Mips::fixup_Mips_GOT_DISP: 123 Type = ELF::R_MIPS_GOT_DISP; 124 break; 125 case Mips::fixup_Mips_GPOFF_HI: 126 Type = setRType((unsigned)ELF::R_MIPS_GPREL16, Type); 127 Type = setRType2((unsigned)ELF::R_MIPS_SUB, Type); 128 Type = setRType3((unsigned)ELF::R_MIPS_HI16, Type); 129 break; 130 case Mips::fixup_Mips_GPOFF_LO: 131 Type = setRType((unsigned)ELF::R_MIPS_GPREL16, Type); 132 Type = setRType2((unsigned)ELF::R_MIPS_SUB, Type); 133 Type = setRType3((unsigned)ELF::R_MIPS_LO16, Type); 134 break; 135 case Mips::fixup_Mips_HIGHER: 136 Type = ELF::R_MIPS_HIGHER; 137 break; 138 case Mips::fixup_Mips_HIGHEST: 139 Type = ELF::R_MIPS_HIGHEST; 140 break; 141 case Mips::fixup_Mips_GOT_HI16: 142 Type = ELF::R_MIPS_GOT_HI16; 143 break; 144 case Mips::fixup_Mips_GOT_LO16: 145 Type = ELF::R_MIPS_GOT_LO16; 146 break; 147 case Mips::fixup_Mips_CALL_HI16: 148 Type = ELF::R_MIPS_CALL_HI16; 149 break; 150 case Mips::fixup_Mips_CALL_LO16: 151 Type = ELF::R_MIPS_CALL_LO16; 152 break; 153 case Mips::fixup_MICROMIPS_26_S1: 154 Type = ELF::R_MICROMIPS_26_S1; 155 break; 156 case Mips::fixup_MICROMIPS_HI16: 157 Type = ELF::R_MICROMIPS_HI16; 158 break; 159 case Mips::fixup_MICROMIPS_LO16: 160 Type = ELF::R_MICROMIPS_LO16; 161 break; 162 case Mips::fixup_MICROMIPS_GOT16: 163 Type = ELF::R_MICROMIPS_GOT16; 164 break; 165 case Mips::fixup_MICROMIPS_PC7_S1: 166 Type = ELF::R_MICROMIPS_PC7_S1; 167 break; 168 case Mips::fixup_MICROMIPS_PC10_S1: 169 Type = ELF::R_MICROMIPS_PC10_S1; 170 break; 171 case Mips::fixup_MICROMIPS_PC16_S1: 172 Type = ELF::R_MICROMIPS_PC16_S1; 173 break; 174 case Mips::fixup_MICROMIPS_CALL16: 175 Type = ELF::R_MICROMIPS_CALL16; 176 break; 177 case Mips::fixup_MICROMIPS_GOT_DISP: 178 Type = ELF::R_MICROMIPS_GOT_DISP; 179 break; 180 case Mips::fixup_MICROMIPS_GOT_PAGE: 181 Type = ELF::R_MICROMIPS_GOT_PAGE; 182 break; 183 case Mips::fixup_MICROMIPS_GOT_OFST: 184 Type = ELF::R_MICROMIPS_GOT_OFST; 185 break; 186 case Mips::fixup_MICROMIPS_TLS_GD: 187 Type = ELF::R_MICROMIPS_TLS_GD; 188 break; 189 case Mips::fixup_MICROMIPS_TLS_LDM: 190 Type = ELF::R_MICROMIPS_TLS_LDM; 191 break; 192 case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16: 193 Type = ELF::R_MICROMIPS_TLS_DTPREL_HI16; 194 break; 195 case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16: 196 Type = ELF::R_MICROMIPS_TLS_DTPREL_LO16; 197 break; 198 case Mips::fixup_MICROMIPS_TLS_TPREL_HI16: 199 Type = ELF::R_MICROMIPS_TLS_TPREL_HI16; 200 break; 201 case Mips::fixup_MICROMIPS_TLS_TPREL_LO16: 202 Type = ELF::R_MICROMIPS_TLS_TPREL_LO16; 203 break; 204 case Mips::fixup_MIPS_PC19_S2: 205 Type = ELF::R_MIPS_PC19_S2; 206 break; 207 case Mips::fixup_MIPS_PC18_S3: 208 Type = ELF::R_MIPS_PC18_S3; 209 break; 210 case Mips::fixup_MIPS_PC21_S2: 211 Type = ELF::R_MIPS_PC21_S2; 212 break; 213 case Mips::fixup_MIPS_PC26_S2: 214 Type = ELF::R_MIPS_PC26_S2; 215 break; 216 case Mips::fixup_MIPS_PCHI16: 217 Type = ELF::R_MIPS_PCHI16; 218 break; 219 case Mips::fixup_MIPS_PCLO16: 220 Type = ELF::R_MIPS_PCLO16; 221 break; 222 } 223 return Type; 224 } 225 226 bool 227 MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD, 228 unsigned Type) const { 229 // FIXME: This is extremely conservative. This really needs to use a 230 // whitelist with a clear explanation for why each realocation needs to 231 // point to the symbol, not to the section. 232 switch (Type) { 233 default: 234 return true; 235 236 case ELF::R_MIPS_GOT16: 237 case ELF::R_MIPS16_GOT16: 238 case ELF::R_MICROMIPS_GOT16: 239 llvm_unreachable("Should have been handled already"); 240 241 // These relocations might be paired with another relocation. The pairing is 242 // done by the static linker by matching the symbol. Since we only see one 243 // relocation at a time, we have to force them to relocate with a symbol to 244 // avoid ending up with a pair where one points to a section and another 245 // points to a symbol. 246 case ELF::R_MIPS_HI16: 247 case ELF::R_MIPS16_HI16: 248 case ELF::R_MICROMIPS_HI16: 249 case ELF::R_MIPS_LO16: 250 case ELF::R_MIPS16_LO16: 251 case ELF::R_MICROMIPS_LO16: 252 return true; 253 254 case ELF::R_MIPS_32: 255 if (MCELF::getOther(SD) & (ELF::STO_MIPS_MICROMIPS >> 2)) 256 return true; 257 // falltrough 258 case ELF::R_MIPS_26: 259 case ELF::R_MIPS_64: 260 case ELF::R_MIPS_GPREL16: 261 return false; 262 } 263 } 264 265 MCObjectWriter *llvm::createMipsELFObjectWriter(raw_ostream &OS, 266 uint8_t OSABI, 267 bool IsLittleEndian, 268 bool Is64Bit) { 269 MCELFObjectTargetWriter *MOTW = new MipsELFObjectWriter(Is64Bit, OSABI, 270 (Is64Bit) ? true : false, 271 IsLittleEndian); 272 return createELFObjectWriter(MOTW, OS, IsLittleEndian); 273 } 274