609 lines · cpp
1//===-- MipsELFObjectWriter.cpp - Mips ELF Writer -------------------------===//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#include "MCTargetDesc/MipsFixupKinds.h"10#include "MCTargetDesc/MipsMCAsmInfo.h"11#include "MCTargetDesc/MipsMCTargetDesc.h"12#include "llvm/ADT/STLExtras.h"13#include "llvm/BinaryFormat/ELF.h"14#include "llvm/MC/MCContext.h"15#include "llvm/MC/MCELFObjectWriter.h"16#include "llvm/MC/MCFixup.h"17#include "llvm/MC/MCObjectWriter.h"18#include "llvm/MC/MCSymbolELF.h"19#include "llvm/MC/MCValue.h"20#include "llvm/Support/Compiler.h"21#include "llvm/Support/Debug.h"22#include "llvm/Support/ErrorHandling.h"23#include "llvm/Support/MathExtras.h"24#include "llvm/Support/raw_ostream.h"25#include <cassert>26#include <cstdint>27#include <iterator>28#include <list>29#include <utility>30 31#define DEBUG_TYPE "mips-elf-object-writer"32 33using namespace llvm;34 35namespace {36 37/// Holds additional information needed by the relocation ordering algorithm.38struct MipsRelocationEntry {39 const ELFRelocationEntry R; ///< The relocation.40 bool Matched = false; ///< Is this relocation part of a match.41 42 MipsRelocationEntry(const ELFRelocationEntry &R) : R(R) {}43};44 45class MipsELFObjectWriter : public MCELFObjectTargetWriter {46public:47 MipsELFObjectWriter(uint8_t OSABI, bool HasRelocationAddend, bool Is64);48 49 ~MipsELFObjectWriter() override = default;50 51 unsigned getRelocType(const MCFixup &, const MCValue &,52 bool IsPCRel) const override;53 bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override;54 void sortRelocs(std::vector<ELFRelocationEntry> &Relocs) override;55};56 57/// The possible results of the Predicate function used by find_best.58enum FindBestPredicateResult {59 FindBest_NoMatch = 0, ///< The current element is not a match.60 FindBest_Match, ///< The current element is a match but better ones are61 /// possible.62 FindBest_PerfectMatch, ///< The current element is an unbeatable match.63};64 65} // end anonymous namespace66 67/// Copy elements in the range [First, Last) to d1 when the predicate is true or68/// d2 when the predicate is false. This is essentially both std::copy_if and69/// std::remove_copy_if combined into a single pass.70template <class InputIt, class OutputIt1, class OutputIt2, class UnaryPredicate>71static std::pair<OutputIt1, OutputIt2> copy_if_else(InputIt First, InputIt Last,72 OutputIt1 d1, OutputIt2 d2,73 UnaryPredicate Predicate) {74 for (InputIt I = First; I != Last; ++I) {75 if (Predicate(*I)) {76 *d1 = *I;77 d1++;78 } else {79 *d2 = *I;80 d2++;81 }82 }83 84 return std::make_pair(d1, d2);85}86 87/// Find the best match in the range [First, Last).88///89/// An element matches when Predicate(X) returns FindBest_Match or90/// FindBest_PerfectMatch. A value of FindBest_PerfectMatch also terminates91/// the search. BetterThan(A, B) is a comparator that returns true when A is a92/// better match than B. The return value is the position of the best match.93///94/// This is similar to std::find_if but finds the best of multiple possible95/// matches.96template <class InputIt, class UnaryPredicate, class Comparator>97static InputIt find_best(InputIt First, InputIt Last, UnaryPredicate Predicate,98 Comparator BetterThan) {99 InputIt Best = Last;100 101 for (InputIt I = First; I != Last; ++I) {102 unsigned Matched = Predicate(*I);103 if (Matched != FindBest_NoMatch) {104 if (Best == Last || BetterThan(*I, *Best))105 Best = I;106 }107 if (Matched == FindBest_PerfectMatch)108 break;109 }110 111 return Best;112}113 114/// Determine the low relocation that matches the given relocation.115/// If the relocation does not need a low relocation then the return value116/// is ELF::R_MIPS_NONE.117///118/// The relocations that need a matching low part are119/// R_(MIPS|MICROMIPS|MIPS16)_HI16 for all symbols and120/// R_(MIPS|MICROMIPS|MIPS16)_GOT16 for local symbols only.121static unsigned getMatchingLoType(const ELFRelocationEntry &Reloc) {122 unsigned Type = Reloc.Type;123 if (Type == ELF::R_MIPS_HI16)124 return ELF::R_MIPS_LO16;125 if (Type == ELF::R_MICROMIPS_HI16)126 return ELF::R_MICROMIPS_LO16;127 if (Type == ELF::R_MIPS16_HI16)128 return ELF::R_MIPS16_LO16;129 130 if (Reloc.Symbol && Reloc.Symbol->getBinding() != ELF::STB_LOCAL)131 return ELF::R_MIPS_NONE;132 133 if (Type == ELF::R_MIPS_GOT16)134 return ELF::R_MIPS_LO16;135 if (Type == ELF::R_MICROMIPS_GOT16)136 return ELF::R_MICROMIPS_LO16;137 if (Type == ELF::R_MIPS16_GOT16)138 return ELF::R_MIPS16_LO16;139 140 return ELF::R_MIPS_NONE;141}142 143// Determine whether a relocation X is a low-part and matches the high-part R144// perfectly by symbol and addend.145static bool isMatchingReloc(unsigned MatchingType, const ELFRelocationEntry &R,146 const ELFRelocationEntry &X) {147 return X.Type == MatchingType && X.Symbol == R.Symbol && X.Addend == R.Addend;148}149 150MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI,151 bool HasRelocationAddend, bool Is64)152 : MCELFObjectTargetWriter(Is64, OSABI, ELF::EM_MIPS, HasRelocationAddend) {}153 154unsigned MipsELFObjectWriter::getRelocType(const MCFixup &Fixup,155 const MCValue &Target,156 bool IsPCRel) const {157 // Determine the type of the relocation.158 auto Kind = Fixup.getKind();159 switch (Target.getSpecifier()) {160 case Mips::S_DTPREL:161 case Mips::S_DTPREL_HI:162 case Mips::S_DTPREL_LO:163 case Mips::S_TLSLDM:164 case Mips::S_TLSGD:165 case Mips::S_GOTTPREL:166 case Mips::S_TPREL_HI:167 case Mips::S_TPREL_LO:168 if (auto *SA = const_cast<MCSymbol *>(Target.getAddSym()))169 static_cast<MCSymbolELF *>(SA)->setType(ELF::STT_TLS);170 break;171 default:172 break;173 }174 175 switch (Kind) {176 case FK_NONE:177 return ELF::R_MIPS_NONE;178 case FK_Data_1:179 reportError(Fixup.getLoc(), "MIPS does not support one byte relocations");180 return ELF::R_MIPS_NONE;181 case Mips::fixup_Mips_16:182 case FK_Data_2:183 return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16;184 case Mips::fixup_Mips_32:185 case FK_Data_4:186 return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32;187 case Mips::fixup_Mips_64:188 case FK_Data_8:189 return IsPCRel190 ? setRTypes(ELF::R_MIPS_PC32, ELF::R_MIPS_64, ELF::R_MIPS_NONE)191 : (unsigned)ELF::R_MIPS_64;192 }193 194 if (IsPCRel) {195 switch (Kind) {196 case Mips::fixup_Mips_Branch_PCRel:197 case Mips::fixup_Mips_PC16:198 return ELF::R_MIPS_PC16;199 case Mips::fixup_MICROMIPS_PC7_S1:200 return ELF::R_MICROMIPS_PC7_S1;201 case Mips::fixup_MICROMIPS_PC10_S1:202 return ELF::R_MICROMIPS_PC10_S1;203 case Mips::fixup_MICROMIPS_PC16_S1:204 return ELF::R_MICROMIPS_PC16_S1;205 case Mips::fixup_MICROMIPS_PC26_S1:206 return ELF::R_MICROMIPS_PC26_S1;207 case Mips::fixup_MICROMIPS_PC19_S2:208 return ELF::R_MICROMIPS_PC19_S2;209 case Mips::fixup_MICROMIPS_PC18_S3:210 return ELF::R_MICROMIPS_PC18_S3;211 case Mips::fixup_MICROMIPS_PC21_S1:212 return ELF::R_MICROMIPS_PC21_S1;213 case Mips::fixup_MIPS_PC19_S2:214 return ELF::R_MIPS_PC19_S2;215 case Mips::fixup_MIPS_PC18_S3:216 return ELF::R_MIPS_PC18_S3;217 case Mips::fixup_MIPS_PC21_S2:218 return ELF::R_MIPS_PC21_S2;219 case Mips::fixup_MIPS_PC26_S2:220 return ELF::R_MIPS_PC26_S2;221 case Mips::fixup_MIPS_PCHI16:222 return ELF::R_MIPS_PCHI16;223 case Mips::fixup_MIPS_PCLO16:224 return ELF::R_MIPS_PCLO16;225 }226 227 llvm_unreachable("invalid PC-relative fixup kind!");228 }229 230 switch (Kind) {231 case Mips::fixup_Mips_DTPREL32:232 return ELF::R_MIPS_TLS_DTPREL32;233 case Mips::fixup_Mips_DTPREL64:234 return ELF::R_MIPS_TLS_DTPREL64;235 case Mips::fixup_Mips_TPREL32:236 return ELF::R_MIPS_TLS_TPREL32;237 case Mips::fixup_Mips_TPREL64:238 return ELF::R_MIPS_TLS_TPREL64;239 case Mips::fixup_Mips_GPREL32:240 return setRTypes(ELF::R_MIPS_GPREL32,241 is64Bit() ? ELF::R_MIPS_64 : ELF::R_MIPS_NONE,242 ELF::R_MIPS_NONE);243 case Mips::fixup_Mips_GPREL16:244 return ELF::R_MIPS_GPREL16;245 case Mips::fixup_Mips_26:246 return ELF::R_MIPS_26;247 case Mips::fixup_Mips_CALL16:248 return ELF::R_MIPS_CALL16;249 case Mips::fixup_Mips_GOT:250 return ELF::R_MIPS_GOT16;251 case Mips::fixup_Mips_HI16:252 return ELF::R_MIPS_HI16;253 case Mips::fixup_Mips_LO16:254 return ELF::R_MIPS_LO16;255 case Mips::fixup_Mips_TLSGD:256 return ELF::R_MIPS_TLS_GD;257 case Mips::fixup_Mips_GOTTPREL:258 return ELF::R_MIPS_TLS_GOTTPREL;259 case Mips::fixup_Mips_TPREL_HI:260 return ELF::R_MIPS_TLS_TPREL_HI16;261 case Mips::fixup_Mips_TPREL_LO:262 return ELF::R_MIPS_TLS_TPREL_LO16;263 case Mips::fixup_Mips_TLSLDM:264 return ELF::R_MIPS_TLS_LDM;265 case Mips::fixup_Mips_DTPREL_HI:266 return ELF::R_MIPS_TLS_DTPREL_HI16;267 case Mips::fixup_Mips_DTPREL_LO:268 return ELF::R_MIPS_TLS_DTPREL_LO16;269 case Mips::fixup_Mips_GOT_PAGE:270 return ELF::R_MIPS_GOT_PAGE;271 case Mips::fixup_Mips_GOT_OFST:272 return ELF::R_MIPS_GOT_OFST;273 case Mips::fixup_Mips_GOT_DISP:274 return ELF::R_MIPS_GOT_DISP;275 case Mips::fixup_Mips_GPOFF_HI:276 return setRTypes(ELF::R_MIPS_GPREL16, ELF::R_MIPS_SUB, ELF::R_MIPS_HI16);277 case Mips::fixup_MICROMIPS_GPOFF_HI:278 return setRTypes(ELF::R_MICROMIPS_GPREL16, ELF::R_MICROMIPS_SUB,279 ELF::R_MICROMIPS_HI16);280 case Mips::fixup_Mips_GPOFF_LO:281 return setRTypes(ELF::R_MIPS_GPREL16, ELF::R_MIPS_SUB, ELF::R_MIPS_LO16);282 case Mips::fixup_MICROMIPS_GPOFF_LO:283 return setRTypes(ELF::R_MICROMIPS_GPREL16, ELF::R_MICROMIPS_SUB,284 ELF::R_MICROMIPS_LO16);285 case Mips::fixup_Mips_HIGHER:286 return ELF::R_MIPS_HIGHER;287 case Mips::fixup_Mips_HIGHEST:288 return ELF::R_MIPS_HIGHEST;289 case Mips::fixup_Mips_SUB:290 return ELF::R_MIPS_SUB;291 case Mips::fixup_Mips_GOT_HI16:292 return ELF::R_MIPS_GOT_HI16;293 case Mips::fixup_Mips_GOT_LO16:294 return ELF::R_MIPS_GOT_LO16;295 case Mips::fixup_Mips_CALL_HI16:296 return ELF::R_MIPS_CALL_HI16;297 case Mips::fixup_Mips_CALL_LO16:298 return ELF::R_MIPS_CALL_LO16;299 case Mips::fixup_MICROMIPS_26_S1:300 return ELF::R_MICROMIPS_26_S1;301 case Mips::fixup_MICROMIPS_HI16:302 return ELF::R_MICROMIPS_HI16;303 case Mips::fixup_MICROMIPS_LO16:304 return ELF::R_MICROMIPS_LO16;305 case Mips::fixup_MICROMIPS_GOT16:306 return ELF::R_MICROMIPS_GOT16;307 case Mips::fixup_MICROMIPS_CALL16:308 return ELF::R_MICROMIPS_CALL16;309 case Mips::fixup_MICROMIPS_GOT_DISP:310 return ELF::R_MICROMIPS_GOT_DISP;311 case Mips::fixup_MICROMIPS_GOT_PAGE:312 return ELF::R_MICROMIPS_GOT_PAGE;313 case Mips::fixup_MICROMIPS_GOT_OFST:314 return ELF::R_MICROMIPS_GOT_OFST;315 case Mips::fixup_MICROMIPS_TLS_GD:316 return ELF::R_MICROMIPS_TLS_GD;317 case Mips::fixup_MICROMIPS_TLS_LDM:318 return ELF::R_MICROMIPS_TLS_LDM;319 case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16:320 return ELF::R_MICROMIPS_TLS_DTPREL_HI16;321 case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16:322 return ELF::R_MICROMIPS_TLS_DTPREL_LO16;323 case Mips::fixup_MICROMIPS_GOTTPREL:324 return ELF::R_MICROMIPS_TLS_GOTTPREL;325 case Mips::fixup_MICROMIPS_TLS_TPREL_HI16:326 return ELF::R_MICROMIPS_TLS_TPREL_HI16;327 case Mips::fixup_MICROMIPS_TLS_TPREL_LO16:328 return ELF::R_MICROMIPS_TLS_TPREL_LO16;329 case Mips::fixup_MICROMIPS_SUB:330 return ELF::R_MICROMIPS_SUB;331 case Mips::fixup_MICROMIPS_HIGHER:332 return ELF::R_MICROMIPS_HIGHER;333 case Mips::fixup_MICROMIPS_HIGHEST:334 return ELF::R_MICROMIPS_HIGHEST;335 case Mips::fixup_Mips_JALR:336 return ELF::R_MIPS_JALR;337 case Mips::fixup_MICROMIPS_JALR:338 return ELF::R_MICROMIPS_JALR;339 }340 341 reportError(Fixup.getLoc(), "unsupported relocation type");342 return ELF::R_MIPS_NONE;343}344 345/// Sort relocation table entries by offset except where another order is346/// required by the MIPS ABI.347///348/// MIPS has a few relocations that have an AHL component in the expression used349/// to evaluate them. This AHL component is an addend with the same number of350/// bits as a symbol value but not all of our ABI's are able to supply a351/// sufficiently sized addend in a single relocation.352///353/// The O32 ABI for example, uses REL relocations which store the addend in the354/// section data. All the relocations with AHL components affect 16-bit fields355/// so the addend for a single relocation is limited to 16-bit. This ABI356/// resolves the limitation by linking relocations (e.g. R_MIPS_HI16 and357/// R_MIPS_LO16) and distributing the addend between the linked relocations. The358/// ABI mandates that such relocations must be next to each other in a359/// particular order (e.g. R_MIPS_HI16 must be immediately followed by a360/// matching R_MIPS_LO16) but the rule is less strict in practice.361///362/// The de facto standard is lenient in the following ways:363/// - 'Immediately following' does not refer to the next relocation entry but364/// the next matching relocation.365/// - There may be multiple high parts relocations for one low part relocation.366/// - There may be multiple low part relocations for one high part relocation.367/// - The AHL addend in each part does not have to be exactly equal as long as368/// the difference does not affect the carry bit from bit 15 into 16. This is369/// to allow, for example, the use of %lo(foo) and %lo(foo+4) when loading370/// both halves of a long long.371///372/// See getMatchingLoType() for a description of which high part relocations373/// match which low part relocations. One particular thing to note is that374/// R_MIPS_GOT16 and similar only have AHL addends if they refer to local375/// symbols.376///377/// It should also be noted that this function is not affected by whether378/// the symbol was kept or rewritten into a section-relative equivalent. We379/// always match using the expressions from the source.380void MipsELFObjectWriter::sortRelocs(std::vector<ELFRelocationEntry> &Relocs) {381 // We do not need to sort the relocation table for RELA relocations which382 // N32/N64 uses as the relocation addend contains the value we require,383 // rather than it being split across a pair of relocations.384 if (hasRelocationAddend())385 return;386 387 // Sort relocations by r_offset. There might be more than one at an offset388 // with composed relocations or .reloc directives.389 llvm::stable_sort(390 Relocs, [](const ELFRelocationEntry &A, const ELFRelocationEntry &B) {391 return A.Offset < B.Offset;392 });393 394 // Place relocations in a list for reorder convenience. Hi16 contains the395 // iterators of high-part relocations.396 std::list<MipsRelocationEntry> Sorted;397 SmallVector<std::list<MipsRelocationEntry>::iterator, 0> Hi16;398 for (auto &R : Relocs) {399 Sorted.push_back(R);400 if (getMatchingLoType(R) != ELF::R_MIPS_NONE)401 Hi16.push_back(std::prev(Sorted.end()));402 }403 404 for (auto I : Hi16) {405 auto &R = I->R;406 unsigned MatchingType = getMatchingLoType(R);407 // If the next relocation is a perfect match, continue;408 if (std::next(I) != Sorted.end() &&409 isMatchingReloc(MatchingType, R, std::next(I)->R))410 continue;411 // Otherwise, find the best matching low-part relocation with the following412 // criteria. It must have the same symbol and its addend is no lower than413 // that of the current high-part.414 //415 // (1) %lo with a smaller offset is preferred.416 // (2) %lo with the same offset that is unmatched is preferred.417 // (3) later %lo is preferred.418 auto Best = Sorted.end();419 for (auto J = Sorted.begin(); J != Sorted.end(); ++J) {420 auto &R1 = J->R;421 if (R1.Type == MatchingType && R.Symbol == R1.Symbol &&422 R.Addend <= R1.Addend &&423 (Best == Sorted.end() || R1.Addend < Best->R.Addend ||424 (!Best->Matched && R1.Addend == Best->R.Addend)))425 Best = J;426 }427 if (Best != Sorted.end() && R.Addend == Best->R.Addend)428 Best->Matched = true;429 430 // Move the high-part before the low-part, or if not found, the end of the431 // list. The unmatched high-part will lead to a linker warning/error.432 Sorted.splice(Best, Sorted, I);433 }434 435 assert(Relocs.size() == Sorted.size() && "Some relocs were not consumed");436 437 // Overwrite the original vector with the sorted elements.438 unsigned CopyTo = 0;439 for (const auto &R : Sorted)440 Relocs[CopyTo++] = R.R;441}442 443bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCValue &V,444 unsigned Type) const {445 // If it's a compound relocation for N64 then we need the relocation if any446 // sub-relocation needs it.447 if (!isUInt<8>(Type))448 return needsRelocateWithSymbol(V, Type & 0xff) ||449 needsRelocateWithSymbol(V, (Type >> 8) & 0xff) ||450 needsRelocateWithSymbol(V, (Type >> 16) & 0xff);451 452 auto *Sym = static_cast<const MCSymbolELF *>(V.getAddSym());453 switch (Type) {454 default:455 errs() << Type << "\n";456 llvm_unreachable("Unexpected relocation");457 return true;458 459 // This relocation doesn't affect the section data.460 case ELF::R_MIPS_NONE:461 return false;462 463 // On REL ABI's (e.g. O32), these relocations form pairs. The pairing is done464 // by the static linker by matching the symbol and offset.465 // We only see one relocation at a time but it's still safe to relocate with466 // the section so long as both relocations make the same decision.467 //468 // Some older linkers may require the symbol for particular cases. Such cases469 // are not supported yet but can be added as required.470 case ELF::R_MIPS_GOT16:471 case ELF::R_MIPS16_GOT16:472 case ELF::R_MICROMIPS_GOT16:473 case ELF::R_MIPS_HIGHER:474 case ELF::R_MIPS_HIGHEST:475 case ELF::R_MIPS_HI16:476 case ELF::R_MIPS16_HI16:477 case ELF::R_MICROMIPS_HI16:478 case ELF::R_MIPS_LO16:479 case ELF::R_MIPS16_LO16:480 case ELF::R_MICROMIPS_LO16:481 // FIXME: It should be safe to return false for the STO_MIPS_MICROMIPS but482 // we neglect to handle the adjustment to the LSB of the addend that483 // it causes in applyFixup() and similar.484 if (Sym->getOther() & ELF::STO_MIPS_MICROMIPS)485 return true;486 return false;487 488 case ELF::R_MIPS_GOT_PAGE:489 case ELF::R_MICROMIPS_GOT_PAGE:490 case ELF::R_MIPS_GOT_OFST:491 case ELF::R_MICROMIPS_GOT_OFST:492 case ELF::R_MIPS_16:493 case ELF::R_MIPS_32:494 case ELF::R_MIPS_GPREL32:495 if (Sym->getOther() & ELF::STO_MIPS_MICROMIPS)496 return true;497 [[fallthrough]];498 case ELF::R_MIPS_26:499 case ELF::R_MIPS_64:500 case ELF::R_MIPS_GPREL16:501 case ELF::R_MIPS_PC16:502 case ELF::R_MIPS_SUB:503 return false;504 505 // FIXME: Many of these relocations should probably return false but this506 // hasn't been confirmed to be safe yet.507 case ELF::R_MIPS_REL32:508 case ELF::R_MIPS_LITERAL:509 case ELF::R_MIPS_CALL16:510 case ELF::R_MIPS_SHIFT5:511 case ELF::R_MIPS_SHIFT6:512 case ELF::R_MIPS_GOT_DISP:513 case ELF::R_MIPS_GOT_HI16:514 case ELF::R_MIPS_GOT_LO16:515 case ELF::R_MIPS_INSERT_A:516 case ELF::R_MIPS_INSERT_B:517 case ELF::R_MIPS_DELETE:518 case ELF::R_MIPS_CALL_HI16:519 case ELF::R_MIPS_CALL_LO16:520 case ELF::R_MIPS_SCN_DISP:521 case ELF::R_MIPS_REL16:522 case ELF::R_MIPS_ADD_IMMEDIATE:523 case ELF::R_MIPS_PJUMP:524 case ELF::R_MIPS_RELGOT:525 case ELF::R_MIPS_JALR:526 case ELF::R_MIPS_TLS_DTPMOD32:527 case ELF::R_MIPS_TLS_DTPREL32:528 case ELF::R_MIPS_TLS_DTPMOD64:529 case ELF::R_MIPS_TLS_DTPREL64:530 case ELF::R_MIPS_TLS_GD:531 case ELF::R_MIPS_TLS_LDM:532 case ELF::R_MIPS_TLS_DTPREL_HI16:533 case ELF::R_MIPS_TLS_DTPREL_LO16:534 case ELF::R_MIPS_TLS_GOTTPREL:535 case ELF::R_MIPS_TLS_TPREL32:536 case ELF::R_MIPS_TLS_TPREL64:537 case ELF::R_MIPS_TLS_TPREL_HI16:538 case ELF::R_MIPS_TLS_TPREL_LO16:539 case ELF::R_MIPS_GLOB_DAT:540 case ELF::R_MIPS_PC21_S2:541 case ELF::R_MIPS_PC26_S2:542 case ELF::R_MIPS_PC18_S3:543 case ELF::R_MIPS_PC19_S2:544 case ELF::R_MIPS_PCHI16:545 case ELF::R_MIPS_PCLO16:546 case ELF::R_MIPS_COPY:547 case ELF::R_MIPS_JUMP_SLOT:548 case ELF::R_MIPS_NUM:549 case ELF::R_MIPS_PC32:550 case ELF::R_MIPS_EH:551 case ELF::R_MICROMIPS_26_S1:552 case ELF::R_MICROMIPS_GPREL16:553 case ELF::R_MICROMIPS_LITERAL:554 case ELF::R_MICROMIPS_PC7_S1:555 case ELF::R_MICROMIPS_PC10_S1:556 case ELF::R_MICROMIPS_PC16_S1:557 case ELF::R_MICROMIPS_CALL16:558 case ELF::R_MICROMIPS_GOT_DISP:559 case ELF::R_MICROMIPS_GOT_HI16:560 case ELF::R_MICROMIPS_GOT_LO16:561 case ELF::R_MICROMIPS_SUB:562 case ELF::R_MICROMIPS_HIGHER:563 case ELF::R_MICROMIPS_HIGHEST:564 case ELF::R_MICROMIPS_CALL_HI16:565 case ELF::R_MICROMIPS_CALL_LO16:566 case ELF::R_MICROMIPS_SCN_DISP:567 case ELF::R_MICROMIPS_JALR:568 case ELF::R_MICROMIPS_HI0_LO16:569 case ELF::R_MICROMIPS_TLS_GD:570 case ELF::R_MICROMIPS_TLS_LDM:571 case ELF::R_MICROMIPS_TLS_DTPREL_HI16:572 case ELF::R_MICROMIPS_TLS_DTPREL_LO16:573 case ELF::R_MICROMIPS_TLS_GOTTPREL:574 case ELF::R_MICROMIPS_TLS_TPREL_HI16:575 case ELF::R_MICROMIPS_TLS_TPREL_LO16:576 case ELF::R_MICROMIPS_GPREL7_S2:577 case ELF::R_MICROMIPS_PC23_S2:578 case ELF::R_MICROMIPS_PC21_S1:579 case ELF::R_MICROMIPS_PC26_S1:580 case ELF::R_MICROMIPS_PC18_S3:581 case ELF::R_MICROMIPS_PC19_S2:582 return true;583 584 // FIXME: Many of these should probably return false but MIPS16 isn't585 // supported by the integrated assembler.586 case ELF::R_MIPS16_26:587 case ELF::R_MIPS16_GPREL:588 case ELF::R_MIPS16_CALL16:589 case ELF::R_MIPS16_TLS_GD:590 case ELF::R_MIPS16_TLS_LDM:591 case ELF::R_MIPS16_TLS_DTPREL_HI16:592 case ELF::R_MIPS16_TLS_DTPREL_LO16:593 case ELF::R_MIPS16_TLS_GOTTPREL:594 case ELF::R_MIPS16_TLS_TPREL_HI16:595 case ELF::R_MIPS16_TLS_TPREL_LO16:596 llvm_unreachable("Unsupported MIPS16 relocation");597 return true;598 }599}600 601std::unique_ptr<MCObjectTargetWriter>602llvm::createMipsELFObjectWriter(const Triple &TT, bool IsN32) {603 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());604 bool IsN64 = TT.isArch64Bit() && !IsN32;605 bool HasRelocationAddend = TT.isArch64Bit();606 return std::make_unique<MipsELFObjectWriter>(OSABI, HasRelocationAddend,607 IsN64);608}609