LLVM: lib/ExecutionEngine/JITLink/aarch32.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

14

22

23#define DEBUG_TYPE "jitlink"

24

25namespace llvm {

26namespace jitlink {

27namespace aarch32 {

28

29

33

34

35

36

37

38

39

46

47

48

49

50

51

52

58

59

60

61

62

63

70 return HalfWords{S | Imm10, J1 | J2 | Imm11};

71}

72

73

74

75

76

77

86

87

88

89

90

91

93 return (Value >> 2) & 0x00ffffff;

94}

95

96

97

98

99

100

104

105

106

107

108

109

115 return HalfWords{Imm1 << 10 | Imm4, Imm3 << 12 | Imm8};

116}

117

118

119

120

121

122

128 uint32_t Imm16 = Imm4 << 12 | Imm1 << 11 | Imm3 << 8 | Imm8;

129 assert(Imm16 <= 0xffff && "Decoded value out-of-range");

130 return Imm16;

131}

132

133

134

135

136

141

142

143

144

145

150

151

152

153

154

155

159 return (Imm4 << 16) | Imm12;

160}

161

162

163

164

165

166

170 return (Imm4 << 12) | Imm12;

171}

172

173

174

175

176

177

182

183

184

185

186

187

192

193namespace {

194

195

196

197

198struct WritableThumbRelocation {

199

200 WritableThumbRelocation(char *FixupPtr)

201 : Hi{*reinterpret_cast<support::ulittle16_t *>(FixupPtr)},

202 Lo{*reinterpret_cast<support::ulittle16_t *>(FixupPtr + 2)} {}

203

206};

207

208struct ThumbRelocation {

209

210 ThumbRelocation(const char *FixupPtr)

211 : Hi{*reinterpret_cast<const support::ulittle16_t *>(FixupPtr)},

212 Lo{*reinterpret_cast<const support::ulittle16_t *>(FixupPtr + 2)} {}

213

214

215 ThumbRelocation(WritableThumbRelocation &Writable)

216 : Hi{Writable.Hi}, Lo(Writable.Lo) {}

217

220};

221

222struct WritableArmRelocation {

223 WritableArmRelocation(char *FixupPtr)

224 : Wd{*reinterpret_cast<support::ulittle32_t *>(FixupPtr)} {}

225

227};

228

229struct ArmRelocation {

230 ArmRelocation(const char *FixupPtr)

231 : Wd{*reinterpret_cast<const support::ulittle32_t *>(FixupPtr)} {}

232

233 ArmRelocation(WritableArmRelocation &Writable) : Wd{Writable.Wd} {}

234

236};

237

238Error makeUnexpectedOpcodeError(const LinkGraph &G, const ThumbRelocation &R,

239 Edge::Kind Kind) {

241 formatv("Invalid opcode [ {0:x4}, {1:x4} ] for relocation: {2}",

242 R.Hi.value(), R.Lo.value(), G.getEdgeKindName(Kind)));

243}

244

245Error makeUnexpectedOpcodeError(const LinkGraph &G, const ArmRelocation &R,

246 Edge::Kind Kind) {

248 formatv("Invalid opcode {0:x8} for relocation: {1}", R.Wd.value(),

249 G.getEdgeKindName(Kind)));

250}

251

252template <EdgeKind_aarch32 K> constexpr bool isArm() {

254}

255template <EdgeKind_aarch32 K> constexpr bool isThumb() {

257}

258

259template <EdgeKind_aarch32 K> static bool checkOpcodeArm(uint32_t Wd) {

261}

262

263template <EdgeKind_aarch32 K>

264static bool checkOpcodeThumb(uint16_t Hi, uint16_t Lo) {

267}

268

