10b57cec5SDimitry Andric //===-- MipsELFObjectWriter.cpp - Mips ELF Writer -------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "MCTargetDesc/MipsFixupKinds.h" 100b57cec5SDimitry Andric #include "MCTargetDesc/MipsMCTargetDesc.h" 110b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 120b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 130b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 140b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h" 150b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 180b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 190b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 200b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 210b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 220b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 230b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 240b57cec5SDimitry Andric #include <algorithm> 250b57cec5SDimitry Andric #include <cassert> 260b57cec5SDimitry Andric #include <cstdint> 270b57cec5SDimitry Andric #include <iterator> 280b57cec5SDimitry Andric #include <list> 290b57cec5SDimitry Andric #include <utility> 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric #define DEBUG_TYPE "mips-elf-object-writer" 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric using namespace llvm; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric namespace { 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric /// Holds additional information needed by the relocation ordering algorithm. 380b57cec5SDimitry Andric struct MipsRelocationEntry { 390b57cec5SDimitry Andric const ELFRelocationEntry R; ///< The relocation. 400b57cec5SDimitry Andric bool Matched = false; ///< Is this relocation part of a match. 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric MipsRelocationEntry(const ELFRelocationEntry &R) : R(R) {} 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric void print(raw_ostream &Out) const { 450b57cec5SDimitry Andric R.print(Out); 460b57cec5SDimitry Andric Out << ", Matched=" << Matched; 470b57cec5SDimitry Andric } 480b57cec5SDimitry Andric }; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric #ifndef NDEBUG 510b57cec5SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const MipsRelocationEntry &RHS) { 520b57cec5SDimitry Andric RHS.print(OS); 530b57cec5SDimitry Andric return OS; 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric #endif 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric class MipsELFObjectWriter : public MCELFObjectTargetWriter { 580b57cec5SDimitry Andric public: 590b57cec5SDimitry Andric MipsELFObjectWriter(uint8_t OSABI, bool HasRelocationAddend, bool Is64); 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric ~MipsELFObjectWriter() override = default; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 640b57cec5SDimitry Andric const MCFixup &Fixup, bool IsPCRel) const override; 655f757f3fSDimitry Andric bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, 660b57cec5SDimitry Andric unsigned Type) const override; 670b57cec5SDimitry Andric void sortRelocs(const MCAssembler &Asm, 680b57cec5SDimitry Andric std::vector<ELFRelocationEntry> &Relocs) override; 690b57cec5SDimitry Andric }; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric /// The possible results of the Predicate function used by find_best. 720b57cec5SDimitry Andric enum FindBestPredicateResult { 730b57cec5SDimitry Andric FindBest_NoMatch = 0, ///< The current element is not a match. 740b57cec5SDimitry Andric FindBest_Match, ///< The current element is a match but better ones are 750b57cec5SDimitry Andric /// possible. 760b57cec5SDimitry Andric FindBest_PerfectMatch, ///< The current element is an unbeatable match. 770b57cec5SDimitry Andric }; 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric } // end anonymous namespace 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric /// Copy elements in the range [First, Last) to d1 when the predicate is true or 820b57cec5SDimitry Andric /// d2 when the predicate is false. This is essentially both std::copy_if and 830b57cec5SDimitry Andric /// std::remove_copy_if combined into a single pass. 840b57cec5SDimitry Andric template <class InputIt, class OutputIt1, class OutputIt2, class UnaryPredicate> 850b57cec5SDimitry Andric static std::pair<OutputIt1, OutputIt2> copy_if_else(InputIt First, InputIt Last, 860b57cec5SDimitry Andric OutputIt1 d1, OutputIt2 d2, 870b57cec5SDimitry Andric UnaryPredicate Predicate) { 880b57cec5SDimitry Andric for (InputIt I = First; I != Last; ++I) { 890b57cec5SDimitry Andric if (Predicate(*I)) { 900b57cec5SDimitry Andric *d1 = *I; 910b57cec5SDimitry Andric d1++; 920b57cec5SDimitry Andric } else { 930b57cec5SDimitry Andric *d2 = *I; 940b57cec5SDimitry Andric d2++; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric return std::make_pair(d1, d2); 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric /// Find the best match in the range [First, Last). 1020b57cec5SDimitry Andric /// 1030b57cec5SDimitry Andric /// An element matches when Predicate(X) returns FindBest_Match or 1040b57cec5SDimitry Andric /// FindBest_PerfectMatch. A value of FindBest_PerfectMatch also terminates 1050b57cec5SDimitry Andric /// the search. BetterThan(A, B) is a comparator that returns true when A is a 1060b57cec5SDimitry Andric /// better match than B. The return value is the position of the best match. 1070b57cec5SDimitry Andric /// 1080b57cec5SDimitry Andric /// This is similar to std::find_if but finds the best of multiple possible 1090b57cec5SDimitry Andric /// matches. 1100b57cec5SDimitry Andric template <class InputIt, class UnaryPredicate, class Comparator> 1110b57cec5SDimitry Andric static InputIt find_best(InputIt First, InputIt Last, UnaryPredicate Predicate, 1120b57cec5SDimitry Andric Comparator BetterThan) { 1130b57cec5SDimitry Andric InputIt Best = Last; 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric for (InputIt I = First; I != Last; ++I) { 1160b57cec5SDimitry Andric unsigned Matched = Predicate(*I); 1170b57cec5SDimitry Andric if (Matched != FindBest_NoMatch) { 1180b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << std::distance(First, I) << " is a match ("; 1190b57cec5SDimitry Andric I->print(dbgs()); dbgs() << ")\n"); 1200b57cec5SDimitry Andric if (Best == Last || BetterThan(*I, *Best)) { 1210b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << ".. and it beats the last one\n"); 1220b57cec5SDimitry Andric Best = I; 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric if (Matched == FindBest_PerfectMatch) { 1260b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << ".. and it is unbeatable\n"); 1270b57cec5SDimitry Andric break; 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric } 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric return Best; 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric /// Determine the low relocation that matches the given relocation. 1350b57cec5SDimitry Andric /// If the relocation does not need a low relocation then the return value 1360b57cec5SDimitry Andric /// is ELF::R_MIPS_NONE. 1370b57cec5SDimitry Andric /// 1380b57cec5SDimitry Andric /// The relocations that need a matching low part are 1390b57cec5SDimitry Andric /// R_(MIPS|MICROMIPS|MIPS16)_HI16 for all symbols and 1400b57cec5SDimitry Andric /// R_(MIPS|MICROMIPS|MIPS16)_GOT16 for local symbols only. 1410b57cec5SDimitry Andric static unsigned getMatchingLoType(const ELFRelocationEntry &Reloc) { 1420b57cec5SDimitry Andric unsigned Type = Reloc.Type; 1430b57cec5SDimitry Andric if (Type == ELF::R_MIPS_HI16) 1440b57cec5SDimitry Andric return ELF::R_MIPS_LO16; 1450b57cec5SDimitry Andric if (Type == ELF::R_MICROMIPS_HI16) 1460b57cec5SDimitry Andric return ELF::R_MICROMIPS_LO16; 1470b57cec5SDimitry Andric if (Type == ELF::R_MIPS16_HI16) 1480b57cec5SDimitry Andric return ELF::R_MIPS16_LO16; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric if (Reloc.OriginalSymbol && 1510b57cec5SDimitry Andric Reloc.OriginalSymbol->getBinding() != ELF::STB_LOCAL) 1520b57cec5SDimitry Andric return ELF::R_MIPS_NONE; 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric if (Type == ELF::R_MIPS_GOT16) 1550b57cec5SDimitry Andric return ELF::R_MIPS_LO16; 1560b57cec5SDimitry Andric if (Type == ELF::R_MICROMIPS_GOT16) 1570b57cec5SDimitry Andric return ELF::R_MICROMIPS_LO16; 1580b57cec5SDimitry Andric if (Type == ELF::R_MIPS16_GOT16) 1590b57cec5SDimitry Andric return ELF::R_MIPS16_LO16; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric return ELF::R_MIPS_NONE; 1620b57cec5SDimitry Andric } 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric /// Determine whether a relocation (X) matches the one given in R. 1650b57cec5SDimitry Andric /// 1660b57cec5SDimitry Andric /// A relocation matches if: 1670b57cec5SDimitry Andric /// - It's type matches that of a corresponding low part. This is provided in 1680b57cec5SDimitry Andric /// MatchingType for efficiency. 1690b57cec5SDimitry Andric /// - It's based on the same symbol. 1700b57cec5SDimitry Andric /// - It's offset of greater or equal to that of the one given in R. 1710b57cec5SDimitry Andric /// It should be noted that this rule assumes the programmer does not use 1720b57cec5SDimitry Andric /// offsets that exceed the alignment of the symbol. The carry-bit will be 1730b57cec5SDimitry Andric /// incorrect if this is not true. 1740b57cec5SDimitry Andric /// 1750b57cec5SDimitry Andric /// A matching relocation is unbeatable if: 1760b57cec5SDimitry Andric /// - It is not already involved in a match. 1770b57cec5SDimitry Andric /// - It's offset is exactly that of the one given in R. 1780b57cec5SDimitry Andric static FindBestPredicateResult isMatchingReloc(const MipsRelocationEntry &X, 1790b57cec5SDimitry Andric const ELFRelocationEntry &R, 1800b57cec5SDimitry Andric unsigned MatchingType) { 1810b57cec5SDimitry Andric if (X.R.Type == MatchingType && X.R.OriginalSymbol == R.OriginalSymbol) { 1820b57cec5SDimitry Andric if (!X.Matched && 1830b57cec5SDimitry Andric X.R.OriginalAddend == R.OriginalAddend) 1840b57cec5SDimitry Andric return FindBest_PerfectMatch; 1850b57cec5SDimitry Andric else if (X.R.OriginalAddend >= R.OriginalAddend) 1860b57cec5SDimitry Andric return FindBest_Match; 1870b57cec5SDimitry Andric } 1880b57cec5SDimitry Andric return FindBest_NoMatch; 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric /// Determine whether Candidate or PreviousBest is the better match. 1920b57cec5SDimitry Andric /// The return value is true if Candidate is the better match. 1930b57cec5SDimitry Andric /// 1940b57cec5SDimitry Andric /// A matching relocation is a better match if: 1950b57cec5SDimitry Andric /// - It has a smaller addend. 1960b57cec5SDimitry Andric /// - It is not already involved in a match. 1970b57cec5SDimitry Andric static bool compareMatchingRelocs(const MipsRelocationEntry &Candidate, 1980b57cec5SDimitry Andric const MipsRelocationEntry &PreviousBest) { 1990b57cec5SDimitry Andric if (Candidate.R.OriginalAddend != PreviousBest.R.OriginalAddend) 2000b57cec5SDimitry Andric return Candidate.R.OriginalAddend < PreviousBest.R.OriginalAddend; 2010b57cec5SDimitry Andric return PreviousBest.Matched && !Candidate.Matched; 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric #ifndef NDEBUG 2050b57cec5SDimitry Andric /// Print all the relocations. 2060b57cec5SDimitry Andric template <class Container> 2070b57cec5SDimitry Andric static void dumpRelocs(const char *Prefix, const Container &Relocs) { 2080b57cec5SDimitry Andric for (const auto &R : Relocs) 2090b57cec5SDimitry Andric dbgs() << Prefix << R << "\n"; 2100b57cec5SDimitry Andric } 2110b57cec5SDimitry Andric #endif 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI, 2140b57cec5SDimitry Andric bool HasRelocationAddend, bool Is64) 2150b57cec5SDimitry Andric : MCELFObjectTargetWriter(Is64, OSABI, ELF::EM_MIPS, HasRelocationAddend) {} 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, 2180b57cec5SDimitry Andric const MCValue &Target, 2190b57cec5SDimitry Andric const MCFixup &Fixup, 2200b57cec5SDimitry Andric bool IsPCRel) const { 2210b57cec5SDimitry Andric // Determine the type of the relocation. 2228bcb0991SDimitry Andric unsigned Kind = Fixup.getTargetKind(); 22381ad6265SDimitry Andric if (Kind >= FirstLiteralRelocationKind) 22481ad6265SDimitry Andric return Kind - FirstLiteralRelocationKind; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric switch (Kind) { 2270b57cec5SDimitry Andric case FK_NONE: 2280b57cec5SDimitry Andric return ELF::R_MIPS_NONE; 2290b57cec5SDimitry Andric case FK_Data_1: 2300b57cec5SDimitry Andric Ctx.reportError(Fixup.getLoc(), 2310b57cec5SDimitry Andric "MIPS does not support one byte relocations"); 2320b57cec5SDimitry Andric return ELF::R_MIPS_NONE; 2330b57cec5SDimitry Andric case Mips::fixup_Mips_16: 2340b57cec5SDimitry Andric case FK_Data_2: 2350b57cec5SDimitry Andric return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16; 2360b57cec5SDimitry Andric case Mips::fixup_Mips_32: 2370b57cec5SDimitry Andric case FK_Data_4: 2380b57cec5SDimitry Andric return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32; 2395ffd83dbSDimitry Andric case Mips::fixup_Mips_64: 2405ffd83dbSDimitry Andric case FK_Data_8: 2415ffd83dbSDimitry Andric return IsPCRel 2425ffd83dbSDimitry Andric ? setRTypes(ELF::R_MIPS_PC32, ELF::R_MIPS_64, ELF::R_MIPS_NONE) 2435ffd83dbSDimitry Andric : (unsigned)ELF::R_MIPS_64; 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric if (IsPCRel) { 2470b57cec5SDimitry Andric switch (Kind) { 2480b57cec5SDimitry Andric case Mips::fixup_Mips_Branch_PCRel: 2490b57cec5SDimitry Andric case Mips::fixup_Mips_PC16: 2500b57cec5SDimitry Andric return ELF::R_MIPS_PC16; 2510b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_PC7_S1: 2520b57cec5SDimitry Andric return ELF::R_MICROMIPS_PC7_S1; 2530b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_PC10_S1: 2540b57cec5SDimitry Andric return ELF::R_MICROMIPS_PC10_S1; 2550b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_PC16_S1: 2560b57cec5SDimitry Andric return ELF::R_MICROMIPS_PC16_S1; 2570b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_PC26_S1: 2580b57cec5SDimitry Andric return ELF::R_MICROMIPS_PC26_S1; 2590b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_PC19_S2: 2600b57cec5SDimitry Andric return ELF::R_MICROMIPS_PC19_S2; 2610b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_PC18_S3: 2620b57cec5SDimitry Andric return ELF::R_MICROMIPS_PC18_S3; 2630b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_PC21_S1: 2640b57cec5SDimitry Andric return ELF::R_MICROMIPS_PC21_S1; 2650b57cec5SDimitry Andric case Mips::fixup_MIPS_PC19_S2: 2660b57cec5SDimitry Andric return ELF::R_MIPS_PC19_S2; 2670b57cec5SDimitry Andric case Mips::fixup_MIPS_PC18_S3: 2680b57cec5SDimitry Andric return ELF::R_MIPS_PC18_S3; 2690b57cec5SDimitry Andric case Mips::fixup_MIPS_PC21_S2: 2700b57cec5SDimitry Andric return ELF::R_MIPS_PC21_S2; 2710b57cec5SDimitry Andric case Mips::fixup_MIPS_PC26_S2: 2720b57cec5SDimitry Andric return ELF::R_MIPS_PC26_S2; 2730b57cec5SDimitry Andric case Mips::fixup_MIPS_PCHI16: 2740b57cec5SDimitry Andric return ELF::R_MIPS_PCHI16; 2750b57cec5SDimitry Andric case Mips::fixup_MIPS_PCLO16: 2760b57cec5SDimitry Andric return ELF::R_MIPS_PCLO16; 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric llvm_unreachable("invalid PC-relative fixup kind!"); 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric switch (Kind) { 2830b57cec5SDimitry Andric case FK_DTPRel_4: 2840b57cec5SDimitry Andric return ELF::R_MIPS_TLS_DTPREL32; 2850b57cec5SDimitry Andric case FK_DTPRel_8: 2860b57cec5SDimitry Andric return ELF::R_MIPS_TLS_DTPREL64; 2870b57cec5SDimitry Andric case FK_TPRel_4: 2880b57cec5SDimitry Andric return ELF::R_MIPS_TLS_TPREL32; 2890b57cec5SDimitry Andric case FK_TPRel_8: 2900b57cec5SDimitry Andric return ELF::R_MIPS_TLS_TPREL64; 2910b57cec5SDimitry Andric case FK_GPRel_4: 2925ffd83dbSDimitry Andric return setRTypes(ELF::R_MIPS_GPREL32, 2935ffd83dbSDimitry Andric is64Bit() ? ELF::R_MIPS_64 : ELF::R_MIPS_NONE, 2945ffd83dbSDimitry Andric ELF::R_MIPS_NONE); 2950b57cec5SDimitry Andric case Mips::fixup_Mips_GPREL16: 2960b57cec5SDimitry Andric return ELF::R_MIPS_GPREL16; 2970b57cec5SDimitry Andric case Mips::fixup_Mips_26: 2980b57cec5SDimitry Andric return ELF::R_MIPS_26; 2990b57cec5SDimitry Andric case Mips::fixup_Mips_CALL16: 3000b57cec5SDimitry Andric return ELF::R_MIPS_CALL16; 3010b57cec5SDimitry Andric case Mips::fixup_Mips_GOT: 3020b57cec5SDimitry Andric return ELF::R_MIPS_GOT16; 3030b57cec5SDimitry Andric case Mips::fixup_Mips_HI16: 3040b57cec5SDimitry Andric return ELF::R_MIPS_HI16; 3050b57cec5SDimitry Andric case Mips::fixup_Mips_LO16: 3060b57cec5SDimitry Andric return ELF::R_MIPS_LO16; 3070b57cec5SDimitry Andric case Mips::fixup_Mips_TLSGD: 3080b57cec5SDimitry Andric return ELF::R_MIPS_TLS_GD; 3090b57cec5SDimitry Andric case Mips::fixup_Mips_GOTTPREL: 3100b57cec5SDimitry Andric return ELF::R_MIPS_TLS_GOTTPREL; 3110b57cec5SDimitry Andric case Mips::fixup_Mips_TPREL_HI: 3120b57cec5SDimitry Andric return ELF::R_MIPS_TLS_TPREL_HI16; 3130b57cec5SDimitry Andric case Mips::fixup_Mips_TPREL_LO: 3140b57cec5SDimitry Andric return ELF::R_MIPS_TLS_TPREL_LO16; 3150b57cec5SDimitry Andric case Mips::fixup_Mips_TLSLDM: 3160b57cec5SDimitry Andric return ELF::R_MIPS_TLS_LDM; 3170b57cec5SDimitry Andric case Mips::fixup_Mips_DTPREL_HI: 3180b57cec5SDimitry Andric return ELF::R_MIPS_TLS_DTPREL_HI16; 3190b57cec5SDimitry Andric case Mips::fixup_Mips_DTPREL_LO: 3200b57cec5SDimitry Andric return ELF::R_MIPS_TLS_DTPREL_LO16; 3210b57cec5SDimitry Andric case Mips::fixup_Mips_GOT_PAGE: 3220b57cec5SDimitry Andric return ELF::R_MIPS_GOT_PAGE; 3230b57cec5SDimitry Andric case Mips::fixup_Mips_GOT_OFST: 3240b57cec5SDimitry Andric return ELF::R_MIPS_GOT_OFST; 3250b57cec5SDimitry Andric case Mips::fixup_Mips_GOT_DISP: 3260b57cec5SDimitry Andric return ELF::R_MIPS_GOT_DISP; 3275ffd83dbSDimitry Andric case Mips::fixup_Mips_GPOFF_HI: 3285ffd83dbSDimitry Andric return setRTypes(ELF::R_MIPS_GPREL16, ELF::R_MIPS_SUB, ELF::R_MIPS_HI16); 3295ffd83dbSDimitry Andric case Mips::fixup_MICROMIPS_GPOFF_HI: 3305ffd83dbSDimitry Andric return setRTypes(ELF::R_MICROMIPS_GPREL16, ELF::R_MICROMIPS_SUB, 3315ffd83dbSDimitry Andric ELF::R_MICROMIPS_HI16); 3325ffd83dbSDimitry Andric case Mips::fixup_Mips_GPOFF_LO: 3335ffd83dbSDimitry Andric return setRTypes(ELF::R_MIPS_GPREL16, ELF::R_MIPS_SUB, ELF::R_MIPS_LO16); 3345ffd83dbSDimitry Andric case Mips::fixup_MICROMIPS_GPOFF_LO: 3355ffd83dbSDimitry Andric return setRTypes(ELF::R_MICROMIPS_GPREL16, ELF::R_MICROMIPS_SUB, 3365ffd83dbSDimitry Andric ELF::R_MICROMIPS_LO16); 3370b57cec5SDimitry Andric case Mips::fixup_Mips_HIGHER: 3380b57cec5SDimitry Andric return ELF::R_MIPS_HIGHER; 3390b57cec5SDimitry Andric case Mips::fixup_Mips_HIGHEST: 3400b57cec5SDimitry Andric return ELF::R_MIPS_HIGHEST; 3410b57cec5SDimitry Andric case Mips::fixup_Mips_SUB: 3420b57cec5SDimitry Andric return ELF::R_MIPS_SUB; 3430b57cec5SDimitry Andric case Mips::fixup_Mips_GOT_HI16: 3440b57cec5SDimitry Andric return ELF::R_MIPS_GOT_HI16; 3450b57cec5SDimitry Andric case Mips::fixup_Mips_GOT_LO16: 3460b57cec5SDimitry Andric return ELF::R_MIPS_GOT_LO16; 3470b57cec5SDimitry Andric case Mips::fixup_Mips_CALL_HI16: 3480b57cec5SDimitry Andric return ELF::R_MIPS_CALL_HI16; 3490b57cec5SDimitry Andric case Mips::fixup_Mips_CALL_LO16: 3500b57cec5SDimitry Andric return ELF::R_MIPS_CALL_LO16; 3510b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_26_S1: 3520b57cec5SDimitry Andric return ELF::R_MICROMIPS_26_S1; 3530b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_HI16: 3540b57cec5SDimitry Andric return ELF::R_MICROMIPS_HI16; 3550b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_LO16: 3560b57cec5SDimitry Andric return ELF::R_MICROMIPS_LO16; 3570b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_GOT16: 3580b57cec5SDimitry Andric return ELF::R_MICROMIPS_GOT16; 3590b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_CALL16: 3600b57cec5SDimitry Andric return ELF::R_MICROMIPS_CALL16; 3610b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_GOT_DISP: 3620b57cec5SDimitry Andric return ELF::R_MICROMIPS_GOT_DISP; 3630b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_GOT_PAGE: 3640b57cec5SDimitry Andric return ELF::R_MICROMIPS_GOT_PAGE; 3650b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_GOT_OFST: 3660b57cec5SDimitry Andric return ELF::R_MICROMIPS_GOT_OFST; 3670b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_TLS_GD: 3680b57cec5SDimitry Andric return ELF::R_MICROMIPS_TLS_GD; 3690b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_TLS_LDM: 3700b57cec5SDimitry Andric return ELF::R_MICROMIPS_TLS_LDM; 3710b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16: 3720b57cec5SDimitry Andric return ELF::R_MICROMIPS_TLS_DTPREL_HI16; 3730b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16: 3740b57cec5SDimitry Andric return ELF::R_MICROMIPS_TLS_DTPREL_LO16; 3750b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_GOTTPREL: 3760b57cec5SDimitry Andric return ELF::R_MICROMIPS_TLS_GOTTPREL; 3770b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_TLS_TPREL_HI16: 3780b57cec5SDimitry Andric return ELF::R_MICROMIPS_TLS_TPREL_HI16; 3790b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_TLS_TPREL_LO16: 3800b57cec5SDimitry Andric return ELF::R_MICROMIPS_TLS_TPREL_LO16; 3810b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_SUB: 3820b57cec5SDimitry Andric return ELF::R_MICROMIPS_SUB; 3830b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_HIGHER: 3840b57cec5SDimitry Andric return ELF::R_MICROMIPS_HIGHER; 3850b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_HIGHEST: 3860b57cec5SDimitry Andric return ELF::R_MICROMIPS_HIGHEST; 3870b57cec5SDimitry Andric case Mips::fixup_Mips_JALR: 3880b57cec5SDimitry Andric return ELF::R_MIPS_JALR; 3890b57cec5SDimitry Andric case Mips::fixup_MICROMIPS_JALR: 3900b57cec5SDimitry Andric return ELF::R_MICROMIPS_JALR; 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric llvm_unreachable("invalid fixup kind!"); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric /// Sort relocation table entries by offset except where another order is 3970b57cec5SDimitry Andric /// required by the MIPS ABI. 3980b57cec5SDimitry Andric /// 3990b57cec5SDimitry Andric /// MIPS has a few relocations that have an AHL component in the expression used 4000b57cec5SDimitry Andric /// to evaluate them. This AHL component is an addend with the same number of 4010b57cec5SDimitry Andric /// bits as a symbol value but not all of our ABI's are able to supply a 4020b57cec5SDimitry Andric /// sufficiently sized addend in a single relocation. 4030b57cec5SDimitry Andric /// 4040b57cec5SDimitry Andric /// The O32 ABI for example, uses REL relocations which store the addend in the 4050b57cec5SDimitry Andric /// section data. All the relocations with AHL components affect 16-bit fields 4060b57cec5SDimitry Andric /// so the addend for a single relocation is limited to 16-bit. This ABI 4070b57cec5SDimitry Andric /// resolves the limitation by linking relocations (e.g. R_MIPS_HI16 and 4080b57cec5SDimitry Andric /// R_MIPS_LO16) and distributing the addend between the linked relocations. The 4090b57cec5SDimitry Andric /// ABI mandates that such relocations must be next to each other in a 4100b57cec5SDimitry Andric /// particular order (e.g. R_MIPS_HI16 must be immediately followed by a 4110b57cec5SDimitry Andric /// matching R_MIPS_LO16) but the rule is less strict in practice. 4120b57cec5SDimitry Andric /// 4130b57cec5SDimitry Andric /// The de facto standard is lenient in the following ways: 4140b57cec5SDimitry Andric /// - 'Immediately following' does not refer to the next relocation entry but 4150b57cec5SDimitry Andric /// the next matching relocation. 4160b57cec5SDimitry Andric /// - There may be multiple high parts relocations for one low part relocation. 4170b57cec5SDimitry Andric /// - There may be multiple low part relocations for one high part relocation. 4180b57cec5SDimitry Andric /// - The AHL addend in each part does not have to be exactly equal as long as 4190b57cec5SDimitry Andric /// the difference does not affect the carry bit from bit 15 into 16. This is 4200b57cec5SDimitry Andric /// to allow, for example, the use of %lo(foo) and %lo(foo+4) when loading 4210b57cec5SDimitry Andric /// both halves of a long long. 4220b57cec5SDimitry Andric /// 4230b57cec5SDimitry Andric /// See getMatchingLoType() for a description of which high part relocations 4240b57cec5SDimitry Andric /// match which low part relocations. One particular thing to note is that 4250b57cec5SDimitry Andric /// R_MIPS_GOT16 and similar only have AHL addends if they refer to local 4260b57cec5SDimitry Andric /// symbols. 4270b57cec5SDimitry Andric /// 4280b57cec5SDimitry Andric /// It should also be noted that this function is not affected by whether 4290b57cec5SDimitry Andric /// the symbol was kept or rewritten into a section-relative equivalent. We 4300b57cec5SDimitry Andric /// always match using the expressions from the source. 4310b57cec5SDimitry Andric void MipsELFObjectWriter::sortRelocs(const MCAssembler &Asm, 4320b57cec5SDimitry Andric std::vector<ELFRelocationEntry> &Relocs) { 4330b57cec5SDimitry Andric // We do not need to sort the relocation table for RELA relocations which 4340b57cec5SDimitry Andric // N32/N64 uses as the relocation addend contains the value we require, 4350b57cec5SDimitry Andric // rather than it being split across a pair of relocations. 4360b57cec5SDimitry Andric if (hasRelocationAddend()) 4370b57cec5SDimitry Andric return; 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric if (Relocs.size() < 2) 4400b57cec5SDimitry Andric return; 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric // Sort relocations by the address they are applied to. 4430b57cec5SDimitry Andric llvm::sort(Relocs, 4440b57cec5SDimitry Andric [](const ELFRelocationEntry &A, const ELFRelocationEntry &B) { 4450b57cec5SDimitry Andric return A.Offset < B.Offset; 4460b57cec5SDimitry Andric }); 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric std::list<MipsRelocationEntry> Sorted; 4490b57cec5SDimitry Andric std::list<ELFRelocationEntry> Remainder; 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric LLVM_DEBUG(dumpRelocs("R: ", Relocs)); 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric // Separate the movable relocations (AHL relocations using the high bits) from 4540b57cec5SDimitry Andric // the immobile relocations (everything else). This does not preserve high/low 4550b57cec5SDimitry Andric // matches that already existed in the input. 4560b57cec5SDimitry Andric copy_if_else(Relocs.begin(), Relocs.end(), std::back_inserter(Remainder), 4570b57cec5SDimitry Andric std::back_inserter(Sorted), [](const ELFRelocationEntry &Reloc) { 4580b57cec5SDimitry Andric return getMatchingLoType(Reloc) != ELF::R_MIPS_NONE; 4590b57cec5SDimitry Andric }); 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric for (auto &R : Remainder) { 4620b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Matching: " << R << "\n"); 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric unsigned MatchingType = getMatchingLoType(R); 4650b57cec5SDimitry Andric assert(MatchingType != ELF::R_MIPS_NONE && 4660b57cec5SDimitry Andric "Wrong list for reloc that doesn't need a match"); 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric // Find the best matching relocation for the current high part. 4690b57cec5SDimitry Andric // See isMatchingReloc for a description of a matching relocation and 4700b57cec5SDimitry Andric // compareMatchingRelocs for a description of what 'best' means. 4710b57cec5SDimitry Andric auto InsertionPoint = 4720b57cec5SDimitry Andric find_best(Sorted.begin(), Sorted.end(), 4730b57cec5SDimitry Andric [&R, &MatchingType](const MipsRelocationEntry &X) { 4740b57cec5SDimitry Andric return isMatchingReloc(X, R, MatchingType); 4750b57cec5SDimitry Andric }, 4760b57cec5SDimitry Andric compareMatchingRelocs); 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric // If we matched then insert the high part in front of the match and mark 4790b57cec5SDimitry Andric // both relocations as being involved in a match. We only mark the high 4800b57cec5SDimitry Andric // part for cosmetic reasons in the debug output. 4810b57cec5SDimitry Andric // 4820b57cec5SDimitry Andric // If we failed to find a match then the high part is orphaned. This is not 4830b57cec5SDimitry Andric // permitted since the relocation cannot be evaluated without knowing the 4840b57cec5SDimitry Andric // carry-in. We can sometimes handle this using a matching low part that is 4850b57cec5SDimitry Andric // already used in a match but we already cover that case in 4860b57cec5SDimitry Andric // isMatchingReloc and compareMatchingRelocs. For the remaining cases we 4870b57cec5SDimitry Andric // should insert the high part at the end of the list. This will cause the 4880b57cec5SDimitry Andric // linker to fail but the alternative is to cause the linker to bind the 4890b57cec5SDimitry Andric // high part to a semi-matching low part and silently calculate the wrong 4900b57cec5SDimitry Andric // value. Unfortunately we have no means to warn the user that we did this 4910b57cec5SDimitry Andric // so leave it up to the linker to complain about it. 4920b57cec5SDimitry Andric if (InsertionPoint != Sorted.end()) 4930b57cec5SDimitry Andric InsertionPoint->Matched = true; 4940b57cec5SDimitry Andric Sorted.insert(InsertionPoint, R)->Matched = true; 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric LLVM_DEBUG(dumpRelocs("S: ", Sorted)); 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric assert(Relocs.size() == Sorted.size() && "Some relocs were not consumed"); 5000b57cec5SDimitry Andric 501*0fca6ea1SDimitry Andric // Overwrite the original vector with the sorted elements. 5020b57cec5SDimitry Andric unsigned CopyTo = 0; 503*0fca6ea1SDimitry Andric for (const auto &R : Sorted) 5040b57cec5SDimitry Andric Relocs[CopyTo++] = R.R; 5050b57cec5SDimitry Andric } 5060b57cec5SDimitry Andric 5075f757f3fSDimitry Andric bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCValue &Val, 5085f757f3fSDimitry Andric const MCSymbol &Sym, 5090b57cec5SDimitry Andric unsigned Type) const { 5100b57cec5SDimitry Andric // If it's a compound relocation for N64 then we need the relocation if any 5110b57cec5SDimitry Andric // sub-relocation needs it. 5120b57cec5SDimitry Andric if (!isUInt<8>(Type)) 5135f757f3fSDimitry Andric return needsRelocateWithSymbol(Val, Sym, Type & 0xff) || 5145f757f3fSDimitry Andric needsRelocateWithSymbol(Val, Sym, (Type >> 8) & 0xff) || 5155f757f3fSDimitry Andric needsRelocateWithSymbol(Val, Sym, (Type >> 16) & 0xff); 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric switch (Type) { 5180b57cec5SDimitry Andric default: 5190b57cec5SDimitry Andric errs() << Type << "\n"; 5200b57cec5SDimitry Andric llvm_unreachable("Unexpected relocation"); 5210b57cec5SDimitry Andric return true; 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric // This relocation doesn't affect the section data. 5240b57cec5SDimitry Andric case ELF::R_MIPS_NONE: 5250b57cec5SDimitry Andric return false; 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric // On REL ABI's (e.g. O32), these relocations form pairs. The pairing is done 5280b57cec5SDimitry Andric // by the static linker by matching the symbol and offset. 5290b57cec5SDimitry Andric // We only see one relocation at a time but it's still safe to relocate with 5300b57cec5SDimitry Andric // the section so long as both relocations make the same decision. 5310b57cec5SDimitry Andric // 5320b57cec5SDimitry Andric // Some older linkers may require the symbol for particular cases. Such cases 5330b57cec5SDimitry Andric // are not supported yet but can be added as required. 5340b57cec5SDimitry Andric case ELF::R_MIPS_GOT16: 5350b57cec5SDimitry Andric case ELF::R_MIPS16_GOT16: 5360b57cec5SDimitry Andric case ELF::R_MICROMIPS_GOT16: 5370b57cec5SDimitry Andric case ELF::R_MIPS_HIGHER: 5380b57cec5SDimitry Andric case ELF::R_MIPS_HIGHEST: 5390b57cec5SDimitry Andric case ELF::R_MIPS_HI16: 5400b57cec5SDimitry Andric case ELF::R_MIPS16_HI16: 5410b57cec5SDimitry Andric case ELF::R_MICROMIPS_HI16: 5420b57cec5SDimitry Andric case ELF::R_MIPS_LO16: 5430b57cec5SDimitry Andric case ELF::R_MIPS16_LO16: 5440b57cec5SDimitry Andric case ELF::R_MICROMIPS_LO16: 5450b57cec5SDimitry Andric // FIXME: It should be safe to return false for the STO_MIPS_MICROMIPS but 5460b57cec5SDimitry Andric // we neglect to handle the adjustment to the LSB of the addend that 5470b57cec5SDimitry Andric // it causes in applyFixup() and similar. 5480b57cec5SDimitry Andric if (cast<MCSymbolELF>(Sym).getOther() & ELF::STO_MIPS_MICROMIPS) 5490b57cec5SDimitry Andric return true; 5500b57cec5SDimitry Andric return false; 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric case ELF::R_MIPS_GOT_PAGE: 5530b57cec5SDimitry Andric case ELF::R_MICROMIPS_GOT_PAGE: 5540b57cec5SDimitry Andric case ELF::R_MIPS_GOT_OFST: 5550b57cec5SDimitry Andric case ELF::R_MICROMIPS_GOT_OFST: 5560b57cec5SDimitry Andric case ELF::R_MIPS_16: 5570b57cec5SDimitry Andric case ELF::R_MIPS_32: 5580b57cec5SDimitry Andric case ELF::R_MIPS_GPREL32: 5590b57cec5SDimitry Andric if (cast<MCSymbolELF>(Sym).getOther() & ELF::STO_MIPS_MICROMIPS) 5600b57cec5SDimitry Andric return true; 561bdd1243dSDimitry Andric [[fallthrough]]; 5620b57cec5SDimitry Andric case ELF::R_MIPS_26: 5630b57cec5SDimitry Andric case ELF::R_MIPS_64: 5640b57cec5SDimitry Andric case ELF::R_MIPS_GPREL16: 5650b57cec5SDimitry Andric case ELF::R_MIPS_PC16: 5660b57cec5SDimitry Andric case ELF::R_MIPS_SUB: 5670b57cec5SDimitry Andric return false; 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric // FIXME: Many of these relocations should probably return false but this 5700b57cec5SDimitry Andric // hasn't been confirmed to be safe yet. 5710b57cec5SDimitry Andric case ELF::R_MIPS_REL32: 5720b57cec5SDimitry Andric case ELF::R_MIPS_LITERAL: 5730b57cec5SDimitry Andric case ELF::R_MIPS_CALL16: 5740b57cec5SDimitry Andric case ELF::R_MIPS_SHIFT5: 5750b57cec5SDimitry Andric case ELF::R_MIPS_SHIFT6: 5760b57cec5SDimitry Andric case ELF::R_MIPS_GOT_DISP: 5770b57cec5SDimitry Andric case ELF::R_MIPS_GOT_HI16: 5780b57cec5SDimitry Andric case ELF::R_MIPS_GOT_LO16: 5790b57cec5SDimitry Andric case ELF::R_MIPS_INSERT_A: 5800b57cec5SDimitry Andric case ELF::R_MIPS_INSERT_B: 5810b57cec5SDimitry Andric case ELF::R_MIPS_DELETE: 5820b57cec5SDimitry Andric case ELF::R_MIPS_CALL_HI16: 5830b57cec5SDimitry Andric case ELF::R_MIPS_CALL_LO16: 5840b57cec5SDimitry Andric case ELF::R_MIPS_SCN_DISP: 5850b57cec5SDimitry Andric case ELF::R_MIPS_REL16: 5860b57cec5SDimitry Andric case ELF::R_MIPS_ADD_IMMEDIATE: 5870b57cec5SDimitry Andric case ELF::R_MIPS_PJUMP: 5880b57cec5SDimitry Andric case ELF::R_MIPS_RELGOT: 5890b57cec5SDimitry Andric case ELF::R_MIPS_JALR: 5900b57cec5SDimitry Andric case ELF::R_MIPS_TLS_DTPMOD32: 5910b57cec5SDimitry Andric case ELF::R_MIPS_TLS_DTPREL32: 5920b57cec5SDimitry Andric case ELF::R_MIPS_TLS_DTPMOD64: 5930b57cec5SDimitry Andric case ELF::R_MIPS_TLS_DTPREL64: 5940b57cec5SDimitry Andric case ELF::R_MIPS_TLS_GD: 5950b57cec5SDimitry Andric case ELF::R_MIPS_TLS_LDM: 5960b57cec5SDimitry Andric case ELF::R_MIPS_TLS_DTPREL_HI16: 5970b57cec5SDimitry Andric case ELF::R_MIPS_TLS_DTPREL_LO16: 5980b57cec5SDimitry Andric case ELF::R_MIPS_TLS_GOTTPREL: 5990b57cec5SDimitry Andric case ELF::R_MIPS_TLS_TPREL32: 6000b57cec5SDimitry Andric case ELF::R_MIPS_TLS_TPREL64: 6010b57cec5SDimitry Andric case ELF::R_MIPS_TLS_TPREL_HI16: 6020b57cec5SDimitry Andric case ELF::R_MIPS_TLS_TPREL_LO16: 6030b57cec5SDimitry Andric case ELF::R_MIPS_GLOB_DAT: 6040b57cec5SDimitry Andric case ELF::R_MIPS_PC21_S2: 6050b57cec5SDimitry Andric case ELF::R_MIPS_PC26_S2: 6060b57cec5SDimitry Andric case ELF::R_MIPS_PC18_S3: 6070b57cec5SDimitry Andric case ELF::R_MIPS_PC19_S2: 6080b57cec5SDimitry Andric case ELF::R_MIPS_PCHI16: 6090b57cec5SDimitry Andric case ELF::R_MIPS_PCLO16: 6100b57cec5SDimitry Andric case ELF::R_MIPS_COPY: 6110b57cec5SDimitry Andric case ELF::R_MIPS_JUMP_SLOT: 6120b57cec5SDimitry Andric case ELF::R_MIPS_NUM: 6130b57cec5SDimitry Andric case ELF::R_MIPS_PC32: 6140b57cec5SDimitry Andric case ELF::R_MIPS_EH: 6150b57cec5SDimitry Andric case ELF::R_MICROMIPS_26_S1: 6160b57cec5SDimitry Andric case ELF::R_MICROMIPS_GPREL16: 6170b57cec5SDimitry Andric case ELF::R_MICROMIPS_LITERAL: 6180b57cec5SDimitry Andric case ELF::R_MICROMIPS_PC7_S1: 6190b57cec5SDimitry Andric case ELF::R_MICROMIPS_PC10_S1: 6200b57cec5SDimitry Andric case ELF::R_MICROMIPS_PC16_S1: 6210b57cec5SDimitry Andric case ELF::R_MICROMIPS_CALL16: 6220b57cec5SDimitry Andric case ELF::R_MICROMIPS_GOT_DISP: 6230b57cec5SDimitry Andric case ELF::R_MICROMIPS_GOT_HI16: 6240b57cec5SDimitry Andric case ELF::R_MICROMIPS_GOT_LO16: 6250b57cec5SDimitry Andric case ELF::R_MICROMIPS_SUB: 6260b57cec5SDimitry Andric case ELF::R_MICROMIPS_HIGHER: 6270b57cec5SDimitry Andric case ELF::R_MICROMIPS_HIGHEST: 6280b57cec5SDimitry Andric case ELF::R_MICROMIPS_CALL_HI16: 6290b57cec5SDimitry Andric case ELF::R_MICROMIPS_CALL_LO16: 6300b57cec5SDimitry Andric case ELF::R_MICROMIPS_SCN_DISP: 6310b57cec5SDimitry Andric case ELF::R_MICROMIPS_JALR: 6320b57cec5SDimitry Andric case ELF::R_MICROMIPS_HI0_LO16: 6330b57cec5SDimitry Andric case ELF::R_MICROMIPS_TLS_GD: 6340b57cec5SDimitry Andric case ELF::R_MICROMIPS_TLS_LDM: 6350b57cec5SDimitry Andric case ELF::R_MICROMIPS_TLS_DTPREL_HI16: 6360b57cec5SDimitry Andric case ELF::R_MICROMIPS_TLS_DTPREL_LO16: 6370b57cec5SDimitry Andric case ELF::R_MICROMIPS_TLS_GOTTPREL: 6380b57cec5SDimitry Andric case ELF::R_MICROMIPS_TLS_TPREL_HI16: 6390b57cec5SDimitry Andric case ELF::R_MICROMIPS_TLS_TPREL_LO16: 6400b57cec5SDimitry Andric case ELF::R_MICROMIPS_GPREL7_S2: 6410b57cec5SDimitry Andric case ELF::R_MICROMIPS_PC23_S2: 6420b57cec5SDimitry Andric case ELF::R_MICROMIPS_PC21_S1: 6430b57cec5SDimitry Andric case ELF::R_MICROMIPS_PC26_S1: 6440b57cec5SDimitry Andric case ELF::R_MICROMIPS_PC18_S3: 6450b57cec5SDimitry Andric case ELF::R_MICROMIPS_PC19_S2: 6460b57cec5SDimitry Andric return true; 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric // FIXME: Many of these should probably return false but MIPS16 isn't 6490b57cec5SDimitry Andric // supported by the integrated assembler. 6500b57cec5SDimitry Andric case ELF::R_MIPS16_26: 6510b57cec5SDimitry Andric case ELF::R_MIPS16_GPREL: 6520b57cec5SDimitry Andric case ELF::R_MIPS16_CALL16: 6530b57cec5SDimitry Andric case ELF::R_MIPS16_TLS_GD: 6540b57cec5SDimitry Andric case ELF::R_MIPS16_TLS_LDM: 6550b57cec5SDimitry Andric case ELF::R_MIPS16_TLS_DTPREL_HI16: 6560b57cec5SDimitry Andric case ELF::R_MIPS16_TLS_DTPREL_LO16: 6570b57cec5SDimitry Andric case ELF::R_MIPS16_TLS_GOTTPREL: 6580b57cec5SDimitry Andric case ELF::R_MIPS16_TLS_TPREL_HI16: 6590b57cec5SDimitry Andric case ELF::R_MIPS16_TLS_TPREL_LO16: 6600b57cec5SDimitry Andric llvm_unreachable("Unsupported MIPS16 relocation"); 6610b57cec5SDimitry Andric return true; 6620b57cec5SDimitry Andric } 6630b57cec5SDimitry Andric } 6640b57cec5SDimitry Andric 6650b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter> 6660b57cec5SDimitry Andric llvm::createMipsELFObjectWriter(const Triple &TT, bool IsN32) { 6670b57cec5SDimitry Andric uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); 6680b57cec5SDimitry Andric bool IsN64 = TT.isArch64Bit() && !IsN32; 6690b57cec5SDimitry Andric bool HasRelocationAddend = TT.isArch64Bit(); 6708bcb0991SDimitry Andric return std::make_unique<MipsELFObjectWriter>(OSABI, HasRelocationAddend, 6710b57cec5SDimitry Andric IsN64); 6720b57cec5SDimitry Andric } 673