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 (.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 (.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 (.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.