269class FixupInfoTable {

271

272public:

273 FixupInfoTable() {

274 populateEntries<FirstArmRelocation, LastArmRelocation>();

275 populateEntries<FirstThumbRelocation, LastThumbRelocation>();

276 }

277

278 const FixupInfoBase *getEntry(Edge::Kind K) {

279 assert(K < Data.size() && "Index out of bounds");

280 return Data.at(K).get();

281 }

282

283private:

284 template <EdgeKind_aarch32 K, EdgeKind_aarch32 LastK> void populateEntries() {

285 assert(K < Data.size() && "Index out of range");

286 assert(Data.at(K) == nullptr && "Initialized entries are immutable");

287 Data[K] = initEntry();

288 if constexpr (K < LastK) {

290 populateEntries<Next, LastK>();

291 }

292 }

293

294 template <EdgeKind_aarch32 K>

295 static std::unique_ptr initEntry() {

296 auto Entry = std::make_unique<FixupInfo>();

297 static_assert(isArm() != isThumb(), "Classes are mutually exclusive");

298 if constexpr (isArm())

299 Entry->checkOpcode = checkOpcodeArm;

301 Entry->checkOpcode = checkOpcodeThumb;

303 }

304

305private:

306 std::array<std::unique_ptr, Items> Data;

307};

308

309ManagedStatic DynFixupInfos;

310

311}

312

314 Edge::Kind Kind) {

316 "Edge kind must be Arm relocation");

317 const FixupInfoBase *Entry = DynFixupInfos->getEntry(Kind);

319 assert(Info.checkOpcode && "Opcode check is mandatory for Arm edges");

320 if (Info.checkOpcode(R.Wd))

321 return makeUnexpectedOpcodeError(G, R, Kind);

322

324}

325

327 Edge::Kind Kind) {

329 "Edge kind must be Thumb relocation");

330 const FixupInfoBase *Entry = DynFixupInfos->getEntry(Kind);

332 assert(Info.checkOpcode && "Opcode check is mandatory for Thumb edges");

333 if (Info.checkOpcode(R.Hi, R.Lo))

334 return makeUnexpectedOpcodeError(G, R, Kind);

335

337}

338

340 return DynFixupInfos->getEntry(K);

341}

342

343template <EdgeKind_aarch32 Kind>

349

350template <EdgeKind_aarch32 Kind>

353 return Wd == Reg;

354}

355

356template <EdgeKind_aarch32 Kind>

359 assert((Mask.Hi & Reg.Hi) == Reg.Hi && (Mask.Lo & Reg.Lo) == Reg.Lo &&

360 "Value bits exceed bit range of given mask");

361 R.Hi = (R.Hi & ~Mask.Hi) | Reg.Hi;

362 R.Lo = (R.Lo & ~Mask.Lo) | Reg.Lo;

363}

364

365template <EdgeKind_aarch32 Kind>

368 assert((Mask & Reg) == Reg && "Value bits exceed bit range of given mask");

369 R.Wd = (R.Wd & ~Mask) | Reg;

370}

371

372template <EdgeKind_aarch32 Kind>

375 assert((Mask.Hi & Imm.Hi) == Imm.Hi && (Mask.Lo & Imm.Lo) == Imm.Lo &&

376 "Value bits exceed bit range of given mask");

377 R.Hi = (R.Hi & ~Mask.Hi) | Imm.Hi;

378 R.Lo = (R.Lo & ~Mask.Lo) | Imm.Lo;

379}

380

381template <EdgeKind_aarch32 Kind>

384 assert((Mask & Imm) == Imm && "Value bits exceed bit range of given mask");

385 R.Wd = (R.Wd & ~Mask) | Imm;

386}

387

389 Edge::Kind Kind) {

391 const char *BlockWorkingMem = B.getContent().data();

392 const char *FixupPtr = BlockWorkingMem + Offset;

393

394 switch (Kind) {

401 default:

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

404 " can not read implicit addend for aarch32 edge kind " +

405 G.getEdgeKindName(Kind));

406 }

407}

408

