LLVM: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

25#include

26#include

27#include

28#include

29#include

30

31#define DEBUG_TYPE "mips-elf-object-writer"

32

33using namespace llvm;

34

35namespace {

36

37

38struct MipsRelocationEntry {

40 bool Matched = false;

41

43};

44

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 &Relocs) override;

55};

56

57

58enum FindBestPredicateResult {

59 FindBest_NoMatch = 0,

60 FindBest_Match,

61

62 FindBest_PerfectMatch,

63};

64

65}

66

67

68

69

70template <class InputIt, class OutputIt1, class OutputIt2, class UnaryPredicate>

72 OutputIt1 d1, OutputIt2 d2,

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

88

89

90

91

92

93

94

95

96template <class InputIt, class UnaryPredicate, class Comparator>

98 Comparator BetterThan) {

99 InputIt Best = Last;

100

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

115

116

117

118

119

120

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

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

144

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)

153

154unsigned MipsELFObjectWriter::getRelocType(const MCFixup &Fixup,

156 bool IsPCRel) const {

157

159 switch (Target.getSpecifier()) {

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) {

177 return ELF::R_MIPS_NONE;

179 reportError(Fixup.getLoc(), "MIPS does not support one byte relocations");

180 return ELF::R_MIPS_NONE;

183 return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16;

186 return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32;

189 return IsPCRel

190 ? 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) {

198 return ELF::R_MIPS_PC16;

200 return ELF::R_MICROMIPS_PC7_S1;

202 return ELF::R_MICROMIPS_PC10_S1;

204 return ELF::R_MICROMIPS_PC16_S1;

206 return ELF::R_MICROMIPS_PC26_S1;

208 return ELF::R_MICROMIPS_PC19_S2;

210 return ELF::R_MICROMIPS_PC18_S3;

212 return ELF::R_MICROMIPS_PC21_S1;

214 return ELF::R_MIPS_PC19_S2;

216 return ELF::R_MIPS_PC18_S3;

218 return ELF::R_MIPS_PC21_S2;

220 return ELF::R_MIPS_PC26_S2;

222 return ELF::R_MIPS_PCHI16;

224 return ELF::R_MIPS_PCLO16;

225 }

226

228 }

229

230 switch (Kind) {

232 return ELF::R_MIPS_TLS_DTPREL32;

234 return ELF::R_MIPS_TLS_DTPREL64;

236 return ELF::R_MIPS_TLS_TPREL32;

238 return ELF::R_MIPS_TLS_TPREL64;

240 return setRTypes(ELF::R_MIPS_GPREL32,

241 is64Bit() ? ELF::R_MIPS_64 : ELF::R_MIPS_NONE,

242 ELF::R_MIPS_NONE);

244 return ELF::R_MIPS_GPREL16;

246 return ELF::R_MIPS_26;

248 return ELF::R_MIPS_CALL16;

250 return ELF::R_MIPS_GOT16;

252 return ELF::R_MIPS_HI16;

254 return ELF::R_MIPS_LO16;

256 return ELF::R_MIPS_TLS_GD;

258 return ELF::R_MIPS_TLS_GOTTPREL;

260 return ELF::R_MIPS_TLS_TPREL_HI16;

262 return ELF::R_MIPS_TLS_TPREL_LO16;

264 return ELF::R_MIPS_TLS_LDM;

266 return ELF::R_MIPS_TLS_DTPREL_HI16;

268 return ELF::R_MIPS_TLS_DTPREL_LO16;

270 return ELF::R_MIPS_GOT_PAGE;

272 return ELF::R_MIPS_GOT_OFST;

274 return ELF::R_MIPS_GOT_DISP;

276 return setRTypes(ELF::R_MIPS_GPREL16, ELF::R_MIPS_SUB, ELF::R_MIPS_HI16);

278 return setRTypes(ELF::R_MICROMIPS_GPREL16, ELF::R_MICROMIPS_SUB,

279 ELF::R_MICROMIPS_HI16);

281 return setRTypes(ELF::R_MIPS_GPREL16, ELF::R_MIPS_SUB, ELF::R_MIPS_LO16);

283 return setRTypes(ELF::R_MICROMIPS_GPREL16, ELF::R_MICROMIPS_SUB,

284 ELF::R_MICROMIPS_LO16);

286 return ELF::R_MIPS_HIGHER;

288 return ELF::R_MIPS_HIGHEST;

290 return ELF::R_MIPS_SUB;

292 return ELF::R_MIPS_GOT_HI16;

294 return ELF::R_MIPS_GOT_LO16;

296 return ELF::R_MIPS_CALL_HI16;

298 return ELF::R_MIPS_CALL_LO16;

300 return ELF::R_MICROMIPS_26_S1;

302 return ELF::R_MICROMIPS_HI16;

304 return ELF::R_MICROMIPS_LO16;

306 return ELF::R_MICROMIPS_GOT16;

308 return ELF::R_MICROMIPS_CALL16;

310 return ELF::R_MICROMIPS_GOT_DISP;

312 return ELF::R_MICROMIPS_GOT_PAGE;

314 return ELF::R_MICROMIPS_GOT_OFST;

316 return ELF::R_MICROMIPS_TLS_GD;

318 return ELF::R_MICROMIPS_TLS_LDM;

320 return ELF::R_MICROMIPS_TLS_DTPREL_HI16;

322 return ELF::R_MICROMIPS_TLS_DTPREL_LO16;

324 return ELF::R_MICROMIPS_TLS_GOTTPREL;

326 return ELF::R_MICROMIPS_TLS_TPREL_HI16;

328 return ELF::R_MICROMIPS_TLS_TPREL_LO16;

330 return ELF::R_MICROMIPS_SUB;

332 return ELF::R_MICROMIPS_HIGHER;

334 return ELF::R_MICROMIPS_HIGHEST;

336 return ELF::R_MIPS_JALR;

338 return ELF::R_MICROMIPS_JALR;

339 }

