LLVM: include/llvm/ExecutionEngine/JITLink/aarch64.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13#ifndef LLVM_EXECUTIONENGINE_JITLINK_AARCH64_H

14#define LLVM_EXECUTIONENGINE_JITLINK_AARCH64_H

15

20

21namespace llvm {

24

25

27

28

29

30

31

32

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

64

65

66

67

68

69

70

71

72

73

75

76

77

78

79

80

81

82

84

85

86

87

88

89

90

91

92

93

94

95

97

98

99

100

101

102

103

104

106

107

108

109

110

111

112

113

114

115

116

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

184

185

186

187

188

189

190

191

192

193

194

195

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

220

221

222

223

224

225

226

227

228

229

230

231

232

234

235

236

237

238

239

240

241

242

243

244

245

246

247

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

266

267

268

269

270

271

272

273

274

275

276

277

278

279

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

358

359

360

361

362

363

364

365

366

367

368

369

370

371

373

374

375

376

377

378

379

380

381

382

383

384

385

386

388

389

390

391

392

393

394

395

396

397

398

399

400

401

403

404

405

406

407

408

409

410

411

412

413

414

415

416

418};

419

420

421

423

424

426 constexpr uint32_t LoadStoreImm12Mask = 0x3b000000;

427 return (Instr & LoadStoreImm12Mask) == 0x39000000;

428}

429

431 constexpr uint32_t TestAndBranchImm14Mask = 0x7e000000;

432 return (Instr & TestAndBranchImm14Mask) == 0x36000000;

433}

434

436 constexpr uint32_t CondBranchImm19Mask = 0xfe000000;

437 return (Instr & CondBranchImm19Mask) == 0x54000000;

438}

439

441 constexpr uint32_t CompAndBranchImm19Mask = 0x7e000000;

442 return (Instr & CompAndBranchImm19Mask) == 0x34000000;

443}

444

446 constexpr uint32_t ADRMask = 0x9f000000;

447 return (Instr & ADRMask) == 0x10000000;

448}

449

451 constexpr uint32_t LDRLitMask = 0x3b000000;

452 return (Instr & LDRLitMask) == 0x18000000;

453}

454

455

456

457

458

459

460

462 constexpr uint32_t Vec128Mask = 0x04800000;

463

465 uint32_t ImplicitShift = Instr >> 30;

466 if (ImplicitShift == 0)

467 if ((Instr & Vec128Mask) == Vec128Mask)

468 ImplicitShift = 4;

469

470 return ImplicitShift;

471 }

472

473 return 0;

474}

475

476

478 constexpr uint32_t MoveWideImm16Mask = 0x5f9fffe0;

479 return (Instr & MoveWideImm16Mask) == 0x52800000;

480}

481

482

483

484

485

488 uint32_t ImplicitShift = (Instr >> 21) & 0b11;

489 return ImplicitShift << 4;

490 }

491

492 return 0;

493}

494

495

497 const Symbol *GOTSymbol) {

499

500 char *BlockWorkingMem = B.getAlreadyMutableContent().data();

501 char *FixupPtr = BlockWorkingMem + E.getOffset();

503

504 switch (E.getKind()) {

506 uint64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();

507 *(ulittle64_t *)FixupPtr = Value;

508 break;

509 }

511 uint64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();

512 if (Value > std::numeric_limits<uint32_t>::max())

514 *(ulittle32_t *)FixupPtr = Value;

515 break;

516 }

523 Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();

524 else

525 Value = FixupAddress - E.getTarget().getAddress() + E.getAddend();

526

528 if (Value < std::numeric_limits<int32_t>::min() ||

529 Value > std::numeric_limits<int32_t>::max())

531 *(little32_t *)FixupPtr = Value;

532 } else

533 *(little64_t *)FixupPtr = Value;

534 break;

535 }

538 "Branch-inst is not 32-bit aligned");

539

540 int64_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();

541

544 "aligned");

545

546 if (Value < -(1 << 27) || Value > ((1 << 27) - 1))