410 Edge::Kind Kind) {

411 ArmRelocation R(B.getContent().data() + Offset);

413 return std::move(Err);

414

415 switch (Kind) {

419

423

424 default:

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

427 " can not read implicit addend for aarch32 edge kind " +

428 G.getEdgeKindName(Kind));

429 }

430}

431

433 Edge::Kind Kind, const ArmConfig &ArmCfg) {

434 ThumbRelocation R(B.getContent().data() + Offset);

436 return std::move(Err);

437

438 switch (Kind) {

444

447

449

452

454

455 default:

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

458 " can not read implicit addend for aarch32 edge kind " +

459 G.getEdgeKindName(Kind));

460 }

461}

462

465

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

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

468

469 Edge::Kind Kind = E.getKind();

470 uint64_t FixupAddress = (B.getAddress() + E.getOffset()).getValue();

471 int64_t Addend = E.getAddend();

472 Symbol &TargetSymbol = E.getTarget();

474

475

476

477 switch (Kind) {

479 int64_t Value = TargetAddress - FixupAddress + Addend;

484 else

487 }

489 int64_t Value = TargetAddress + Addend;

494 else

497 }

499 int64_t Value = TargetAddress - FixupAddress + Addend;

505 } else {

508 }

510 }

513 default:

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

516 " encountered unfixable aarch32 edge kind " +

517 G.getEdgeKindName(E.getKind()));

518 }

519}

520

522 WritableArmRelocation R(B.getAlreadyMutableContent().data() + E.getOffset());

523 Edge::Kind Kind = E.getKind();

525 return Err;

526

527 uint64_t FixupAddress = (B.getAddress() + E.getOffset()).getValue();

528 int64_t Addend = E.getAddend();

529 Symbol &TargetSymbol = E.getTarget();

531

532 switch (Kind) {

536 "stub when bridging to Thumb: " +

538

539 int64_t Value = TargetAddress - FixupAddress + Addend;

540

544

546 }

551 "BL/BLX branch instruction: " +

553

554 int64_t Value = TargetAddress - FixupAddress + Addend;

555

556

557

560 if (TargetIsThumb != InstrIsBlx) {

562

565 } else {

566

568 }

569 }

570

574

576 }

578 uint16_t Value = (TargetAddress + Addend) & 0xffff;

581 }

583 uint16_t Value = ((TargetAddress + Addend) >> 16) & 0xffff;

586 }

587 default:

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

590 " encountered unfixable aarch32 edge kind " +

591 G.getEdgeKindName(E.getKind()));

592 }

593}

594

597 WritableThumbRelocation R(B.getAlreadyMutableContent().data() +

598 E.getOffset());

599 Edge::Kind Kind = E.getKind();

601 return Err;

602

603 uint64_t FixupAddress = (B.getAddress() + E.getOffset()).getValue();

604 int64_t Addend = E.getAddend();

605 Symbol &TargetSymbol = E.getTarget();

607

608 switch (Kind) {

612 "stub when bridging to ARM: " +

614

615 int64_t Value = TargetAddress - FixupAddress + Addend;

620 } else {

624 }

625

627 }

628

630 int64_t Value = TargetAddress - FixupAddress + Addend;

631

632

633

636 if (TargetIsArm != InstrIsBlx) {

638

639

643 } else {

644

646 }

647 }

648

653 } else {

657 }

658

661 "Opcode BLX implies H bit is clear (avoid UB in BLX T2)");

663 }

664

666 uint16_t Value = (TargetAddress + Addend) & 0xffff;

669 }

671 uint16_t Value = ((TargetAddress + Addend) >> 16) & 0xffff;

674 }

676 uint16_t Value = ((TargetAddress + Addend - FixupAddress) & 0xffff);

679 }

681 uint16_t Value = (((TargetAddress + Addend - FixupAddress) >> 16) & 0xffff);

684 }

685

686 default:

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

689 " encountered unfixable aarch32 edge kind " +

690 G.getEdgeKindName(E.getKind()));

691 }

692}

693

695 0x00,

696 0x00,

697 0x00,

698 0x00,

