31 #define DEBUG_TYPE "mips-elf-object-writer"
38 struct MipsRelocationEntry {
46 Out <<
", Matched=" << Matched;
59 MipsELFObjectWriter(uint8_t OSABI,
bool HasRelocationAddend,
bool Is64);
61 ~MipsELFObjectWriter()
override =
default;
65 bool needsRelocateWithSymbol(
const MCSymbol &Sym,
66 unsigned Type)
const override;
68 std::vector<ELFRelocationEntry> &Relocs)
override;
72 enum FindBestPredicateResult {
76 FindBest_PerfectMatch,
84 template <
class InputIt,
class OutputIt1,
class OutputIt2,
class UnaryPredicate>
85 static std::pair<OutputIt1, OutputIt2>
copy_if_else(InputIt First, InputIt Last,
86 OutputIt1
d1, OutputIt2 d2,
88 for (InputIt
I =
First;
I != Last; ++
I) {
98 return std::make_pair(
d1, d2);
110 template <
class InputIt,
class UnaryPredicate,
class Comparator>
112 Comparator BetterThan) {
115 for (InputIt
I =
First;
I != Last; ++
I) {
117 if (Matched != FindBest_NoMatch) {
120 if (Best == Last || BetterThan(*
I, *Best)) {
125 if (Matched == FindBest_PerfectMatch) {
143 if (
Type == ELF::R_MIPS_HI16)
144 return ELF::R_MIPS_LO16;
145 if (
Type == ELF::R_MICROMIPS_HI16)
146 return ELF::R_MICROMIPS_LO16;
147 if (
Type == ELF::R_MIPS16_HI16)
148 return ELF::R_MIPS16_LO16;
152 return ELF::R_MIPS_NONE;
154 if (
Type == ELF::R_MIPS_GOT16)
155 return ELF::R_MIPS_LO16;
156 if (
Type == ELF::R_MICROMIPS_GOT16)
157 return ELF::R_MICROMIPS_LO16;
158 if (
Type == ELF::R_MIPS16_GOT16)
159 return ELF::R_MIPS16_LO16;
161 return ELF::R_MIPS_NONE;
180 unsigned MatchingType) {
181 if (
X.R.Type == MatchingType &&
X.R.OriginalSymbol == R.OriginalSymbol) {
183 X.R.OriginalAddend == R.OriginalAddend)
184 return FindBest_PerfectMatch;
185 else if (
X.R.OriginalAddend >= R.OriginalAddend)
186 return FindBest_Match;
188 return FindBest_NoMatch;
198 const MipsRelocationEntry &PreviousBest) {
199 if (Candidate.R.OriginalAddend != PreviousBest.R.OriginalAddend)
200 return Candidate.R.OriginalAddend < PreviousBest.R.OriginalAddend;
201 return PreviousBest.Matched && !Candidate.Matched;
206 template <
class Container>
208 for (
const auto &R : Relocs)
213 MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI,
214 bool HasRelocationAddend,
bool Is64)
217 unsigned MipsELFObjectWriter::getRelocType(
MCContext &Ctx,
220 bool IsPCRel)
const {
226 return ELF::R_MIPS_NONE;
229 "MIPS does not support one byte relocations");
230 return ELF::R_MIPS_NONE;
233 return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16;
236 return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32;
240 ? setRTypes(ELF::R_MIPS_PC32, ELF::R_MIPS_64, ELF::R_MIPS_NONE)
241 : (unsigned)
ELF::R_MIPS_64;
248 return ELF::R_MIPS_PC16;
250 return ELF::R_MICROMIPS_PC7_S1;
252 return ELF::R_MICROMIPS_PC10_S1;
254 return ELF::R_MICROMIPS_PC16_S1;
256 return ELF::R_MICROMIPS_PC26_S1;
258 return ELF::R_MICROMIPS_PC19_S2;
260 return ELF::R_MICROMIPS_PC18_S3;
262 return ELF::R_MICROMIPS_PC21_S1;
264 return ELF::R_MIPS_PC19_S2;
266 return ELF::R_MIPS_PC18_S3;
268 return ELF::R_MIPS_PC21_S2;
270 return ELF::R_MIPS_PC26_S2;
272 return ELF::R_MIPS_PCHI16;
274 return ELF::R_MIPS_PCLO16;
282 return ELF::R_MIPS_TLS_DTPREL32;
284 return ELF::R_MIPS_TLS_DTPREL64;
286 return ELF::R_MIPS_TLS_TPREL32;
288 return ELF::R_MIPS_TLS_TPREL64;
290 return setRTypes(ELF::R_MIPS_GPREL32,
291 is64Bit() ? ELF::R_MIPS_64 : ELF::R_MIPS_NONE,
294 return ELF::R_MIPS_GPREL16;
296 return ELF::R_MIPS_26;
298 return ELF::R_MIPS_CALL16;
300 return ELF::R_MIPS_GOT16;
302 return ELF::R_MIPS_HI16;
304 return ELF::R_MIPS_LO16;
306 return ELF::R_MIPS_TLS_GD;
308 return ELF::R_MIPS_TLS_GOTTPREL;
310 return ELF::R_MIPS_TLS_TPREL_HI16;
312 return ELF::R_MIPS_TLS_TPREL_LO16;
314 return ELF::R_MIPS_TLS_LDM;
316 return ELF::R_MIPS_TLS_DTPREL_HI16;
318 return ELF::R_MIPS_TLS_DTPREL_LO16;
320 return ELF::R_MIPS_GOT_PAGE;
322 return ELF::R_MIPS_GOT_OFST;
324 return ELF::R_MIPS_GOT_DISP;
326 return setRTypes(ELF::R_MIPS_GPREL16, ELF::R_MIPS_SUB, ELF::R_MIPS_HI16);
328 return setRTypes(ELF::R_MICROMIPS_GPREL16, ELF::R_MICROMIPS_SUB,
329 ELF::R_MICROMIPS_HI16);
331 return setRTypes(ELF::R_MIPS_GPREL16, ELF::R_MIPS_SUB, ELF::R_MIPS_LO16);
333 return setRTypes(ELF::R_MICROMIPS_GPREL16, ELF::R_MICROMIPS_SUB,
334 ELF::R_MICROMIPS_LO16);
336 return ELF::R_MIPS_HIGHER;
338 return ELF::R_MIPS_HIGHEST;
340 return ELF::R_MIPS_SUB;
342 return ELF::R_MIPS_GOT_HI16;
344 return ELF::R_MIPS_GOT_LO16;
346 return ELF::R_MIPS_CALL_HI16;
348 return ELF::R_MIPS_CALL_LO16;
350 return ELF::R_MICROMIPS_26_S1;
352 return ELF::R_MICROMIPS_HI16;
354 return ELF::R_MICROMIPS_LO16;
356 return ELF::R_MICROMIPS_GOT16;
358 return ELF::R_MICROMIPS_CALL16;
360 return ELF::R_MICROMIPS_GOT_DISP;
362 return ELF::R_MICROMIPS_GOT_PAGE;
364 return ELF::R_MICROMIPS_GOT_OFST;
366 return ELF::R_MICROMIPS_TLS_GD;
368 return ELF::R_MICROMIPS_TLS_LDM;
370 return ELF::R_MICROMIPS_TLS_DTPREL_HI16;
372 return ELF::R_MICROMIPS_TLS_DTPREL_LO16;
374 return ELF::R_MICROMIPS_TLS_GOTTPREL;
376 return ELF::R_MICROMIPS_TLS_TPREL_HI16;
378 return ELF::R_MICROMIPS_TLS_TPREL_LO16;
380 return ELF::R_MICROMIPS_SUB;
382 return ELF::R_MICROMIPS_HIGHER;
384 return ELF::R_MICROMIPS_HIGHEST;
386 return ELF::R_MIPS_JALR;
388 return ELF::R_MICROMIPS_JALR;
430 std::vector<ELFRelocationEntry> &Relocs) {
434 if (hasRelocationAddend())
437 if (Relocs.size() < 2)
443 return A.Offset <
B.Offset;
446 std::list<MipsRelocationEntry> Sorted;
447 std::list<ELFRelocationEntry> Remainder;
454 copy_if_else(Relocs.begin(), Relocs.end(), std::back_inserter(Remainder),
456 return getMatchingLoType(Reloc) != ELF::R_MIPS_NONE;
459 for (
auto &
R : Remainder) {
463 assert(MatchingType != ELF::R_MIPS_NONE &&
464 "Wrong list for reloc that doesn't need a match");
469 auto InsertionPoint =
471 [&
R, &MatchingType](
const MipsRelocationEntry &
X) {
472 return isMatchingReloc(X, R, MatchingType);
490 if (InsertionPoint != Sorted.end())
491 InsertionPoint->Matched =
true;
492 Sorted.insert(InsertionPoint,
R)->Matched =
true;
497 assert(Relocs.size() == Sorted.size() &&
"Some relocs were not consumed");
502 for (
const auto &
R :
reverse(Sorted))
503 Relocs[CopyTo++] =
R.R;
506 bool MipsELFObjectWriter::needsRelocateWithSymbol(
const MCSymbol &Sym,
507 unsigned Type)
const {
511 return needsRelocateWithSymbol(Sym,
Type & 0xff) ||
512 needsRelocateWithSymbol(Sym, (
Type >> 8) & 0xff) ||
513 needsRelocateWithSymbol(Sym, (
Type >> 16) & 0xff);
522 case ELF::R_MIPS_NONE:
532 case ELF::R_MIPS_GOT16:
533 case ELF::R_MIPS16_GOT16:
534 case ELF::R_MICROMIPS_GOT16:
535 case ELF::R_MIPS_HIGHER:
536 case ELF::R_MIPS_HIGHEST:
537 case ELF::R_MIPS_HI16:
538 case ELF::R_MIPS16_HI16:
539 case ELF::R_MICROMIPS_HI16:
540 case ELF::R_MIPS_LO16:
541 case ELF::R_MIPS16_LO16:
542 case ELF::R_MICROMIPS_LO16:
550 case ELF::R_MIPS_GOT_PAGE:
551 case ELF::R_MICROMIPS_GOT_PAGE:
552 case ELF::R_MIPS_GOT_OFST:
553 case ELF::R_MICROMIPS_GOT_OFST:
556 case ELF::R_MIPS_GPREL32:
562 case ELF::R_MIPS_GPREL16:
563 case ELF::R_MIPS_PC16:
564 case ELF::R_MIPS_SUB:
569 case ELF::R_MIPS_REL32:
570 case ELF::R_MIPS_LITERAL:
571 case ELF::R_MIPS_CALL16:
572 case ELF::R_MIPS_SHIFT5:
573 case ELF::R_MIPS_SHIFT6:
574 case ELF::R_MIPS_GOT_DISP:
575 case ELF::R_MIPS_GOT_HI16:
576 case ELF::R_MIPS_GOT_LO16:
577 case ELF::R_MIPS_INSERT_A:
578 case ELF::R_MIPS_INSERT_B:
579 case ELF::R_MIPS_DELETE:
580 case ELF::R_MIPS_CALL_HI16:
581 case ELF::R_MIPS_CALL_LO16:
582 case ELF::R_MIPS_SCN_DISP:
583 case ELF::R_MIPS_REL16:
584 case ELF::R_MIPS_ADD_IMMEDIATE:
585 case ELF::R_MIPS_PJUMP:
586 case ELF::R_MIPS_RELGOT:
587 case ELF::R_MIPS_JALR:
588 case ELF::R_MIPS_TLS_DTPMOD32:
589 case ELF::R_MIPS_TLS_DTPREL32:
590 case ELF::R_MIPS_TLS_DTPMOD64:
591 case ELF::R_MIPS_TLS_DTPREL64:
592 case ELF::R_MIPS_TLS_GD:
593 case ELF::R_MIPS_TLS_LDM:
594 case ELF::R_MIPS_TLS_DTPREL_HI16:
595 case ELF::R_MIPS_TLS_DTPREL_LO16:
596 case ELF::R_MIPS_TLS_GOTTPREL:
597 case ELF::R_MIPS_TLS_TPREL32:
598 case ELF::R_MIPS_TLS_TPREL64:
599 case ELF::R_MIPS_TLS_TPREL_HI16:
600 case ELF::R_MIPS_TLS_TPREL_LO16:
601 case ELF::R_MIPS_GLOB_DAT:
602 case ELF::R_MIPS_PC21_S2:
603 case ELF::R_MIPS_PC26_S2:
604 case ELF::R_MIPS_PC18_S3:
605 case ELF::R_MIPS_PC19_S2:
606 case ELF::R_MIPS_PCHI16:
607 case ELF::R_MIPS_PCLO16:
608 case ELF::R_MIPS_COPY:
609 case ELF::R_MIPS_JUMP_SLOT:
610 case ELF::R_MIPS_NUM:
611 case ELF::R_MIPS_PC32:
613 case ELF::R_MICROMIPS_26_S1:
614 case ELF::R_MICROMIPS_GPREL16:
615 case ELF::R_MICROMIPS_LITERAL:
616 case ELF::R_MICROMIPS_PC7_S1:
617 case ELF::R_MICROMIPS_PC10_S1:
618 case ELF::R_MICROMIPS_PC16_S1:
619 case ELF::R_MICROMIPS_CALL16:
620 case ELF::R_MICROMIPS_GOT_DISP:
621 case ELF::R_MICROMIPS_GOT_HI16:
622 case ELF::R_MICROMIPS_GOT_LO16:
623 case ELF::R_MICROMIPS_SUB:
624 case ELF::R_MICROMIPS_HIGHER:
625 case ELF::R_MICROMIPS_HIGHEST:
626 case ELF::R_MICROMIPS_CALL_HI16:
627 case ELF::R_MICROMIPS_CALL_LO16:
628 case ELF::R_MICROMIPS_SCN_DISP:
629 case ELF::R_MICROMIPS_JALR:
630 case ELF::R_MICROMIPS_HI0_LO16:
631 case ELF::R_MICROMIPS_TLS_GD:
632 case ELF::R_MICROMIPS_TLS_LDM:
633 case ELF::R_MICROMIPS_TLS_DTPREL_HI16:
634 case ELF::R_MICROMIPS_TLS_DTPREL_LO16:
635 case ELF::R_MICROMIPS_TLS_GOTTPREL:
636 case ELF::R_MICROMIPS_TLS_TPREL_HI16:
637 case ELF::R_MICROMIPS_TLS_TPREL_LO16:
638 case ELF::R_MICROMIPS_GPREL7_S2:
639 case ELF::R_MICROMIPS_PC23_S2:
640 case ELF::R_MICROMIPS_PC21_S1:
641 case ELF::R_MICROMIPS_PC26_S1:
642 case ELF::R_MICROMIPS_PC18_S3:
643 case ELF::R_MICROMIPS_PC19_S2:
648 case ELF::R_MIPS16_26:
649 case ELF::R_MIPS16_GPREL:
650 case ELF::R_MIPS16_CALL16:
651 case ELF::R_MIPS16_TLS_GD:
652 case ELF::R_MIPS16_TLS_LDM:
653 case ELF::R_MIPS16_TLS_DTPREL_HI16:
654 case ELF::R_MIPS16_TLS_DTPREL_LO16:
655 case ELF::R_MIPS16_TLS_GOTTPREL:
656 case ELF::R_MIPS16_TLS_TPREL_HI16:
657 case ELF::R_MIPS16_TLS_TPREL_LO16:
663 std::unique_ptr<MCObjectTargetWriter>
665 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
666 bool IsN64 = TT.isArch64Bit() && !IsN32;
667 bool HasRelocationAddend = TT.isArch64Bit();
668 return std::make_unique<MipsELFObjectWriter>(OSABI, HasRelocationAddend,