brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.6 KiB · 680d279 Raw
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