548

549 uint32_t RawInstr = *(little32_t *)FixupPtr;

550 assert((RawInstr & 0x7fffffff) == 0x14000000 &&

551 "RawInstr isn't a B or BR immediate instruction");

553 uint32_t FixedInstr = RawInstr | Imm;

554 *(little32_t *)FixupPtr = FixedInstr;

555 break;

556 }

559 (E.getTarget().getAddress() + E.getAddend()).getValue();

560

561 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;

563 "RawInstr isn't a MOVK/MOVZ instruction");

564

566 uint32_t Imm = (TargetOffset >> ImmShift) & 0xffff;

567 uint32_t FixedInstr = RawInstr | (Imm << 5);

568 *(ulittle32_t *)FixupPtr = FixedInstr;

569 break;

570 }

572 assert((FixupAddress.getValue() & 0x3) == 0 && "LDR is not 32-bit aligned");

573 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;

575 int64_t Delta = E.getTarget().getAddress() + E.getAddend() - FixupAddress;

576 if (Delta & 0x3)

578 "aligned");

581 uint32_t EncodedImm = ((static_cast<uint32_t>(Delta) >> 2) & 0x7ffff) << 5;

582 uint32_t FixedInstr = RawInstr | EncodedImm;

583 *(ulittle32_t *)FixupPtr = FixedInstr;

584 break;

585 }

587 assert((FixupAddress.getValue() & 0x3) == 0 && "ADR is not 32-bit aligned");

588 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;

589 assert(isADR(RawInstr) && "RawInstr is not an ADR");

590 int64_t Delta = E.getTarget().getAddress() + E.getAddend() - FixupAddress;

593 auto UDelta = static_cast<uint32_t>(Delta);

594 uint32_t EncodedImmHi = ((UDelta >> 2) & 0x7ffff) << 5;

595 uint32_t EncodedImmLo = (UDelta & 0x3) << 29;

596 uint32_t FixedInstr = RawInstr | EncodedImmHi | EncodedImmLo;

597 *(ulittle32_t *)FixupPtr = FixedInstr;

598 break;

599 }

602 "Test and branch is not 32-bit aligned");

603 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;

605 "RawInstr is not a test and branch");

606 int64_t Delta = E.getTarget().getAddress() + E.getAddend() - FixupAddress;

607 if (Delta & 0x3)

609 "Test and branch literal target is not 32-bit aligned");

612 uint32_t EncodedImm = ((static_cast<uint32_t>(Delta) >> 2) & 0x3fff) << 5;

613 uint32_t FixedInstr = RawInstr | EncodedImm;

614 *(ulittle32_t *)FixupPtr = FixedInstr;

615 break;

616 }

619 "Conditional branch is not 32-bit aligned");

620 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;

622 "RawInstr is not a conditional branch");

623 int64_t Delta = E.getTarget().getAddress() + E.getAddend() - FixupAddress;

624 if (Delta & 0x3)

626 "Conditional branch literal target is not 32-bit "

627 "aligned");

630 uint32_t EncodedImm = ((static_cast<uint32_t>(Delta) >> 2) & 0x7ffff) << 5;

631 uint32_t FixedInstr = RawInstr | EncodedImm;

632 *(ulittle32_t *)FixupPtr = FixedInstr;

633 break;

634 }

637 (E.getTarget().getAddress().getValue() + E.getAddend()) &

638 ~static_cast<uint64_t>(4096 - 1);

640 FixupAddress.getValue() & ~static_cast<uint64_t>(4096 - 1);

641

642 int64_t PageDelta = TargetPage - PCPage;

645

646 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;

647 assert((RawInstr & 0xffffffe0) == 0x90000000 &&

648 "RawInstr isn't an ADRP instruction");

649 uint32_t ImmLo = (static_cast<uint64_t>(PageDelta) >> 12) & 0x3;

650 uint32_t ImmHi = (static_cast<uint64_t>(PageDelta) >> 14) & 0x7ffff;