340

342 return ELF::R_MIPS_NONE;

343}

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380void MipsELFObjectWriter::sortRelocs(std::vector &Relocs) {

381

382

383

384 if (hasRelocationAddend())

385 return;

386

387

388

390 Relocs, [](const ELFRelocationEntry &A, const ELFRelocationEntry &B) {

391 return A.Offset < B.Offset;

392 });

393

394

395

396 std::list Sorted;

397 SmallVector<std::list::iterator, 0> Hi16;

398 for (auto &R : Relocs) {

399 Sorted.push_back(R);

401 Hi16.push_back(std::prev(Sorted.end()));

402 }

403

404 for (auto I : Hi16) {

405 auto &R = I->R;

407

408 if (std::next(I) != Sorted.end() &&

410 continue;

411

412

413

414

415

416

417

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

431

432 Sorted.splice(Best, Sorted, I);

433 }

434

435 assert(Relocs.size() == Sorted.size() && "Some relocs were not consumed");

436

437

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

446

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:

457 return true;

458

459

460 case ELF::R_MIPS_NONE:

461 return false;

462

463

464

465

466

467

468

469

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

482

483

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:

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

506

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

585

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:

597 return true;

598 }

599}

600

601std::unique_ptr

604 bool IsN64 = TT.isArch64Bit() && !IsN32;

605 bool HasRelocationAddend = TT.isArch64Bit();

606 return std::make_unique(OSABI, HasRelocationAddend,

607 IsN64);

608}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static Error reportError(StringRef Message)

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static bool isMatchingReloc(unsigned MatchingType, const ELFRelocationEntry &R, const ELFRelocationEntry &X)

Definition MipsELFObjectWriter.cpp:145

static InputIt find_best(InputIt First, InputIt Last, UnaryPredicate Predicate, Comparator BetterThan)

Find the best match in the range [First, Last).

Definition MipsELFObjectWriter.cpp:97

static std::pair< OutputIt1, OutputIt2 > copy_if_else(InputIt First, InputIt Last, OutputIt1 d1, OutputIt2 d2, UnaryPredicate Predicate)

Copy elements in the range [First, Last) to d1 when the predicate is true or d2 when the predicate is...

Definition MipsELFObjectWriter.cpp:71

static unsigned getMatchingLoType(const ELFRelocationEntry &Reloc)

Determine the low relocation that matches the given relocation.

Definition MipsELFObjectWriter.cpp:121

PowerPC TLS Dynamic Call Fixup

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

static bool is64Bit(const char *name)

Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...

void push_back(const T &Elt)

Target - Wrapper for Target specific information.

Triple - Helper class for working with autoconf configuration names.

The instances of the Type class are immutable: once they are created, they are never changed.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ fixup_MICROMIPS_TLS_TPREL_LO16

@ fixup_MICROMIPS_GOT_PAGE

@ fixup_MICROMIPS_PC16_S1

@ fixup_MICROMIPS_TLS_TPREL_HI16

@ fixup_MICROMIPS_PC21_S1

@ fixup_MICROMIPS_GPOFF_LO

@ fixup_MICROMIPS_PC19_S2

@ fixup_MICROMIPS_TLS_LDM

@ fixup_MICROMIPS_GOT_OFST

@ fixup_MICROMIPS_TLS_DTPREL_HI16

@ fixup_MICROMIPS_PC10_S1

@ fixup_MICROMIPS_HIGHEST

@ fixup_MICROMIPS_GOT_DISP

@ fixup_MICROMIPS_PC18_S3

@ fixup_MICROMIPS_PC26_S1

@ fixup_MICROMIPS_GOTTPREL

@ fixup_MICROMIPS_TLS_DTPREL_LO16

@ fixup_Mips_Branch_PCRel

@ fixup_MICROMIPS_GPOFF_HI

This is an optimization pass for GlobalISel generic memory operations.

void stable_sort(R &&Range)

std::unique_ptr< MCObjectTargetWriter > createMipsELFObjectWriter(const Triple &TT, bool IsN32)

Construct a Mips ELF object writer.

Definition MipsELFObjectWriter.cpp:602

constexpr bool isUInt(uint64_t x)

Checks if an unsigned integer fits into the given bit width.

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

@ FK_Data_8

A eight-byte fixup.

@ FK_Data_1

A one-byte fixup.

@ FK_Data_4

A four-byte fixup.

@ FK_Data_2

A two-byte fixup.