LLVM 20.0.0git
x86_64.h
Go to the documentation of this file.
1//===-- x86_64.h - Generic JITLink x86-64 edge kinds, utilities -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Generic utilities for graphs representing x86-64 objects.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_JITLINK_X86_64_H
14#define LLVM_EXECUTIONENGINE_JITLINK_X86_64_H
15
18
19namespace llvm {
20namespace jitlink {
21namespace x86_64 {
22
23/// Represents x86-64 fixups and other x86-64-specific edge kinds.
25
26 /// A plain 64-bit pointer value relocation.
27 ///
28 /// Fixup expression:
29 /// Fixup <- Target + Addend : uint64
30 ///
32
33 /// A plain 32-bit pointer value relocation.
34 ///
35 /// Fixup expression:
36 /// Fixup <- Target + Addend : uint32
37 ///
38 /// Errors:
39 /// - The target must reside in the low 32-bits of the address space,
40 /// otherwise an out-of-range error will be returned.
41 ///
43
44 /// A signed 32-bit pointer value relocation
45 ///
46 /// Fixup expression:
47 /// Fixup <- Target + Addend : int32
48 ///
49 /// Errors:
50 /// - The target must reside in the signed 32-bits([-2**31, 2**32 - 1]) of
51 /// the address space, otherwise an out-of-range error will be returned.
53
54 /// A plain 16-bit pointer value relocation.
55 ///
56 /// Fixup expression:
57 /// Fixup <- Target + Addend : uint16
58 ///
59 /// Errors:
60 /// - The target must reside in the low 16-bits of the address space,
61 /// otherwise an out-of-range error will be returned.
62 ///
64
65 /// A plain 8-bit pointer value relocation.
66 ///
67 /// Fixup expression:
68 /// Fixup <- Target + Addend : uint8
69 ///
70 /// Errors:
71 /// - The target must reside in the low 8-bits of the address space,
72 /// otherwise an out-of-range error will be returned.
73 ///
75
76 /// A 64-bit delta.
77 ///
78 /// Delta from the fixup to the target.
79 ///
80 /// Fixup expression:
81 /// Fixup <- Target - Fixup + Addend : int64
82 ///
84
85 /// A 32-bit delta.
86 ///
87 /// Delta from the fixup to the target.
88 ///
89 /// Fixup expression:
90 /// Fixup <- Target - Fixup + Addend : int32
91 ///
92 /// Errors:
93 /// - The result of the fixup expression must fit into an int32, otherwise
94 /// an out-of-range error will be returned.
95 ///
97
98 /// A 16-bit delta.
99 ///
100 /// Delta from the fixup to the target.
101 ///
102 /// Fixup expression:
103 /// Fixup <- Target - Fixup + Addend : int16
104 ///
105 /// Errors:
106 /// - The result of the fixup expression must fit into an int16, otherwise
107 /// an out-of-range error will be returned.
108 ///
110
111 /// An 8-bit delta.
112 ///
113 /// Delta from the fixup to the target.
114 ///
115 /// Fixup expression:
116 /// Fixup <- Target - Fixup + Addend : int8
117 ///
118 /// Errors:
119 /// - The result of the fixup expression must fit into an int8, otherwise
120 /// an out-of-range error will be returned.
121 ///
123
124 /// A 64-bit negative delta.
125 ///
126 /// Delta from target back to the fixup.
127 ///
128 /// Fixup expression:
129 /// Fixup <- Fixup - Target + Addend : int64
130 ///
132
133 /// A 32-bit negative delta.
134 ///
135 /// Delta from the target back to the fixup.
136 ///
137 /// Fixup expression:
138 /// Fixup <- Fixup - Target + Addend : int32
139 ///
140 /// Errors:
141 /// - The result of the fixup expression must fit into an int32, otherwise
142 /// an out-of-range error will be returned.
144
145 /// A 64-bit size relocation.
146 ///
147 /// Fixup expression:
148 /// Fixup <- Size + Addend : uint64
149 ///
151
152 /// A 32-bit size relocation.
153 ///
154 /// Fixup expression:
155 /// Fixup <- Size + Addend : uint32
156 ///
157 /// Errors:
158 /// - The result of the fixup expression must fit into an uint32, otherwise
159 /// an out-of-range error will be returned.
160 ///
162
163 /// A 64-bit GOT delta.
164 ///
165 /// Delta from the global offset table to the target
166 ///
167 /// Fixup expression:
168 /// Fixup <- Target - GOTSymbol + Addend : int64
169 ///
170 /// Errors:
171 /// - *ASSERTION* Failure to a null pointer GOTSymbol, which the GOT section
172 /// symbol was not been defined.
174
175 /// A 32-bit PC-relative branch.
176 ///
177 /// Represents a PC-relative call or branch to a target. This can be used to
178 /// identify, record, and/or patch call sites.
179 ///
180 /// The fixup expression for this kind includes an implicit offset to account
181 /// for the PC (unlike the Delta edges) so that a Branch32PCRel with a target
182 /// T and addend zero is a call/branch to the start (offset zero) of T.
183 ///
184 /// Fixup expression:
185 /// Fixup <- Target - (Fixup + 4) + Addend : int32
186 ///
187 /// Errors:
188 /// - The result of the fixup expression must fit into an int32, otherwise
189 /// an out-of-range error will be returned.
190 ///
192
193 /// A 32-bit PC-relative relocation.
194 ///
195 /// Represents a data/control flow instruction using PC-relative addressing
196 /// to a target.
197 ///
198 /// The fixup expression for this kind includes an implicit offset to account
199 /// for the PC (unlike the Delta edges) so that a PCRel32 with a target
200 /// T and addend zero is a call/branch to the start (offset zero) of T.
201 ///
202 /// Fixup expression:
203 /// Fixup <- Target - (Fixup + 4) + Addend : int32
204 ///
205 /// Errors:
206 /// - The result of the fixup expression must fit into an int32, otherwise
207 /// an out-of-range error will be returned.
208 ///
210
211 /// A 32-bit PC-relative branch to a pointer jump stub.
212 ///
213 /// The target of this relocation should be a pointer jump stub of the form:
214 ///
215 /// \code{.s}
216 /// .text
217 /// jmpq *tgtptr(%rip)
218 /// ; ...
219 ///
220 /// .data
221 /// tgtptr:
222 /// .quad 0
223 /// \endcode
224 ///
225 /// This edge kind has the same fixup expression as BranchPCRel32, but further
226 /// identifies the call/branch as being to a pointer jump stub. For edges of
227 /// this kind the jump stub should not be bypassed (use
228 /// BranchPCRel32ToPtrJumpStubBypassable for that), but the pointer location
229 /// target may be recorded to allow manipulation at runtime.
230 ///
231 /// Fixup expression:
232 /// Fixup <- Target - Fixup + Addend - 4 : int32
233 ///
234 /// Errors:
235 /// - The result of the fixup expression must fit into an int32, otherwise
236 /// an out-of-range error will be returned.
237 ///
239
240 /// A relaxable version of BranchPCRel32ToPtrJumpStub.
241 ///
242 /// The edge kind has the same fixup expression as BranchPCRel32ToPtrJumpStub,
243 /// but identifies the call/branch as being to a pointer jump stub that may be
244 /// bypassed with a direct jump to the ultimate target if the ultimate target
245 /// is within range of the fixup location.
246 ///
247 /// Fixup expression:
248 /// Fixup <- Target - Fixup + Addend - 4: int32
249 ///
250 /// Errors:
251 /// - The result of the fixup expression must fit into an int32, otherwise
252 /// an out-of-range error will be returned.
253 ///
255
256 /// A GOT entry getter/constructor, transformed to Delta32 pointing at the GOT
257 /// entry for the original target.
258 ///
259 /// Indicates that this edge should be transformed into a Delta32 targeting
260 /// the GOT entry for the edge's current target, maintaining the same addend.
261 /// A GOT entry for the target should be created if one does not already
262 /// exist.
263 ///
264 /// Edges of this kind are usually handled by a GOT builder pass inserted by
265 /// default.
266 ///
267 /// Fixup expression:
268 /// NONE
269 ///
270 /// Errors:
271 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
272 /// phase will result in an assert/unreachable during the fixup phase.
273 ///
275
276 /// A GOT entry getter/constructor, transformed to Delta64 pointing at the GOT
277 /// entry for the original target.
278 ///
279 /// Indicates that this edge should be transformed into a Delta64 targeting
280 /// the GOT entry for the edge's current target, maintaining the same addend.
281 /// A GOT entry for the target should be created if one does not already
282 /// exist.
283 ///
284 /// Edges of this kind are usually handled by a GOT builder pass inserted by
285 /// default.
286 ///
287 /// Fixup expression:
288 /// NONE
289 ///
290 /// Errors:
291 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
292 /// phase will result in an assert/unreachable during the fixup phase.
293 ///
295
296 /// A GOT entry offset within GOT getter/constructor, transformed to
297 /// Delta64FromGOT
298 /// pointing at the GOT entry for the original target
299 ///
300 /// Indicates that this edge should be transformed into a Delta64FromGOT
301 /// targeting
302 /// the GOT entry for the edge's current target, maintaining the same addend.
303 /// A GOT entry for the target should be created if one does not already
304 /// exist.
305 ///
306 /// Edges of this kind are usually handled by a GOT builder pass inserted by
307 /// default
308 ///
309 /// Fixup expression:
310 /// NONE
311 ///
312 /// Errors:
313 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
314 /// phase will result in an assert/unreachable during the fixup phase
316
317 /// A PC-relative load of a GOT entry, relaxable if GOT entry target is
318 /// in-range of the fixup
319 ///
320 /// TODO: Explain the optimization
321 ///
322 /// Fixup expression
323 /// Fixup <- Target - (Fixup + 4) + Addend : int32
324 ///
325 /// Errors:
326 /// - The result of the fixup expression must fit into an int32, otherwise
327 /// an out-of-range error will be returned.
328 //
330
331 /// A PC-relative REX load of a GOT entry, relaxable if GOT entry target
332 /// is in-range of the fixup.
333 ///
334 /// If the GOT entry target is in-range of the fixup then the load from the
335 /// GOT may be replaced with a direct memory address calculation.
336 ///
337 /// Fixup expression:
338 /// Fixup <- Target - (Fixup + 4) + Addend : int32
339 ///
340 /// Errors:
341 /// - The result of the fixup expression must fit into an int32, otherwise
342 /// an out-of-range error will be returned.
343 ///
345
346 /// A GOT entry getter/constructor, transformed to
347 /// PCRel32ToGOTLoadREXRelaxable pointing at the GOT entry for the original
348 /// target.
349 ///
350 /// Indicates that this edge should be lowered to a PC32ToGOTLoadREXRelaxable
351 /// targeting the GOT entry for the edge's current target, maintaining the
352 /// same addend. A GOT entry for the target should be created if one does not
353 /// already exist.
354 ///
355 /// Edges of this kind are usually lowered by a GOT builder pass inserted by
356 /// default.
357 ///
358 /// Fixup expression:
359 /// NONE
360 ///
361 /// Errors:
362 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
363 /// phase will result in an assert/unreachable during the fixup phase.
364 ///
366
367 /// A GOT entry getter/constructor, transformed to
368 /// PCRel32ToGOTLoadRelaxable pointing at the GOT entry for the original
369 /// target.
370 ///
371 /// Indicates that this edge should be lowered to a PC32ToGOTLoadRelaxable
372 /// targeting the GOT entry for the edge's current target, maintaining the
373 /// same addend. A GOT entry for the target should be created if one does not
374 /// already exist.
375 ///
376 /// Edges of this kind are usually lowered by a GOT builder pass inserted by
377 /// default.
378 ///
379 /// Fixup expression:
380 /// NONE
381 ///
382 /// Errors:
383 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
384 /// phase will result in an assert/unreachable during the fixup phase.
385 ///
387
388 /// A PC-relative REX load of a Thread Local Variable Pointer (TLVP) entry,
389 /// relaxable if the TLVP entry target is in-range of the fixup.
390 ///
391 /// If the TLVP entry target is in-range of the fixup then the load from the
392 /// TLVP may be replaced with a direct memory address calculation.
393 ///
394 /// The target of this edge must be a thread local variable entry of the form
395 /// .quad <tlv getter thunk>
396 /// .quad <tlv key>
397 /// .quad <tlv initializer>
398 ///
399 /// Fixup expression:
400 /// Fixup <- Target - (Fixup + 4) + Addend : int32
401 ///
402 /// Errors:
403 /// - The result of the fixup expression must fit into an int32, otherwise
404 /// an out-of-range error will be returned.
405 /// - The target must be either external, or a TLV entry of the required
406 /// form, otherwise a malformed TLV entry error will be returned.
407 ///
409
410 /// TODO: Explain the generic edge kind
412
413 /// A TLVP entry getter/constructor, transformed to
414 /// Delta32ToTLVPLoadREXRelaxable.
415 ///
416 /// Indicates that this edge should be transformed into a
417 /// Delta32ToTLVPLoadREXRelaxable targeting the TLVP entry for the edge's
418 /// current target. A TLVP entry for the target should be created if one does
419 /// not already exist.
420 ///
421 /// Fixup expression:
422 /// NONE
423 ///
424 /// Errors:
425 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
426 /// phase will result in an assert/unreachable during the fixup phase.
427 ///
429 // First platform specific relocation.
432
433/// Returns a string name for the given x86-64 edge. For debugging purposes
434/// only.
435const char *getEdgeKindName(Edge::Kind K);
436
437/// Apply fixup expression for edge to block content.
439 const Symbol *GOTSymbol) {
440 using namespace support;
441
442 char *BlockWorkingMem = B.getAlreadyMutableContent().data();
443 char *FixupPtr = BlockWorkingMem + E.getOffset();
444 auto FixupAddress = B.getAddress() + E.getOffset();
445
446 switch (E.getKind()) {
447
448 case Pointer64: {
449 uint64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();
450 *(ulittle64_t *)FixupPtr = Value;
451 break;
452 }
453
454 case Pointer32: {
455 uint64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();
456 if (LLVM_LIKELY(isUInt<32>(Value)))
457 *(ulittle32_t *)FixupPtr = Value;
458 else
459 return makeTargetOutOfRangeError(G, B, E);
460 break;
461 }
462 case Pointer32Signed: {
463 int64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();
464 if (LLVM_LIKELY(isInt<32>(Value)))
465 *(little32_t *)FixupPtr = Value;
466 else
467 return makeTargetOutOfRangeError(G, B, E);
468 break;
469 }
470
471 case Pointer16: {
472 uint64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();
473 if (LLVM_LIKELY(isUInt<16>(Value)))
474 *(ulittle16_t *)FixupPtr = Value;
475 else
476 return makeTargetOutOfRangeError(G, B, E);
477 break;
478 }
479
480 case Pointer8: {
481 uint64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();
482 if (LLVM_LIKELY(isUInt<8>(Value)))
483 *(uint8_t *)FixupPtr = Value;
484 else
485 return makeTargetOutOfRangeError(G, B, E);
486 break;
487 }
488
489 case PCRel32:
490 case BranchPCRel32:
496 int64_t Value =
497 E.getTarget().getAddress() - (FixupAddress + 4) + E.getAddend();
498 if (LLVM_LIKELY(isInt<32>(Value)))
499 *(little32_t *)FixupPtr = Value;
500 else
501 return makeTargetOutOfRangeError(G, B, E);
502 break;
503 }
504
505 case Delta64: {
506 int64_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
507 *(little64_t *)FixupPtr = Value;
508 break;
509 }
510
511 case Delta32: {
512 int64_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
513 if (LLVM_LIKELY(isInt<32>(Value)))
514 *(little32_t *)FixupPtr = Value;
515 else
516 return makeTargetOutOfRangeError(G, B, E);
517 break;
518 }
519
520 case Delta16: {
521 int64_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
522 if (LLVM_LIKELY(isInt<16>(Value)))
523 *(little16_t *)FixupPtr = Value;
524 else
525 return makeTargetOutOfRangeError(G, B, E);
526 break;
527 }
528
529 case Delta8: {
530 int64_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
531 if (LLVM_LIKELY(isInt<8>(Value)))
532 *FixupPtr = Value;
533 else
534 return makeTargetOutOfRangeError(G, B, E);
535 break;
536 }
537
538 case NegDelta64: {
539 int64_t Value = FixupAddress - E.getTarget().getAddress() + E.getAddend();
540 *(little64_t *)FixupPtr = Value;
541 break;
542 }
543
544 case NegDelta32: {
545 int64_t Value = FixupAddress - E.getTarget().getAddress() + E.getAddend();
546 if (LLVM_LIKELY(isInt<32>(Value)))
547 *(little32_t *)FixupPtr = Value;
548 else
549 return makeTargetOutOfRangeError(G, B, E);
550 break;
551 }
552
553 case Size64: {
554 uint64_t Value = E.getTarget().getSize() + E.getAddend();
555 *(ulittle64_t *)FixupPtr = Value;
556 break;
557 }
558
559 case Size32: {
560 uint64_t Value = E.getTarget().getSize() + E.getAddend();
561 if (LLVM_LIKELY(isUInt<32>(Value)))
562 *(ulittle32_t *)FixupPtr = Value;
563 else
564 return makeTargetOutOfRangeError(G, B, E);
565 break;
566 }
567
568 case Delta64FromGOT: {
569 assert(GOTSymbol && "No GOT section symbol");
570 int64_t Value =
571 E.getTarget().getAddress() - GOTSymbol->getAddress() + E.getAddend();
572 *(little64_t *)FixupPtr = Value;
573 break;
574 }
575
576 default:
577 return make_error<JITLinkError>(
578 "In graph " + G.getName() + ", section " + B.getSection().getName() +
579 " unsupported edge kind " + getEdgeKindName(E.getKind()));
580 }
581
582 return Error::success();
583}
584
585/// x86_64 pointer size.
586constexpr uint64_t PointerSize = 8;
587
588/// x86-64 null pointer content.
589extern const char NullPointerContent[PointerSize];
590
591/// x86-64 pointer jump stub content.
592///
593/// Contains the instruction sequence for an indirect jump via an in-memory
594/// pointer:
595/// jmpq *ptr(%rip)
596extern const char PointerJumpStubContent[6];
597
598/// Creates a new pointer block in the given section and returns an anonymous
599/// symbol pointing to it.
600///
601/// If InitialTarget is given then an Pointer64 relocation will be added to the
602/// block pointing at InitialTarget.
603///
604/// The pointer block will have the following default values:
605/// alignment: 64-bit
606/// alignment-offset: 0
607/// address: highest allowable (~7U)
609 Symbol *InitialTarget = nullptr,
610 uint64_t InitialAddend = 0) {
611 auto &B = G.createContentBlock(PointerSection, NullPointerContent,
612 orc::ExecutorAddr(~uint64_t(7)), 8, 0);
613 if (InitialTarget)
614 B.addEdge(Pointer64, 0, *InitialTarget, InitialAddend);
615 return G.addAnonymousSymbol(B, 0, 8, false, false);
616}
617
618/// Create a jump stub block that jumps via the pointer at the given symbol.
619///
620/// The stub block will have the following default values:
621/// alignment: 8-bit
622/// alignment-offset: 0
623/// address: highest allowable: (~5U)
625 Symbol &PointerSymbol) {
626 auto &B = G.createContentBlock(StubSection, PointerJumpStubContent,
627 orc::ExecutorAddr(~uint64_t(5)), 1, 0);
628 B.addEdge(BranchPCRel32, 2, PointerSymbol, 0);
629 return B;
630}
631
632/// Create a jump stub that jumps via the pointer at the given symbol and
633/// an anonymous symbol pointing to it. Return the anonymous symbol.
634///
635/// The stub block will be created by createPointerJumpStubBlock.
637 Section &StubSection,
638 Symbol &PointerSymbol) {
639 return G.addAnonymousSymbol(
640 createPointerJumpStubBlock(G, StubSection, PointerSymbol), 0, 6, true,
641 false);
642}
643
644/// x86-64 reentry trampoline.
645///
646/// Contains the instruction sequence for a trampoline that stores its return
647/// address on the stack and calls <reentry-symbol>:
648/// call <reentry-symbol>
649extern const char ReentryTrampolineContent[5];
650
651/// Create a block of N reentry trampolines.
653 Section &TrampolineSection,
654 Symbol &ReentrySymbol) {
655 auto &B = G.createContentBlock(TrampolineSection, ReentryTrampolineContent,
656 orc::ExecutorAddr(~uint64_t(7)), 1, 0);
657 B.addEdge(BranchPCRel32, 1, ReentrySymbol, 0);
658 return B;
659}
660
662 Section &TrampolineSection,
663 Symbol &ReentrySymbol) {
664 return G.addAnonymousSymbol(
665 createReentryTrampolineBlock(G, TrampolineSection, ReentrySymbol), 0,
666 sizeof(ReentryTrampolineContent), true, false);
667}
668
669/// Global Offset Table Builder.
670class GOTTableManager : public TableManager<GOTTableManager> {
671public:
672 static StringRef getSectionName() { return "$__GOT"; }
673
675 Edge::Kind KindToSet = Edge::Invalid;
676 switch (E.getKind()) {
678 // we need to make sure that the GOT section exists, but don't otherwise
679 // need to fix up this edge
680 getGOTSection(G);
681 return false;
682 }
685 break;
688 break;
690 KindToSet = x86_64::Delta64;
691 break;
693 KindToSet = x86_64::Delta64FromGOT;
694 break;
696 KindToSet = x86_64::Delta32;
697 break;
698 default:
699 return false;
700 }
701 assert(KindToSet != Edge::Invalid &&
702 "Fell through switch, but no new kind to set");
703 DEBUG_WITH_TYPE("jitlink", {
704 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
705 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "
706 << formatv("{0:x}", E.getOffset()) << ")\n";
707 });
708 E.setKind(KindToSet);
709 E.setTarget(getEntryForTarget(G, E.getTarget()));
710 return true;
711 }
712
714 return createAnonymousPointer(G, getGOTSection(G), &Target);
715 }
716
717private:
718 Section &getGOTSection(LinkGraph &G) {
719 if (!GOTSection)
720 GOTSection = &G.createSection(getSectionName(), orc::MemProt::Read);
721 return *GOTSection;
722 }
723
724 Section *GOTSection = nullptr;
725};
726
727/// Procedure Linkage Table Builder.
728class PLTTableManager : public TableManager<PLTTableManager> {
729public:
731
732 static StringRef getSectionName() { return "$__STUBS"; }
733
735 if (E.getKind() == x86_64::BranchPCRel32 && !E.getTarget().isDefined()) {
736 DEBUG_WITH_TYPE("jitlink", {
737 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
738 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "
739 << formatv("{0:x}", E.getOffset()) << ")\n";
740 });
741 // Set the edge kind to Branch32ToPtrJumpStubBypassable to enable it to
742 // be optimized when the target is in-range.
744 E.setTarget(getEntryForTarget(G, E.getTarget()));
745 return true;
746 }
747 return false;
748 }
749
753 }
754
755public:
757 if (!PLTSection)
758 PLTSection = &G.createSection(getSectionName(),
760 return *PLTSection;
761 }
762
764 Section *PLTSection = nullptr;
765};
766
767/// Optimize the GOT and Stub relocations if the edge target address is in range
768/// 1. PCRel32GOTLoadRelaxable. For this edge kind, if the target is in range,
769/// then replace GOT load with lea
770/// 2. BranchPCRel32ToPtrJumpStubRelaxable. For this edge kind, if the target is
771/// in range, replace a indirect jump by plt stub with a direct jump to the
772/// target
774
775} // namespace x86_64
776} // end namespace jitlink
777} // end namespace llvm
778
779#endif // LLVM_EXECUTIONENGINE_JITLINK_X86_64_H
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:319
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition: Debug.h:64
#define G(x, y, z)
Definition: MD5.cpp:56
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Target - Wrapper for Target specific information.
LLVM Value Representation.
Definition: Value.h:74
Represents an address in the executor process.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163