651 uint32_t FixedInstr = RawInstr | (ImmLo << 29) | (ImmHi << 5);

652 *(ulittle32_t *)FixupPtr = FixedInstr;

653 break;

654 }

657 (E.getTarget().getAddress() + E.getAddend()).getValue() & 0xfff;

658

659 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;

661

662 if (TargetOffset & ((1 << ImmShift) - 1))

664

665 uint32_t EncodedImm = (TargetOffset >> ImmShift) << 10;

666 uint32_t FixedInstr = RawInstr | EncodedImm;

667 *(ulittle32_t *)FixupPtr = FixedInstr;

668 break;

669 }

671 assert(GOTSymbol && "No GOT section symbol");

673 (E.getTarget().getAddress() + E.getAddend()).getValue() -

674 (GOTSymbol->getAddress().getValue() & ~static_cast<uint64_t>(4096 - 1));

675 if (TargetOffset > 0x7fff)

677

678 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;

679 const unsigned ImmShift = 3;

680 if (TargetOffset & ((1 << ImmShift) - 1))

682

683 uint32_t EncodedImm = (TargetOffset >> ImmShift) << 10;

684 uint32_t FixedInstr = RawInstr | EncodedImm;

685 *(ulittle32_t *)FixupPtr = FixedInstr;

686 break;

687 }

688 default:

690 "In graph " + G.getName() + ", section " + B.getSection().getName() +

692 }

693

695}

696

697

699

700

702

703

704

705

706

707

708

709

711

712

713

714

715

716

717

718

719

720

721

723 Symbol *InitialTarget = nullptr,

724 uint64_t InitialAddend = 0) {

727 if (InitialTarget)

728 B.addEdge(Pointer64, 0, *InitialTarget, InitialAddend);

729 return G.addAnonymousSymbol(B, 0, 8, false, false);

730}

731

732

733

734

735

736

737

739 Symbol &PointerSymbol) {

742 B.addEdge(Page21, 0, PointerSymbol, 0);

744 return B;

745}

746

747

748

749

750

753 Symbol &PointerSymbol) {

754 return G.addAnonymousSymbol(

757}

758

759

760

761

762

763

764

766

767

769 Section &TrampolineSection,

770 Symbol &ReentrySymbol) {

774 return B;

775}

776

778 Section &TrampolineSection,

779 Symbol &ReentrySymbol) {

780 return G.addAnonymousSymbol(

783}

784

785

787public:

789

791 if ((GOTSection = G.findSectionByName(getSectionName())))

792 registerExistingEntries();

793 }

794

796 Edge::Kind KindToSet = Edge::Invalid;

797 const char *BlockWorkingMem = B->getContent().data();

798 const char *FixupPtr = BlockWorkingMem + E.getOffset();

799

800 switch (E.getKind()) {

804 break;

805 }

810 (void)RawInstr;

811 assert(E.getAddend() == 0 &&

812 "GOTPageOffset12/TLVPageOffset12 with non-zero addend");

813 assert((RawInstr & 0xfffffc00) == 0xf9400000 &&

814 "RawInstr isn't a 64-bit LDR immediate");

815 break;

816 }

820 (void)RawInstr;

821 assert(E.getAddend() == 0 && "GOTPageOffset15 with non-zero addend");

822 assert((RawInstr & 0xfffffc00) == 0xf9400000 &&

823 "RawInstr isn't a 64-bit LDR immediate");

824 break;

825 }

828 break;

829 }

830 default:

831 return false;

832 }

833 assert(KindToSet != Edge::Invalid &&

834 "Fell through switch, but no new kind to set");

836 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "

837 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "

838 << formatv("{0:x}", E.getOffset()) << ")\n";

839 });

840 E.setKind(KindToSet);

842 return true;

843 }

844

848

849private:

851 if (!GOTSection)

854 return *GOTSection;

855 }

856

857 LLVM_ABI void registerExistingEntries();

858

859 Section *GOTSection = nullptr;

860};