699};

700

701

702template <size_t Size>

705 static_assert(Size == 4, "Pointers are 32-bit");

706 constexpr uint64_t Alignment = 4;

709}

710

712 if (!GOTSection)

715 constexpr int64_t GOTEntryAddend = 0;

717 return G.addAnonymousSymbol(B, 0, B.getSize(), false, false);

718}

719

721 Edge::Kind KindToSet = Edge::Invalid;

722 switch (E.getKind()) {

725 break;

726 }

727 default:

728 return false;

729 }

730 LLVM_DEBUG(dbgs() << " Transforming " << G.getEdgeKindName(E.getKind())

731 << " edge at " << B->getFixupAddress(E) << " ("

732 << B->getAddress() << " + "

733 << formatv("{0:x}", E.getOffset()) << ") into "

734 << G.getEdgeKindName(KindToSet) << "\n");

735 E.setKind(KindToSet);

737 return true;

738}

739

741 0x78, 0x47,

742 0xfd, 0xe7,

743 0x04, 0xf0, 0x1f, 0xe5,

744 0x00, 0x00, 0x00, 0x00,

745};

746

748 0x00, 0xc0, 0x00, 0xe3,

749 0x00, 0xc0, 0x40, 0xe3,

750 0x1c, 0xff, 0x2f, 0xe1

751};

752

754 0x40, 0xf2, 0x00, 0x0c,

755 0xc0, 0xf2, 0x00, 0x0c,

756 0x60, 0x47

757};

758

759

760template <size_t Size>

762 constexpr uint64_t Alignment = 4;

765}

766

772

777

778 [[maybe_unused]] const char *StubPtr = B.getContent().data();

782 "Linker generated stubs may only corrupt register r12 (IP)");

783 return B;

784}

785

790

791 [[maybe_unused]] const char *StubPtr = B.getContent().data();

795 "Linker generated stubs may only corrupt register r12 (IP)");

796 return B;

797}

798

801

802

803 if (Target.isDefined()) {

804 switch (E.getKind()) {

809 return true;

810 default:

811 return false;

812 }

813 }

814

815

816

818 switch (E.getKind()) {

820 return TargetIsThumb;

822 return !TargetIsThumb;

823 default:

824 break;

825 }

826

827 return false;

828}

829

830

831

832

833Symbol *StubsManager_prev7::getOrCreateSlotEntrypoint(LinkGraph &G,

834 StubMapEntry &Slot,

835 bool Thumb) {

838 if (Thumb && !Slot.ThumbEntry) {

839 Slot.ThumbEntry =

840 &G.addAnonymousSymbol(*Slot.B, ThumbEntrypointOffset, 4, true, false);

841 Slot.ThumbEntry->setTargetFlags(ThumbSymbol);

842 }

843 if (!Thumb && !Slot.ArmEntry)

844 Slot.ArmEntry =

845 &G.addAnonymousSymbol(*Slot.B, ArmEntrypointOffset, 8, true, false);

846 return Thumb ? Slot.ThumbEntry : Slot.ArmEntry;

847}

848

851 return false;

852

854 assert(Target.hasName() && "Edge cannot point to anonymous target");

855 auto [Slot, NewStub] = getStubMapSlot(*Target.getName());

856

857 if (NewStub) {

858 if (!StubsSection)

862 dbgs() << " Created stub entry for " << Target.getName() << " in "

863 << StubsSection->getName() << "\n";

864 });

866 }

867

868

869

870

872 Symbol *StubEntrypoint = getOrCreateSlotEntrypoint(G, *Slot, UseThumb);

873

875 dbgs() << " Using " << (UseThumb ? "Thumb" : "Arm") << " entrypoint "

876 << *StubEntrypoint << " in "

878 });

879

880 E.setTarget(*StubEntrypoint);

881 return true;

882}

883

886 return false;

887

888

889

