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-exception
6//
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} // end anonymous namespace
58
59/// Determine the low relocation that matches the given relocation.
60/// If the relocation does not need a low relocation then the return value
61/// is ELF::R_MIPS_NONE.
62///
63/// The relocations that need a matching low part are
64/// R_(MIPS|MICROMIPS|MIPS16)_HI16 for all symbols and
65/// R_(MIPS|MICROMIPS|MIPS16)_GOT16 for local symbols only.
66static unsigned getMatchingLoType(const ELFRelocationEntry &Reloc) {
67 unsigned Type = Reloc.Type;
68 if (Type == ELF::R_MIPS_HI16)
69 return ELF::R_MIPS_LO16;
70 if (Type == ELF::R_MICROMIPS_HI16)
71 return ELF::R_MICROMIPS_LO16;
72 if (Type == ELF::R_MIPS16_HI16)
73 return ELF::R_MIPS16_LO16;
74
75 if (Reloc.Symbol && Reloc.Symbol->getBinding() != ELF::STB_LOCAL)
76 return ELF::R_MIPS_NONE;
77
78 if (Type == ELF::R_MIPS_GOT16)
79 return ELF::R_MIPS_LO16;
80 if (Type == ELF::R_MICROMIPS_GOT16)
81 return ELF::R_MICROMIPS_LO16;
82 if (Type == ELF::R_MIPS16_GOT16)
83 return ELF::R_MIPS16_LO16;
84
85 return ELF::R_MIPS_NONE;
86}
87
88// Determine whether a relocation X is a low-part and matches the high-part R
89// perfectly by symbol and addend.
90static bool isMatchingReloc(unsigned MatchingType, const ELFRelocationEntry &R,
91 const ELFRelocationEntry &X) {
92 return X.Type == MatchingType && X.Symbol == R.Symbol && X.Addend == R.Addend;
93}
94
95MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI,
96 bool HasRelocationAddend, bool Is64)
97 : MCELFObjectTargetWriter(Is64, OSABI, ELF::EM_MIPS, HasRelocationAddend) {}
98
99unsigned MipsELFObjectWriter::getRelocType(const MCFixup &Fixup,
100 const MCValue &Target,
101 bool IsPCRel) const {
102 // Determine the type of the relocation.
103 auto Kind = Fixup.getKind();
104 switch (Target.getSpecifier()) {
105 case Mips::S_DTPREL:
106 case Mips::S_DTPREL_HI:
107 case Mips::S_DTPREL_LO:
108 case Mips::S_TLSLDM:
109 case Mips::S_TLSGD:
110 case Mips::S_GOTTPREL:
111 case Mips::S_TPREL_HI:
112 case Mips::S_TPREL_LO:
113 if (auto *SA = const_cast<MCSymbol *>(Target.getAddSym()))
114 static_cast<MCSymbolELF *>(SA)->setType(ELF::STT_TLS);
115 break;
116 default:
117 break;
118 }
119
120 switch (Kind) {
121 case FK_NONE:
122 return ELF::R_MIPS_NONE;
123 case FK_Data_1:
124 reportError(L: Fixup.getLoc(), Msg: "MIPS does not support one byte relocations");
125 return ELF::R_MIPS_NONE;
126 case Mips::fixup_Mips_16:
127 case FK_Data_2:
128 return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16;
129 case Mips::fixup_Mips_32:
130 case FK_Data_4:
131 return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32;
132 case Mips::fixup_Mips_64:
133 case FK_Data_8:
134 return IsPCRel
135 ? setRTypes(Value1: ELF::R_MIPS_PC32, Value2: ELF::R_MIPS_64, Value3: ELF::R_MIPS_NONE)
136 : (unsigned)ELF::R_MIPS_64;
137 }
138
139 if (IsPCRel) {
140 switch (Kind) {
141 case Mips::fixup_Mips_Branch_PCRel:
142 case Mips::fixup_Mips_PC16:
143 return ELF::R_MIPS_PC16;
144 case Mips::fixup_MICROMIPS_PC7_S1:
145 return ELF::R_MICROMIPS_PC7_S1;
146 case Mips::fixup_MICROMIPS_PC10_S1:
147 return ELF::R_MICROMIPS_PC10_S1;
148 case Mips::fixup_MICROMIPS_PC16_S1:
149 return ELF::R_MICROMIPS_PC16_S1;
150 case Mips::fixup_MICROMIPS_PC26_S1:
151 return ELF::R_MICROMIPS_PC26_S1;
152 case Mips::fixup_MICROMIPS_PC19_S2:
153 return ELF::R_MICROMIPS_PC19_S2;
154 case Mips::fixup_MICROMIPS_PC18_S3:
155 return ELF::R_MICROMIPS_PC18_S3;
156 case Mips::fixup_MICROMIPS_PC21_S1:
157 return ELF::R_MICROMIPS_PC21_S1;
158 case Mips::fixup_MIPS_PC19_S2:
159 return ELF::R_MIPS_PC19_S2;
160 case Mips::fixup_MIPS_PC18_S3:
161 return ELF::R_MIPS_PC18_S3;
162 case Mips::fixup_MIPS_PC21_S2:
163 return ELF::R_MIPS_PC21_S2;
164 case Mips::fixup_MIPS_PC26_S2:
165 return ELF::R_MIPS_PC26_S2;
166 case Mips::fixup_MIPS_PCHI16:
167 return ELF::R_MIPS_PCHI16;
168 case Mips::fixup_MIPS_PCLO16:
169 return ELF::R_MIPS_PCLO16;
170 }
171
172 llvm_unreachable("invalid PC-relative fixup kind!");
173 }
174
175 switch (Kind) {
176 case Mips::fixup_Mips_DTPREL32:
177 return ELF::R_MIPS_TLS_DTPREL32;
178 case Mips::fixup_Mips_DTPREL64:
179 return ELF::R_MIPS_TLS_DTPREL64;
180 case Mips::fixup_Mips_TPREL32:
181 return ELF::R_MIPS_TLS_TPREL32;
182 case Mips::fixup_Mips_TPREL64:
183 return ELF::R_MIPS_TLS_TPREL64;
184 case Mips::fixup_Mips_GPREL32:
185 return setRTypes(Value1: ELF::R_MIPS_GPREL32,
186 Value2: is64Bit() ? ELF::R_MIPS_64 : ELF::R_MIPS_NONE,
187 Value3: ELF::R_MIPS_NONE);
188 case Mips::fixup_Mips_GPREL16:
189 return ELF::R_MIPS_GPREL16;
190 case Mips::fixup_Mips_26:
191 return ELF::R_MIPS_26;
192 case Mips::fixup_Mips_CALL16:
193 return ELF::R_MIPS_CALL16;
194 case Mips::fixup_Mips_GOT:
195 return ELF::R_MIPS_GOT16;
196 case Mips::fixup_Mips_HI16:
197 return ELF::R_MIPS_HI16;
198 case Mips::fixup_Mips_LO16:
199 return ELF::R_MIPS_LO16;
200 case Mips::fixup_Mips_TLSGD:
201 return ELF::R_MIPS_TLS_GD;
202 case Mips::fixup_Mips_GOTTPREL:
203 return ELF::R_MIPS_TLS_GOTTPREL;
204 case Mips::fixup_Mips_TPREL_HI:
205 return ELF::R_MIPS_TLS_TPREL_HI16;
206 case Mips::fixup_Mips_TPREL_LO:
207 return ELF::R_MIPS_TLS_TPREL_LO16;
208 case Mips::fixup_Mips_TLSLDM:
209 return ELF::R_MIPS_TLS_LDM;
210 case Mips::fixup_Mips_DTPREL_HI:
211 return ELF::R_MIPS_TLS_DTPREL_HI16;
212 case Mips::fixup_Mips_DTPREL_LO:
213 return ELF::R_MIPS_TLS_DTPREL_LO16;
214 case Mips::fixup_Mips_GOT_PAGE:
215 return ELF::R_MIPS_GOT_PAGE;
216 case Mips::fixup_Mips_GOT_OFST:
217 return ELF::R_MIPS_GOT_OFST;
218 case Mips::fixup_Mips_GOT_DISP:
219 return ELF::R_MIPS_GOT_DISP;
220 case Mips::fixup_Mips_GPOFF_HI:
221 return setRTypes(Value1: ELF::R_MIPS_GPREL16, Value2: ELF::R_MIPS_SUB, Value3: ELF::R_MIPS_HI16);
222 case Mips::fixup_MICROMIPS_GPOFF_HI:
223 return setRTypes(Value1: ELF::R_MICROMIPS_GPREL16, Value2: ELF::R_MICROMIPS_SUB,
224 Value3: ELF::R_MICROMIPS_HI16);
225 case Mips::fixup_Mips_GPOFF_LO:
226 return setRTypes(Value1: ELF::R_MIPS_GPREL16, Value2: ELF::R_MIPS_SUB, Value3: ELF::R_MIPS_LO16);
227 case Mips::fixup_MICROMIPS_GPOFF_LO:
228 return setRTypes(Value1: ELF::R_MICROMIPS_GPREL16, Value2: ELF::R_MICROMIPS_SUB,
229 Value3: ELF::R_MICROMIPS_LO16);
230 case Mips::fixup_Mips_HIGHER:
231 return ELF::R_MIPS_HIGHER;
232 case Mips::fixup_Mips_HIGHEST:
233 return ELF::R_MIPS_HIGHEST;
234 case Mips::fixup_Mips_SUB:
235 return ELF::R_MIPS_SUB;
236 case Mips::fixup_Mips_GOT_HI16:
237 return ELF::R_MIPS_GOT_HI16;
238 case Mips::fixup_Mips_GOT_LO16:
239 return ELF::R_MIPS_GOT_LO16;
240 case Mips::fixup_Mips_CALL_HI16:
241 return ELF::R_MIPS_CALL_HI16;
242 case Mips::fixup_Mips_CALL_LO16:
243 return ELF::R_MIPS_CALL_LO16;
244 case Mips::fixup_MICROMIPS_26_S1:
245 return ELF::R_MICROMIPS_26_S1;
246 case Mips::fixup_MICROMIPS_HI16:
247 return ELF::R_MICROMIPS_HI16;
248 case Mips::fixup_MICROMIPS_LO16:
249 return ELF::R_MICROMIPS_LO16;
250 case Mips::fixup_MICROMIPS_GOT16:
251 return ELF::R_MICROMIPS_GOT16;
252 case Mips::fixup_MICROMIPS_CALL16:
253 return ELF::R_MICROMIPS_CALL16;
254 case Mips::fixup_MICROMIPS_GOT_DISP:
255 return ELF::R_MICROMIPS_GOT_DISP;
256 case Mips::fixup_MICROMIPS_GOT_PAGE:
257 return ELF::R_MICROMIPS_GOT_PAGE;
258 case Mips::fixup_MICROMIPS_GOT_OFST:
259 return ELF::R_MICROMIPS_GOT_OFST;
260 case Mips::fixup_MICROMIPS_TLS_GD:
261 return ELF::R_MICROMIPS_TLS_GD;
262 case Mips::fixup_MICROMIPS_TLS_LDM:
263 return ELF::R_MICROMIPS_TLS_LDM;
264 case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16:
265 return ELF::R_MICROMIPS_TLS_DTPREL_HI16;
266 case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16:
267 return ELF::R_MICROMIPS_TLS_DTPREL_LO16;
268 case Mips::fixup_MICROMIPS_GOTTPREL:
269 return ELF::R_MICROMIPS_TLS_GOTTPREL;
270 case Mips::fixup_MICROMIPS_TLS_TPREL_HI16:
271 return ELF::R_MICROMIPS_TLS_TPREL_HI16;
272 case Mips::fixup_MICROMIPS_TLS_TPREL_LO16:
273 return ELF::R_MICROMIPS_TLS_TPREL_LO16;
274 case Mips::fixup_MICROMIPS_SUB:
275 return ELF::R_MICROMIPS_SUB;
276 case Mips::fixup_MICROMIPS_HIGHER:
277 return ELF::R_MICROMIPS_HIGHER;
278 case Mips::fixup_MICROMIPS_HIGHEST:
279 return ELF::R_MICROMIPS_HIGHEST;
280 case Mips::fixup_Mips_JALR:
281 return ELF::R_MIPS_JALR;
282 case Mips::fixup_MICROMIPS_JALR:
283 return ELF::R_MICROMIPS_JALR;
284 }
285
286 reportError(L: Fixup.getLoc(), Msg: "unsupported relocation type");
287 return ELF::R_MIPS_NONE;
288}
289
290/// Sort relocation table entries by offset except where another order is
291/// required by the MIPS ABI.
292///
293/// MIPS has a few relocations that have an AHL component in the expression used
294/// to evaluate them. This AHL component is an addend with the same number of
295/// bits as a symbol value but not all of our ABI's are able to supply a
296/// sufficiently sized addend in a single relocation.
297///
298/// The O32 ABI for example, uses REL relocations which store the addend in the
299/// section data. All the relocations with AHL components affect 16-bit fields
300/// so the addend for a single relocation is limited to 16-bit. This ABI
301/// resolves the limitation by linking relocations (e.g. R_MIPS_HI16 and
302/// R_MIPS_LO16) and distributing the addend between the linked relocations. The
303/// ABI mandates that such relocations must be next to each other in a
304/// particular order (e.g. R_MIPS_HI16 must be immediately followed by a
305/// matching R_MIPS_LO16) but the rule is less strict in practice.
306///
307/// The de facto standard is lenient in the following ways:
308/// - 'Immediately following' does not refer to the next relocation entry but
309/// the next matching relocation.
310/// - There may be multiple high parts relocations for one low part relocation.
311/// - There may be multiple low part relocations for one high part relocation.
312/// - The AHL addend in each part does not have to be exactly equal as long as
313/// the difference does not affect the carry bit from bit 15 into 16. This is
314/// to allow, for example, the use of %lo(foo) and %lo(foo+4) when loading
315/// both halves of a long long.
316///
317/// See getMatchingLoType() for a description of which high part relocations
318/// match which low part relocations. One particular thing to note is that
319/// R_MIPS_GOT16 and similar only have AHL addends if they refer to local
320/// symbols.
321///
322/// It should also be noted that this function is not affected by whether
323/// the symbol was kept or rewritten into a section-relative equivalent. We
324/// always match using the expressions from the source.
325void MipsELFObjectWriter::sortRelocs(std::vector<ELFRelocationEntry> &Relocs) {
326 // We do not need to sort the relocation table for RELA relocations which
327 // N32/N64 uses as the relocation addend contains the value we require,
328 // rather than it being split across a pair of relocations.
329 if (hasRelocationAddend())
330 return;
331
332 // Sort relocations by r_offset. There might be more than one at an offset
333 // with composed relocations or .reloc directives.
334 llvm::stable_sort(
335 Range&: Relocs, C: [](const ELFRelocationEntry &A, const ELFRelocationEntry &B) {
336 return A.Offset < B.Offset;
337 });
338
339 // Place relocations in a list for reorder convenience. Hi16 contains the
340 // iterators of high-part relocations.
341 std::list<MipsRelocationEntry> Sorted;
342 SmallVector<std::list<MipsRelocationEntry>::iterator, 0> Hi16;
343 for (auto &R : Relocs) {
344 Sorted.push_back(x: R);
345 if (getMatchingLoType(Reloc: R) != ELF::R_MIPS_NONE)
346 Hi16.push_back(Elt: std::prev(x: Sorted.end()));
347 }
348
349 for (auto I : Hi16) {
350 auto &R = I->R;
351 unsigned MatchingType = getMatchingLoType(Reloc: R);
352 // If the next relocation is a perfect match, continue;
353 if (std::next(x: I) != Sorted.end() &&
354 isMatchingReloc(MatchingType, R, X: std::next(x: I)->R))
355 continue;
356 // Otherwise, find the best matching low-part relocation with the following
357 // criteria. It must have the same symbol and its addend is no lower than
358 // that of the current high-part.
359 //
360 // (1) %lo with a smaller offset is preferred.
361 // (2) %lo with the same offset that is unmatched is preferred.
362 // (3) later %lo is preferred.
363 auto Best = Sorted.end();
364 for (auto J = Sorted.begin(); J != Sorted.end(); ++J) {
365 auto &R1 = J->R;
366 if (R1.Type == MatchingType && R.Symbol == R1.Symbol &&
367 R.Addend <= R1.Addend &&
368 (Best == Sorted.end() || R1.Addend < Best->R.Addend ||
369 (!Best->Matched && R1.Addend == Best->R.Addend)))
370 Best = J;
371 }
372 if (Best != Sorted.end() && R.Addend == Best->R.Addend)
373 Best->Matched = true;
374
375 // Move the high-part before the low-part, or if not found, the end of the
376 // list. The unmatched high-part will lead to a linker warning/error.
377 Sorted.splice(position: Best, x&: Sorted, i: I);
378 }
379
380 assert(Relocs.size() == Sorted.size() && "Some relocs were not consumed");
381
382 // Overwrite the original vector with the sorted elements.
383 unsigned CopyTo = 0;
384 for (const auto &R : Sorted)
385 Relocs[CopyTo++] = R.R;
386}
387
388bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCValue &V,
389 unsigned Type) const {
390 // If it's a compound relocation for N64 then we need the relocation if any
391 // sub-relocation needs it.
392 if (!isUInt<8>(x: Type))
393 return needsRelocateWithSymbol(V, Type: Type & 0xff) ||
394 needsRelocateWithSymbol(V, Type: (Type >> 8) & 0xff) ||
395 needsRelocateWithSymbol(V, Type: (Type >> 16) & 0xff);
396
397 auto *Sym = static_cast<const MCSymbolELF *>(V.getAddSym());
398 switch (Type) {
399 default:
400 errs() << Type << "\n";
401 llvm_unreachable("Unexpected relocation");
402 return true;
403
404 // This relocation doesn't affect the section data.
405 case ELF::R_MIPS_NONE:
406 return false;
407
408 // On REL ABI's (e.g. O32), these relocations form pairs. The pairing is done
409 // by the static linker by matching the symbol and offset.
410 // We only see one relocation at a time but it's still safe to relocate with
411 // the section so long as both relocations make the same decision.
412 //
413 // Some older linkers may require the symbol for particular cases. Such cases
414 // are not supported yet but can be added as required.
415 case ELF::R_MIPS_GOT16:
416 case ELF::R_MIPS16_GOT16:
417 case ELF::R_MICROMIPS_GOT16:
418 case ELF::R_MIPS_HIGHER:
419 case ELF::R_MIPS_HIGHEST:
420 case ELF::R_MIPS_HI16:
421 case ELF::R_MIPS16_HI16:
422 case ELF::R_MICROMIPS_HI16:
423 case ELF::R_MIPS_LO16:
424 case ELF::R_MIPS16_LO16:
425 case ELF::R_MICROMIPS_LO16:
426 // FIXME: It should be safe to return false for the STO_MIPS_MICROMIPS but
427 // we neglect to handle the adjustment to the LSB of the addend that
428 // it causes in applyFixup() and similar.
429 if (Sym->getOther() & ELF::STO_MIPS_MICROMIPS)
430 return true;
431 return false;
432
433 case ELF::R_MIPS_GOT_PAGE:
434 case ELF::R_MICROMIPS_GOT_PAGE:
435 case ELF::R_MIPS_GOT_OFST:
436 case ELF::R_MICROMIPS_GOT_OFST:
437 case ELF::R_MIPS_16:
438 case ELF::R_MIPS_32:
439 case ELF::R_MIPS_GPREL32:
440 if (Sym->getOther() & ELF::STO_MIPS_MICROMIPS)
441 return true;
442 [[fallthrough]];
443 case ELF::R_MIPS_26:
444 case ELF::R_MIPS_64:
445 case ELF::R_MIPS_GPREL16:
446 case ELF::R_MIPS_PC16:
447 case ELF::R_MIPS_SUB:
448 return false;
449
450 // FIXME: Many of these relocations should probably return false but this
451 // hasn't been confirmed to be safe yet.
452 case ELF::R_MIPS_REL32:
453 case ELF::R_MIPS_LITERAL:
454 case ELF::R_MIPS_CALL16:
455 case ELF::R_MIPS_SHIFT5:
456 case ELF::R_MIPS_SHIFT6:
457 case ELF::R_MIPS_GOT_DISP:
458 case ELF::R_MIPS_GOT_HI16:
459 case ELF::R_MIPS_GOT_LO16:
460 case ELF::R_MIPS_INSERT_A:
461 case ELF::R_MIPS_INSERT_B:
462 case ELF::R_MIPS_DELETE:
463 case ELF::R_MIPS_CALL_HI16:
464 case ELF::R_MIPS_CALL_LO16:
465 case ELF::R_MIPS_SCN_DISP:
466 case ELF::R_MIPS_REL16:
467 case ELF::R_MIPS_ADD_IMMEDIATE:
468 case ELF::R_MIPS_PJUMP:
469 case ELF::R_MIPS_RELGOT:
470 case ELF::R_MIPS_JALR:
471 case ELF::R_MIPS_TLS_DTPMOD32:
472 case ELF::R_MIPS_TLS_DTPREL32:
473 case ELF::R_MIPS_TLS_DTPMOD64:
474 case ELF::R_MIPS_TLS_DTPREL64:
475 case ELF::R_MIPS_TLS_GD:
476 case ELF::R_MIPS_TLS_LDM:
477 case ELF::R_MIPS_TLS_DTPREL_HI16:
478 case ELF::R_MIPS_TLS_DTPREL_LO16:
479 case ELF::R_MIPS_TLS_GOTTPREL:
480 case ELF::R_MIPS_TLS_TPREL32:
481 case ELF::R_MIPS_TLS_TPREL64:
482 case ELF::R_MIPS_TLS_TPREL_HI16:
483 case ELF::R_MIPS_TLS_TPREL_LO16:
484 case ELF::R_MIPS_GLOB_DAT:
485 case ELF::R_MIPS_PC21_S2:
486 case ELF::R_MIPS_PC26_S2:
487 case ELF::R_MIPS_PC18_S3:
488 case ELF::R_MIPS_PC19_S2:
489 case ELF::R_MIPS_PCHI16:
490 case ELF::R_MIPS_PCLO16:
491 case ELF::R_MIPS_COPY:
492 case ELF::R_MIPS_JUMP_SLOT:
493 case ELF::R_MIPS_NUM:
494 case ELF::R_MIPS_PC32:
495 case ELF::R_MIPS_EH:
496 case ELF::R_MICROMIPS_26_S1:
497 case ELF::R_MICROMIPS_GPREL16:
498 case ELF::R_MICROMIPS_LITERAL:
499 case ELF::R_MICROMIPS_PC7_S1:
500 case ELF::R_MICROMIPS_PC10_S1:
501 case ELF::R_MICROMIPS_PC16_S1:
502 case ELF::R_MICROMIPS_CALL16:
503 case ELF::R_MICROMIPS_GOT_DISP:
504 case ELF::R_MICROMIPS_GOT_HI16:
505 case ELF::R_MICROMIPS_GOT_LO16:
506 case ELF::R_MICROMIPS_SUB:
507 case ELF::R_MICROMIPS_HIGHER:
508 case ELF::R_MICROMIPS_HIGHEST:
509 case ELF::R_MICROMIPS_CALL_HI16:
510 case ELF::R_MICROMIPS_CALL_LO16:
511 case ELF::R_MICROMIPS_SCN_DISP:
512 case ELF::R_MICROMIPS_JALR:
513 case ELF::R_MICROMIPS_HI0_LO16:
514 case ELF::R_MICROMIPS_TLS_GD:
515 case ELF::R_MICROMIPS_TLS_LDM:
516 case ELF::R_MICROMIPS_TLS_DTPREL_HI16:
517 case ELF::R_MICROMIPS_TLS_DTPREL_LO16:
518 case ELF::R_MICROMIPS_TLS_GOTTPREL:
519 case ELF::R_MICROMIPS_TLS_TPREL_HI16:
520 case ELF::R_MICROMIPS_TLS_TPREL_LO16:
521 case ELF::R_MICROMIPS_GPREL7_S2:
522 case ELF::R_MICROMIPS_PC23_S2:
523 case ELF::R_MICROMIPS_PC21_S1:
524 case ELF::R_MICROMIPS_PC26_S1:
525 case ELF::R_MICROMIPS_PC18_S3:
526 case ELF::R_MICROMIPS_PC19_S2:
527 return true;
528
529 // FIXME: Many of these should probably return false but MIPS16 isn't
530 // supported by the integrated assembler.
531 case ELF::R_MIPS16_26:
532 case ELF::R_MIPS16_GPREL:
533 case ELF::R_MIPS16_CALL16:
534 case ELF::R_MIPS16_TLS_GD:
535 case ELF::R_MIPS16_TLS_LDM:
536 case ELF::R_MIPS16_TLS_DTPREL_HI16:
537 case ELF::R_MIPS16_TLS_DTPREL_LO16:
538 case ELF::R_MIPS16_TLS_GOTTPREL:
539 case ELF::R_MIPS16_TLS_TPREL_HI16:
540 case ELF::R_MIPS16_TLS_TPREL_LO16:
541 llvm_unreachable("Unsupported MIPS16 relocation");
542 return true;
543 }
544}
545
546std::unique_ptr<MCObjectTargetWriter>
547llvm::createMipsELFObjectWriter(const Triple &TT, bool IsN32) {
548 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType: TT.getOS());
549 bool IsN64 = TT.isArch64Bit() && !IsN32;
550 bool HasRelocationAddend = TT.isArch64Bit();
551 return std::make_unique<MipsELFObjectWriter>(args&: OSABI, args&: HasRelocationAddend,
552 args&: IsN64);
553}
554