861

862

864public:

866

871

875 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "

876 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "

877 << formatv("{0:x}", E.getOffset()) << ")\n";

878 });

880 return true;

881 }

882 return false;

883 }

884

889

890public:

897

899

902};

903

904

906

907

908

909

910

911

912

913

914

916

917

918

919

920

921

922

923

924

926

927}

928}

929}

930

931#endif

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

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

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

#define DEBUG_WITH_TYPE(TYPE,...)

DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

StringRef - Represent a constant reference to a string, i.e.

Target - Wrapper for Target specific information.

LLVM Value Representation.

An Addressable with content and edges.

Represents fixups and constraints in the LinkGraph.

Represents an object file section.

orc::ExecutorAddr getAddress() const

Returns the address of this symbol.

A CRTP base for tables that are built on demand, e.g.

Symbol & getEntryForTarget(LinkGraph &G, Symbol &Target)

Global Offset Table Builder.

Definition aarch64.h:786

GOTTableManager(LinkGraph &G)

Definition aarch64.h:790

Symbol & createEntry(LinkGraph &G, Symbol &Target)

Definition aarch64.h:845

bool visitEdge(LinkGraph &G, Block *B, Edge &E)

Definition aarch64.h:795

static StringRef getSectionName()

Definition aarch64.h:788

static StringRef getSectionName()

Definition aarch64.h:865

PLTTableManager(LinkGraph &G, GOTTableManager &GOT)

Definition aarch64.h:867

GOTTableManager & GOT

Definition aarch64.h:900

bool visitEdge(LinkGraph &G, Block *B, Edge &E)

Definition aarch64.h:872

Symbol & createEntry(LinkGraph &G, Symbol &Target)

Definition aarch64.h:885

LLVM_ABI void registerExistingEntries()

Section * StubsSection

Definition aarch64.h:901

Section & getStubsSection(LinkGraph &G)

Definition aarch64.h:891

Represents an address in the executor process.

uint64_t getValue() const

LLVM_ABI const char NullPointerContent[PointerSize]

AArch64 null pointer content.

bool isLDRLiteral(uint32_t Instr)

Definition aarch64.h:450

bool isADR(uint32_t Instr)

Definition aarch64.h:445

bool isCondBranchImm19(uint32_t Instr)

Definition aarch64.h:435

LLVM_ABI const char ReentryTrampolineContent[8]

AArch64 reentry trampoline.

constexpr uint64_t PointerSize

aarch64 pointer size.

Definition aarch64.h:698

Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const Symbol *GOTSymbol)

Apply fixup expression for edge to block content.

Definition aarch64.h:496

Block & createReentryTrampolineBlock(LinkGraph &G, Section &TrampolineSection, Symbol &ReentrySymbol)

Create a block of N reentry trampolines.

Definition aarch64.h:768

bool isMoveWideImm16(uint32_t Instr)

Definition aarch64.h:477

bool isCompAndBranchImm19(uint32_t Instr)

Definition aarch64.h:440

LLVM_ABI const char PointerJumpStubContent[12]

bool isLoadStoreImm12(uint32_t Instr)

Definition aarch64.h:425

LLVM_ABI Error createEmptyPointerSigningFunction(LinkGraph &G)

Creates a pointer signing function section, block, and symbol to reserve space for a signing function...

LLVM_ABI Error lowerPointer64AuthEdgesToSigningFunction(LinkGraph &G)

Given a LinkGraph containing Pointer64Authenticated edges, transform those edges to Pointer64 and add...

LLVM_ABI const char * getEdgeKindName(Edge::Kind K)

Returns a string name for the given aarch64 edge.

Block & createPointerJumpStubBlock(LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)

Create a jump stub block that jumps via the pointer at the given symbol.

Definition aarch64.h:738

Symbol & createAnonymousPointer(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget=nullptr, uint64_t InitialAddend=0)

Creates a new pointer block in the given section and returns an Anonymous symbol pointing to it.

Definition aarch64.h:722