891 LLVM_DEBUG(dbgs() << " Preparing " << (MakeThumb ? "Thumb" : "Arm")

892 << " stub for " << G.getEdgeKindName(E.getKind())

893 << " edge at " << B->getFixupAddress(E) << " ("

894 << B->getAddress() << " + "

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

896

898 assert(Target.hasName() && "Edge cannot point to anonymous target");

900

901 if (!StubSymbol) {

902 if (!StubsSection)

907 StubSymbol = &G.addAnonymousSymbol(B, 0, B.getSize(), true, false);

908 if (MakeThumb)

910

912 dbgs() << " Created " << (MakeThumb ? "Thumb" : "Arm") << " entry for "

913 << Target.getName() << " in " << StubsSection->getName() << ": "

914 << *StubSymbol << "\n";

915 });

916 }

917

919 "Instruction set states of stub and relocation site should be equal");

921 dbgs() << " Using " << (MakeThumb ? "Thumb" : "Arm") << " entry "

923 << "\n";

924 });

925

926 E.setTarget(*StubSymbol);

927 return true;

928}

929

931#define KIND_NAME_CASE(K) \

932 case K: \

933 return #K;

934

935 switch (K) {

951 default:

953 }

954#undef KIND_NAME_CASE

955}

956

958#define CPUARCH_NAME_CASE(K) \

959 case K: \

960 return #K;

961

963 switch (K) {

984 }

986#undef CPUARCH_NAME_CASE

987}

988

989}

990}

991}

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

static bool isThumb(const MCSubtargetInfo &STI)

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

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

Analysis containing CSE Info

#define LLVM_LIKELY(EXPR)

#define CPUARCH_NAME_CASE(K)

#define KIND_NAME_CASE(K)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

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

Target - Wrapper for Target specific information.

const char * getName() const

getName - Get the target name.

LLVM Value Representation.

An Addressable with content and edges.

Represents fixups and constraints in the LinkGraph.

Represents an object file section.

StringRef getName() const

Returns the name of this section.

TargetFlagsType getTargetFlags() const

Get the target flags of this Symbol.

void setTargetFlags(TargetFlagsType Flags)

Set the target flags for this Symbol.

orc::ExecutorAddr getAddress() const

Returns the address of this symbol.

Section & getSection() const

Return the Section for this Symbol (Symbol must be defined).

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

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

Definition aarch32.cpp:720

static StringRef getSectionName()

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

Definition aarch32.cpp:711

static StringRef getSectionName()

Name of the object file section that will contain all our stubs.

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

Implements link-graph traversal via visitExistingEdges()

Definition aarch32.cpp:849

static StringRef getSectionName()

Name of the object file section that will contain all our stubs.

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

Implements link-graph traversal via visitExistingEdges().

Definition aarch32.cpp:884

Represents an address in the executor process.

uint64_t getValue() const

#define llvm_unreachable(msg)

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

EdgeKind_aarch32

JITLink-internal AArch32 fixup kinds.

@ Data_RequestGOTAndTransformToDelta32

Create GOT entry and store offset.

@ Arm_MovtAbs

Write immediate value to the top halfword of the destination register.

@ Data_PRel31

Relative 31-bit value relocation that preserves the most-significant bit.

@ Data_Pointer32

Absolute 32-bit value relocation.

@ FirstThumbRelocation

Relocations of class Thumb16 and Thumb32 (covers Thumb instruction subset)

@ Arm_MovwAbsNC

Write immediate value to the lower halfword of the destination register.

@ Arm_Call

Write immediate value for unconditional PC-relative branch with link.

@ Thumb_MovtPrel

Write PC-relative immediate value to the top halfword of the destination register.

@ Thumb_Jump24

Write immediate value for PC-relative branch without link.

@ Arm_Jump24

Write immediate value for conditional PC-relative branch without link.

@ Thumb_MovwAbsNC

Write immediate value to the lower halfword of the destination register.

@ FirstArmRelocation

Relocations of class Arm (covers fixed-width 4-byte instruction subset)

@ Data_Delta32

Relative 32-bit value relocation.

@ Thumb_Call

Write immediate value for unconditional PC-relative branch with link.

@ Thumb_MovtAbs

Write immediate value to the top halfword of the destination register.

@ Thumb_MovwPrelNC

Write PC-relative immediate value to the lower halfword of the destination register.

static Block & createStubThumbv7(LinkGraph &G, Section &S, Symbol &Target)

Definition aarch32.cpp:773

LLVM_ABI Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E, const ArmConfig &ArmCfg)

Helper function to apply the fixup for Thumb-class relocations.

Definition aarch32.cpp:595

int64_t decodeImmBT4BlT1BlxT2(uint32_t Hi, uint32_t Lo)

Decode 22-bit immediate value for branch instructions without J1J2 range extension (formats B T4,...

Definition aarch32.cpp:53

static bool needsStub(const Edge &E)

Definition aarch32.cpp:799

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

Helper function to apply the fixup for Data-class relocations.

Definition aarch32.cpp:463

LLVM_ABI Expected< int64_t > readAddendData(LinkGraph &G, Block &B, Edge::OffsetT Offset, Edge::Kind Kind)

Helper function to read the initial addend for Data-class relocations.

Definition aarch32.cpp:388

HalfWords encodeImmBT4BlT1BlxT2(int64_t Value)

Encode 22-bit immediate value for branch instructions without J1J2 range extension (formats B T4,...

Definition aarch32.cpp:40

LLVM_ABI const char * getCPUArchName(ARMBuildAttrs::CPUArch K)

Human-readable name for a given CPU architecture kind.

Definition aarch32.cpp:957

LLVM_ABI uint32_t encodeRegMovtA1MovwA2(int64_t Value)

Encode register ID for instruction formats MOVT A1 and MOVW A2.

Definition aarch32.cpp:178

LLVM_ABI int64_t decodeRegMovtA1MovwA2(uint64_t Value)

Decode register ID for instruction formats MOVT A1 and MOVW A2.

Definition aarch32.cpp:188

LLVM_ABI uint16_t decodeImmMovtT1MovwT3(uint32_t Hi, uint32_t Lo)

Decode 16-bit immediate value from move instruction formats MOVT T1 and MOVW T3.

Definition aarch32.cpp:123

const uint8_t ArmThumbv5LdrPc[]

Definition aarch32.cpp:740

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

Helper function to apply the fixup for Arm-class relocations.

Definition aarch32.cpp:521

LLVM_ABI int64_t decodeImmBT4BlT1BlxT2_J1J2(uint32_t Hi, uint32_t Lo)

Decode 25-bit immediate value for branch instructions with J1J2 range extension (formats B T4,...

Definition aarch32.cpp:78

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

Get a human-readable name for the given AArch32 edge kind.

Definition aarch32.cpp:930

LLVM_ABI HalfWords encodeRegMovtT1MovwT3(int64_t Value)

Encode register ID for instruction formats MOVT T1 and MOVW T3.

Definition aarch32.cpp:137

LLVM_ABI bool hasTargetFlags(Symbol &Sym, TargetFlagsType Flags)

Check whether the given target flags are set for this Symbol.

Definition aarch32.cpp:30

static Block & allocStub(LinkGraph &G, Section &S, const uint8_t(&Code)[Size])

Create a new node in the link-graph for the given stub template.

Definition aarch32.cpp:761

const uint8_t GOTEntryInit[]

Definition aarch32.cpp:694

const uint8_t Thumbv7ABS[]

Definition aarch32.cpp:753

LLVM_ABI HalfWords encodeImmBT4BlT1BlxT2_J1J2(int64_t Value)

Encode 25-bit immediate value for branch instructions with J1J2 range extension (formats B T4,...

Definition aarch32.cpp:64

static Error checkOpcode(LinkGraph &G, const ArmRelocation &R, Edge::Kind Kind)

Definition aarch32.cpp:313

LLVM_ABI Expected< int64_t > readAddendThumb(LinkGraph &G, Block &B, Edge::OffsetT Offset, Edge::Kind Kind, const ArmConfig &ArmCfg)

Helper function to read the initial addend for Thumb-class relocations.

Definition aarch32.cpp:432

const uint8_t Armv7ABS[]

Definition aarch32.cpp:747

void writeRegister(WritableThumbRelocation &R, HalfWords Reg)

Definition aarch32.cpp:357

LLVM_ABI HalfWords encodeImmMovtT1MovwT3(uint16_t Value)

Encode 16-bit immediate value for move instruction formats MOVT T1 and MOVW T3.

Definition aarch32.cpp:110

bool checkRegister(const ThumbRelocation &R, HalfWords Reg)

Definition aarch32.cpp:344

LLVM_ABI uint32_t encodeImmBA1BlA1BlxA2(int64_t Value)

Encode 26-bit immediate value for branch instructions (formats B A1, BL A1 and BLX A2).

Definition aarch32.cpp:92

static Block & allocPointer(LinkGraph &G, Section &S, const uint8_t(&Content)[Size])

Create a new node in the link-graph for the given pointer value.

Definition aarch32.cpp:703

LLVM_ABI uint16_t decodeImmMovtA1MovwA2(uint64_t Value)

Decode 16-bit immediate value for move instruction formats MOVT A1 and MOVW A2.

Definition aarch32.cpp:167

void writeImmediate(WritableThumbRelocation &R, HalfWords Imm)

Definition aarch32.cpp:373

LLVM_ABI int64_t decodeImmBA1BlA1BlxA2(int64_t Value)

Decode 26-bit immediate value for branch instructions (formats B A1, BL A1 and BLX A2).

Definition aarch32.cpp:101

static Block & createStubArmv7(LinkGraph &G, Section &S, Symbol &Target)

Definition aarch32.cpp:786

LLVM_ABI uint32_t encodeImmMovtA1MovwA2(uint16_t Value)

Encode 16-bit immediate value for move instruction formats MOVT A1 and MOVW A2.

Definition aarch32.cpp:156

LLVM_ABI int64_t decodeRegMovtT1MovwT3(uint32_t Hi, uint32_t Lo)

Decode register ID from instruction formats MOVT T1 and MOVW T3.

Definition aarch32.cpp:146

LLVM_ABI Expected< int64_t > readAddendArm(LinkGraph &G, Block &B, Edge::OffsetT Offset, Edge::Kind Kind)

Helper function to read the initial addend for Arm-class relocations.

Definition aarch32.cpp:409

static Block & createStubPrev7(LinkGraph &G, Section &S, Symbol &Target)

Definition aarch32.cpp:767

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.

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

Returns the string name of the given generic edge kind, or "unknown" otherwise.

uint8_t TargetFlagsType

Holds target-specific properties for a symbol.

uint64_t ExecutorAddrDiff

uint32_t read32(const void *P, endianness E)

void write32le(void *P, uint32_t V)

void write32be(void *P, uint32_t V)

uint32_t read32be(const void *P)

uint32_t read32le(const void *P)

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

detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_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.

constexpr bool isUInt(uint64_t x)

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

Error make_error(ArgTs &&... Args)

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

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

FunctionAddr VTableAddr Next

constexpr int64_t SignExtend64(uint64_t x)

Sign-extend the number in the bottom B bits of X to a 64-bit integer.

JITLink sub-arch configuration for Arm CPU models.

FixupInfo checks for Arm edge kinds work on 32-bit words.

FixupInfo base class is required for dynamic lookups.

static LLVM_ABI const FixupInfoBase * getDynFixupInfo(Edge::Kind K)

Definition aarch32.cpp:339

FixupInfo check for Thumb32 edge kinds work on a pair of 16-bit halfwords.

Collection of named constants per fixup kind.

Immutable pair of halfwords, Hi and Lo, with overflow check.