LLVM_ABI const char * getPointerSigningFunctionSectionName()

Returns the name of the pointer signing function section.

Symbol & createAnonymousReentryTrampoline(LinkGraph &G, Section &TrampolineSection, Symbol &ReentrySymbol)

Definition aarch64.h:777

EdgeKind_aarch64

Represents aarch64 fixups and other aarch64-specific edge kinds.

Definition aarch64.h:26

@ LDRLiteral19

The signed 21-bit delta from the fixup to the target.

Definition aarch64.h:219

@ Pointer64Authenticated

An arm64e authenticated pointer relocation.

Definition aarch64.h:63

@ RequestGOTAndTransformToPageOffset15

A GOT entry getter/constructor, transformed to Pageoffset15 pointing at the GOT entry for the origina...

Definition aarch64.h:337

@ CondBranch19PCRel

A 19-bit PC-relative conditional branch.

Definition aarch64.h:183

@ RequestTLVPAndTransformToPageOffset12

A TLVP entry getter/constructor, transformed to PageOffset12.

Definition aarch64.h:387

@ RequestTLSDescEntryAndTransformToPageOffset12

A TLSDesc entry getter/constructor, transformed to PageOffset12.

Definition aarch64.h:417

@ Page21

The signed 21-bit delta from the fixup page to the page containing the target.

Definition aarch64.h:248

@ Branch26PCRel

A 26-bit PC-relative branch.

Definition aarch64.h:139

@ Delta32

A 32-bit delta.

Definition aarch64.h:96

@ Pointer64

A plain 64-bit pointer value relocation.

Definition aarch64.h:33

@ Delta64

A 64-bit delta.

Definition aarch64.h:83

@ Pointer32

A plain 32-bit pointer value relocation.

Definition aarch64.h:74

@ RequestTLVPAndTransformToPage21

A TLVP entry getter/constructor, transformed to Page21.

Definition aarch64.h:372

@ GotPageOffset15

The 15-bit offset of the GOT entry from the GOT table.

Definition aarch64.h:280

@ MoveWide16

A 16-bit slice of the target address (which slice depends on the instruction at the fixup location).

Definition aarch64.h:196

@ TestAndBranch14PCRel

A 14-bit PC-relative test and branch.

Definition aarch64.h:161

@ RequestGOTAndTransformToPage21

A GOT entry getter/constructor, transformed to Page21 pointing at the GOT entry for the original targ...

Definition aarch64.h:300

@ ADRLiteral21

The signed 21-bit delta from the fixup to the target.

Definition aarch64.h:233

@ RequestGOTAndTransformToPageOffset12

A GOT entry getter/constructor, transformed to Pageoffset12 pointing at the GOT entry for the origina...

Definition aarch64.h:320

@ NegDelta32

A 32-bit negative delta.

Definition aarch64.h:117

@ NegDelta64

A 64-bit negative delta.

Definition aarch64.h:105

@ RequestGOTAndTransformToDelta32

A GOT entry getter/constructor, transformed to Delta32 pointing at the GOT entry for the original tar...

Definition aarch64.h:357

@ PageOffset12

The 12-bit (potentially shifted) offset of the target within its page.

Definition aarch64.h:265

@ RequestTLSDescEntryAndTransformToPage21

A TLSDesc entry getter/constructor, transformed to Page21.

Definition aarch64.h:402

bool isTestAndBranchImm14(uint32_t Instr)

Definition aarch64.h:430

unsigned getPageOffset12Shift(uint32_t Instr)

Definition aarch64.h:461

unsigned getMoveWide16Shift(uint32_t Instr)

Definition aarch64.h:486

Symbol & createAnonymousPointerJumpStub(LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)

Create a jump stub that jumps via the pointer at the given symbol and an anonymous symbol pointing to...

Definition aarch64.h:751

LLVM_ABI Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B, const Edge &E)

Create an out of range error for the given edge in the given block.

detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t

This is an optimization pass for GlobalISel generic memory operations.

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.