LLVM 22.0.0git
systemz.h
Go to the documentation of this file.
1//=== systemz.h - Generic JITLink systemz 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 systemz objects.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_JITLINK_SYSTEMZ_H
14#define LLVM_EXECUTIONENGINE_JITLINK_SYSTEMZ_H
15
16#include "TableManager.h"
18
19using namespace llvm::support::endian;
20
21namespace llvm {
22namespace jitlink {
23namespace systemz {
24
25/// Represents systemz fixups and other systemz-specific edge kinds.
26enum EdgeKind_systemz : Edge::Kind {
27
28 /// A plain 64-bit pointer value relocation.
29 ///
30 /// Fixup expression:
31 /// Fixup <- Target + Addend : uint64
32 ///
33 Pointer64 = Edge::FirstRelocation,
34
35 /// A plain 32-bit pointer value relocation.
36 ///
37 /// Fixup expression:
38 /// Fixup <- Target + Addend : uint32
39 ///
40 /// Errors:
41 /// - The target must reside in the low 32-bits of the address space,
42 /// otherwise an out-of-range error will be returned.
43 ///
45
46 /// A plain 20-bit pointer value relocation.
47 ///
48 /// Fixup expression:
49 /// Fixup <- Target + Addend : uint20
50 ///
51 /// Errors:
52 /// - The target must reside in the low 20-bits of the address space,
53 /// otherwise an out-of-range error will be returned.
54 ///
56
57 /// A plain 16-bit pointer value relocation.
58 ///
59 /// Fixup expression:
60 /// Fixup <- Target + Addend : uint16
61 ///
62 /// Errors:
63 /// - The target must reside in the low 16-bits of the address space,
64 /// otherwise an out-of-range error will be returned.
65 ///
67
68 /// A plain 12-bit pointer value relocation.
69 ///
70 /// Fixup expression:
71 /// Fixup <- Target + Addend : uint12
72 ///
73 /// Errors:
74 /// - The target must reside in the low 12-bits of the address space,
75 /// otherwise an out-of-range error will be returned.
76 ///
78
79 /// A plain 8-bit pointer value relocation.
80 ///
81 /// Fixup expression:
82 /// Fixup <- Target + Addend : uint8
83 ///
84 /// Errors:
85 /// - The target must reside in the low 8-bits of the address space,
86 /// otherwise an out-of-range error will be returned.
87 ///
89
90 /// A 64-bit delta.
91 ///
92 /// Delta from the fixup to the target.
93 ///
94 /// Fixup expression:
95 /// Fixup <- Target - Fixup + Addend : int64
96 ///
98
99 /// A 32-bit delta.
100 ///
101 /// Delta from the fixup to the target.
102 ///
103 /// Fixup expression:
104 /// Fixup <- Target - Fixup + Addend : int32
105 ///
106 /// Errors:
107 /// - The result of the fixup expression must fit into an int32, otherwise
108 /// an out-of-range error will be returned.
109 ///
111
112 /// A 16-bit delta.
113 ///
114 /// Delta from the fixup to the target.
115 ///
116 /// Fixup expression:
117 /// Fixup <- Target - Fixup + Addend : int16
118 ///
119 /// Errors:
120 /// - The result of the fixup expression must fit into an int16, otherwise
121 /// an out-of-range error will be returned.
122 ///
124
125 /// A 32-bit delta shifted by 1.
126 ///
127 /// Delta from the fixup to the target.
128 ///
129 /// Fixup expression:
130 /// Fixup <- (Target - Fixup + Addend) >> 1 : int32
131 ///
132 /// Errors:
133 /// - The result of the fixup expression before shifting right by 1 must
134 /// fit into an int33, otherwise an out-of-range error will be returned.
135 /// - The result of the fixup expression before shifting right by 1 must
136 /// be multiple of 2, otherwise an alignment error will be returned.
137 ///
139
140 /// A 24-bit delta shifted by 1.
141 ///
142 /// Delta from the fixup to the target.
143 ///
144 /// Fixup expression:
145 /// Fixup <- (Target - Fixup + Addend) >> 1 : int24
146 ///
147 /// Errors:
148 /// - The result of the fixup expression before shifting right by 1 must
149 /// fit into an int25, otherwise an out-of-range error will be returned.
150 /// - The result of the fixup expression before shifting right by 1 must
151 /// be multiple of 2, otherwise an alignment error will be returned.
152 ///
154
155 /// A 16-bit delta shifted by 1.
156 ///
157 /// Delta from the fixup to the target.
158 ///
159 /// Fixup expression:
160 /// Fixup <- (Target - Fixup + Addend) >> 1 : int16
161 ///
162 /// Errors:
163 /// - The result of the fixup expression before shifting right by 1 must
164 /// fit into an int17, otherwise an out-of-range error will be returned.
165 /// - The result of the fixup expression before shifting right by 1 must
166 /// be multiple of 2, otherwise an alignment error will be returned.
167 ///
169
170 /// A 12-bit delta shifted by 1.
171 ///
172 /// Delta from the fixup to the target.
173 ///
174 /// Fixup expression:
175 /// Fixup <- (Target - Fixup + Addend) >> 1 : int12
176 ///
177 /// Errors:
178 /// - The result of the fixup expression before shifting right by 1 must
179 /// fit into an int13, otherwise an out-of-range error will be returned.
180 /// - The result of the fixup expression before shifting right by 1 must
181 /// be multiple of 2, otherwise an alignment error will be returned.
182 ///
184
185 /// A 64-bit negative delta.
186 ///
187 /// Delta from target back to the fixup.
188 ///
189 /// Fixup expression:
190 /// Fixup <- Fixup - Target + Addend : int64
191 ///
193
194 /// A 32-bit negative delta.
195 ///
196 /// Delta from the target back to the fixup.
197 ///
198 /// Fixup expression:
199 /// Fixup <- Fixup - Target + Addend : int32
200 ///
201 /// Errors:
202 /// - The result of the fixup expression must fit into an int32, otherwise
203 /// an out-of-range error will be returned.
205
206 /// A 32-bit Delta shifted by 1.
207 ///
208 /// Delta from the fixup to the PLT slot for the target. This will lead to
209 /// creation of a PLT stub.
210 ///
211 /// Fixup expression:
212 /// Fixup <- (Target - Fixup + Addend) >> 1 : int32
213 ///
214 /// Errors:
215 /// - The result of the fixup expression before shifting right by 1 must
216 /// fit into an int33, otherwise an out-of-range error will be returned.
217 /// - The result of the fixup expression before shifting right by 1 must
218 /// be multiple of 2, otherwise an alignment error will be returned.
219 ///
221
222 /// A 24-bit Delta shifted by 1.
223 ///
224 /// Delta from the fixup to the PLT slot for the target. This will lead to
225 /// creation of a PLT stub.
226 ///
227 /// Fixup expression:
228 /// Fixup <- (Target - Fixup + Addend) >> 1 : int24
229 ///
230 /// Errors:
231 /// - The result of the fixup expression before shifting right by 1 must
232 /// fit into an int25, otherwise an out-of-range error will be returned.
233 /// - The result of the fixup expression before shifting right by 1 must
234 /// be multiple of 2, otherwise an alignment error will be returned.
235 ///
237
238 /// A 16-bit Delta shifted by 1.
239 ///
240 /// Delta from the fixup to the PLT slot for the target. This will lead to
241 /// creation of a PLT stub.
242 ///
243 /// Fixup expression:
244 /// Fixup <- (Target - Fixup + Addend) >> 1 : int16
245 ///
246 /// Errors:
247 /// - The result of the fixup expression before shifting right by 1 must
248 /// fit into an int17, otherwise an out-of-range error will be returned.
249 /// - The result of the fixup expression before shifting right by 1 must
250 /// be multiple of 2, otherwise an alignment error will be returned.
251 ///
253
254 /// A 12-bit Delta shifted by 1.
255 ///
256 /// Delta from the fixup to the PLT slot for the target. This will lead to
257 /// creation of a PLT stub.
258 ///
259 /// Fixup expression:
260 /// Fixup <- (Target - Fixup + Addend) >> 1 : int12
261 ///
262 /// Errors:
263 /// - The result of the fixup expression before shifting right by 1 must
264 /// fit into an int13, otherwise an out-of-range error will be returned.
265 /// - The result of the fixup expression before shifting right by 1 must
266 /// be multiple of 2, otherwise an alignment error will be returned.
267 ///
269
270 /// A 64-bit Delta.
271 ///
272 /// Delta from the fixup to the PLT slot for the target. This will lead to
273 /// creation of a PLT stub.
274 ///
275 /// Fixup expression:
276 /// Fixup <- Target - Fixup + Addend : int64
277 ///
279
280 /// A 32-bit Delta.
281 ///
282 /// Delta from the fixup to the PLT slot for the target. This will lead to
283 /// creation of a PLT stub.
284 ///
285 /// Fixup expression:
286 /// Fixup <- Target - Fixup + Addend : int32
287 ///
288 /// Errors:
289 /// - The result of the fixup expression must fit into an int32, otherwise
290 /// an out-of-range error will be returned.
291 ///
293
294 /// A 64-bit offset from GOT to PLT.
295 ///
296 /// Fixup expression:
297 /// Fixup <- Target - GOTBase + Addend : int64
298 ///
299 /// Errors:
300 /// - *ASSERTION* Failure to a null pointer GOTSymbol, which the GOT section
301 /// symbol was not been defined.
302 ///
304
305 /// A 32-bit offset from GOT to PLT.
306 ///
307 /// Fixup expression:
308 /// Fixup <- Target - GOTBase + Addend : int32
309 ///
310 /// Errors:
311 /// - *ASSERTION* Failure to a null pointer GOTSymbol, which the GOT section
312 /// symbol was not been defined.
313 /// - The result of the fixup expression must fit into an int32, otherwise
314 /// an out-of-range error will be returned.
315 ///
317
318 /// A 16-bit offset from GOT to PLT.
319 ///
320 /// Fixup expression:
321 /// Fixup <- Target - GOTBase + Addend : int16
322 ///
323 /// Errors:
324 /// - *ASSERTION* Failure to a null pointer GOTSymbol, which the GOT section
325 /// symbol was not been defined.
326 /// - The result of the fixup expression must fit into an int16, otherwise
327 /// an out-of-range error will be returned.
328 ///
330
331 /// A 64-bit offset from GOT.
332 ///
333 /// Fixup expression:
334 /// Fixup <- Target - GOTBase + Addend : int64
335 ///
336 /// Errors:
337 /// - *ASSERTION* Failure to a null pointer GOTSymbol, which the GOT section
338 /// symbol was not been defined.
339 ///
341
342 /// A 32-bit offset from GOT.
343 ///
344 /// Fixup expression:
345 /// Fixup <- Target - GOTBase + Addend : int32
346 ///
347 /// Errors:
348 /// - *ASSERTION* Failure to a null pointer GOTSymbol, which the GOT section
349 /// symbol was not been defined.
350 /// - The result of the fixup expression must fit into an int32, otherwise
351 /// an out-of-range error will be returned.
352 ///
354
355 /// A 16-bit offset from GOT.
356 ///
357 /// Fixup expression:
358 /// Fixup <- Target - GOTBase + Addend : int16
359 ///
360 /// Errors:
361 /// - *ASSERTION* Failure to a null pointer GOTSymbol, which the GOT section
362 /// symbol was not been defined.
363 /// - The result of the fixup expression must fit into an int16, otherwise
364 /// an out-of-range error will be returned.
365 ///
367
368 /// A 20-bit offset from GOT.
369 ///
370 /// Fixup expression:
371 /// Fixup <- Target - GOTBase + Addend : int20
372 ///
373 /// Errors:
374 /// - *ASSERTION* Failure to a null pointer GOTSymbol, which the GOT section
375 /// symbol was not been defined.
376 /// - The result of the fixup expression must fit into an int16, otherwise
377 /// an out-of-range error will be returned.
378 ///
380
381 /// A 12-bit offset from GOT.
382 ///
383 /// Fixup expression:
384 /// Fixup <- Target - GOTBase + Addend : int12
385 ///
386 /// Errors:
387 /// - *ASSERTION* Failure to a null pointer GOTSymbol, which the GOT section
388 /// symbol was not been defined.
389 /// - The result of the fixup expression must fit into an int16, otherwise
390 /// an out-of-range error will be returned.
391 ///
393
394 /// A GOT entry getter/constructor, transformed to Delta64FromGOT pointing
395 /// at the GOT entry for the original target.
396 ///
397 /// Indicates that this edge should be transformed into a Delta64FromGOT
398 /// targeting the GOT entry for the edge's current target, maintaining the
399 /// same addend. A GOT entry for the target should be created if one does
400 /// not already exist.
401 ///
402 /// Edges of this kind are usually handled by a GOT builder pass inserted by
403 /// default.
404 ///
405 /// Fixup expression:
406 /// NONE
407 ///
408 /// Errors:
409 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
410 ///
412
413 /// A GOT entry getter/constructor, transformed to Delta32FromGOT pointing
414 /// at the GOT entry for the original target.
415 ///
416 /// Indicates that this edge should be transformed into a Delta32FromGOT
417 /// targeting the GOT entry for the edge's current target, maintaining the
418 /// same addend. A GOT entry for the target should be created if one does
419 /// not already exist.
420 ///
421 /// Edges of this kind are usually handled by a GOT builder pass inserted by
422 /// default.
423 ///
424 /// Fixup expression:
425 /// NONE
426 ///
427 /// Errors:
428 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
429 ///
431
432 /// A GOT entry getter/constructor, transformed to Delta20FromGOT pointing
433 /// at the GOT entry for the original target.
434 ///
435 /// Indicates that this edge should be transformed into a Delta20FromGOT
436 /// targeting the GOT entry for the edge's current target, maintaining the
437 /// same addend. A GOT entry for the target should be created if one does
438 /// not already exist.
439 ///
440 /// Edges of this kind are usually handled by a GOT builder pass inserted by
441 /// default.
442 ///
443 /// Fixup expression:
444 /// NONE
445 ///
446 /// Errors:
447 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
448 ///
450
451 /// A GOT entry getter/constructor, transformed to Delta16FromGOT pointing
452 /// at the GOT entry for the original target.
453 ///
454 /// Indicates that this edge should be transformed into a Delta16FromGOT
455 /// targeting the GOT entry for the edge's current target, maintaining the
456 /// same addend. A GOT entry for the target should be created if one does
457 /// not already exist.
458 ///
459 /// Edges of this kind are usually handled by a GOT builder pass inserted by
460 /// default.
461 ///
462 /// Fixup expression:
463 /// NONE
464 ///
465 /// Errors:
466 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
467 ///
469
470 /// A GOT entry getter/constructor, transformed to Delta12FromGOT pointing
471 /// at the GOT entry for the original target.
472 ///
473 /// Indicates that this edge should be transformed into a Delta12FromGOT
474 /// targeting the GOT entry for the edge's current target, maintaining the
475 /// same addend. A GOT entry for the target should be created if one does
476 /// not already exist.
477 ///
478 /// Edges of this kind are usually handled by a GOT builder pass inserted by
479 /// default.
480 ///
481 /// Fixup expression:
482 /// NONE
483 ///
484 /// Errors:
485 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
486 /// phase will result in an assert/unreachable during the fixup phase.
487 ///
489
490 /// A GOT entry getter/constructor, transformed to Delta32dbl pointing at
491 /// the GOT entry for the original target.
492 ///
493 /// Indicates that this edge should be transformed into a Delta32dbl targeting
494 /// the GOT entry for the edge's current target, maintaining the same addend.
495 /// A GOT entry for the target should be created if one does not already
496 /// exist.
497 ///
498 /// Edges of this kind are usually handled by a GOT builder pass inserted by
499 /// default.
500 ///
501 /// Fixup expression:
502 /// NONE
503 ///
504 /// Errors:
505 /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup
506 /// phase will result in an assert/unreachable during the fixup phase.
507 ///
509
510 /// A 32-bit Delta to GOT base.
511 ///
512 /// Fixup expression:
513 /// Fixup <- GOTBase - Fixup + Addend : int32
514 ///
515 /// Errors:
516 /// - *ASSERTION* Failure to a null pointer GOTSymbol, which the GOT section
517 /// symbol was not been defined.
518 /// - The result of the fixup expression must fit into an int32, otherwise
519 /// an out-of-range error will be returned.
520 ///
522
523 /// A 32-bit Delta to GOT base shifted by 1.
524 ///
525 /// Fixup expression:
526 /// Fixup <- (GOTBase - Fixup + Addend) >> 1 : int32
527 ///
528 /// Errors:
529 /// - *ASSERTION* Failure to a null pointer GOTSymbol, which the GOT section
530 /// symbol was not been defined.
531 /// - The result of the fixup expression before shifting right by 1 must
532 /// fit into an int33, otherwise an out-of-range error will be returned.
533 /// - The result of the fixup expression before shifting right by 1 must
534 /// be multiple of 2, otherwise an alignment error will be returned.
535 ///
537
538};
539
540/// Returns a string name for the given systemz edge. For debugging purposes
541/// only
542const char *getEdgeKindName(Edge::Kind K);
543
544/// Apply fixup expression for edge to block content.
545inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
546 const Symbol *GOTSymbol) {
547 using namespace support;
548
549 char *BlockWorkingMem = B.getAlreadyMutableContent().data();
550 char *FixupPtr = BlockWorkingMem + E.getOffset();
551 orc::ExecutorAddr FixupAddress = B.getAddress() + E.getOffset();
552 int64_t S = E.getTarget().getAddress().getValue();
553 int64_t A = E.getAddend();
554 int64_t P = FixupAddress.getValue();
555 int64_t GOTBase = GOTSymbol ? GOTSymbol->getAddress().getValue() : 0;
556 Edge::Kind K = E.getKind();
557
558 DEBUG_WITH_TYPE("jitlink", {
559 dbgs() << " Applying fixup on " << G.getEdgeKindName(K)
560 << " edge, (S, A, P, .GOT.) = (" << formatv("{0:x}", S) << ", "
561 << formatv("{0:x}", A) << ", " << formatv("{0:x}", P) << ", "
562 << formatv("{0:x}", GOTBase) << ")\n";
563 });
564
565 const auto isAlignmentCorrect = [](uint64_t Value, int N) {
566 return (Value & (N - 1)) ? false : true;
567 };
568
569 switch (K) {
570 case Pointer64: {
571 uint64_t Value = S + A;
572 write64be(FixupPtr, Value);
573 break;
574 }
575 case Pointer32: {
576 uint64_t Value = S + A;
578 return makeTargetOutOfRangeError(G, B, E);
579 write32be(FixupPtr, Value);
580 break;
581 }
582 case Pointer20: {
583 uint64_t Value = S + A;
585 return makeTargetOutOfRangeError(G, B, E);
586 write32be(FixupPtr, (read32be(FixupPtr) & 0xF00000FF) |
587 ((Value & 0xFFF) << 16) | ((Value & 0xFF000) >> 4));
588 break;
589 }
590 case Pointer16: {
591 uint64_t Value = S + A;
593 return makeTargetOutOfRangeError(G, B, E);
594 write16be(FixupPtr, Value);
595 break;
596 }
597 case Pointer12: {
598 uint64_t Value = S + A;
600 return makeTargetOutOfRangeError(G, B, E);
601 write16be(FixupPtr, (read16be(FixupPtr) & 0xF000) | Value);
602 break;
603 }
604 case Pointer8: {
605 uint64_t Value = S + A;
607 return makeTargetOutOfRangeError(G, B, E);
608 *(uint8_t *)FixupPtr = Value;
609 break;
610 }
611 case Delta64:
612 case DeltaPLT64: {
613 int64_t Value = S + A - P;
614 write64be(FixupPtr, Value);
615 break;
616 }
617 case Delta32:
618 case DeltaPLT32: {
619 int64_t Value = S + A - P;
621 return makeTargetOutOfRangeError(G, B, E);
622 write32be(FixupPtr, Value);
623 break;
624 }
625 case Delta16: {
626 int64_t Value = S + A - P;
628 return makeTargetOutOfRangeError(G, B, E);
629 write16be(FixupPtr, Value);
630 break;
631 }
632 case NegDelta32: {
633 int64_t Value = P + A - S;
635 return makeTargetOutOfRangeError(G, B, E);
636 write32be(FixupPtr, Value);
637 break;
638 }
639 case Delta32dbl:
640 case DeltaPLT32dbl: {
641 int64_t Value = S + A - P;
643 return makeTargetOutOfRangeError(G, B, E);
645 return makeAlignmentError(FixupAddress, Value, 2, E);
646 write32be(FixupPtr, Value >> 1);
647 break;
648 }
649 case Delta24dbl:
650 case DeltaPLT24dbl: {
651 int64_t Value = S + A - P;
653 return makeTargetOutOfRangeError(G, B, E);
655 return makeAlignmentError(FixupAddress, Value, 2, E);
656 FixupPtr[0] = Value >> 17;
657 FixupPtr[1] = Value >> 9;
658 FixupPtr[2] = Value >> 1;
659 break;
660 }
661 case Delta16dbl:
662 case DeltaPLT16dbl: {
663 int64_t Value = S + A - P;
665 return makeTargetOutOfRangeError(G, B, E);
667 return makeAlignmentError(FixupAddress, Value, 2, E);
668 write16be(FixupPtr, Value >> 1);
669 break;
670 }
671 case Delta12dbl:
672 case DeltaPLT12dbl: {
673 int64_t Value = S + A - P;
675 return makeTargetOutOfRangeError(G, B, E);
677 return makeAlignmentError(FixupAddress, Value, 2, E);
678 write16be(FixupPtr,
679 (read16be(FixupPtr) & 0xF000) | ((Value >> 1) & 0x0FFF));
680 break;
681 }
682 case Delta32GOTBase: {
683 assert(GOTSymbol && "No GOT section symbol");
684 int64_t Value = GOTBase + A - P;
686 return makeTargetOutOfRangeError(G, B, E);
687 write32be(FixupPtr, Value);
688 break;
689 }
690 case Delta32dblGOTBase: {
691 assert(GOTSymbol && "No GOT section symbol");
692 int64_t Value = GOTBase + A - P;
694 return makeTargetOutOfRangeError(G, B, E);
696 return makeAlignmentError(FixupAddress, Value, 2, E);
697 write32be(FixupPtr, Value >> 1);
698 break;
699 }
701 case Delta64FromGOT: {
702 assert(GOTSymbol && "No GOT section symbol");
703 int64_t Value = S + A - GOTBase;
704 write64be(FixupPtr, Value);
705 break;
706 }
708 case Delta32FromGOT: {
709 assert(GOTSymbol && "No GOT section symbol");
710 int64_t Value = S + A - GOTBase;
712 return makeTargetOutOfRangeError(G, B, E);
713 write32be(FixupPtr, Value);
714 break;
715 }
717 case Delta16FromGOT: {
718 assert(GOTSymbol && "No GOT section symbol");
719 int64_t Value = S + A - GOTBase;
721 return makeTargetOutOfRangeError(G, B, E);
722 write16be(FixupPtr, Value);
723 break;
724 }
725 case Delta20FromGOT: {
726 assert(GOTSymbol && "No GOT section symbol");
727 uint64_t Value = S - GOTBase + A;
729 return makeTargetOutOfRangeError(G, B, E);
730 write32be(FixupPtr, (read32be(FixupPtr) & 0xF00000FF) |
731 ((Value & 0xFFF) << 16) | ((Value & 0xFF000) >> 4));
732 break;
733 }
734 case Delta12FromGOT: {
735 assert(GOTSymbol && "No GOT section symbol");
736 uint64_t Value = S - GOTBase + A;
738 return makeTargetOutOfRangeError(G, B, E);
739 write16be(FixupPtr, (read16be(FixupPtr) & 0xF000) | Value);
740 break;
741 }
742 default:
744 "In graph " + G.getName() + ", section " + B.getSection().getName() +
745 " unsupported edge kind " + getEdgeKindName(E.getKind()));
746 }
747
748 return Error::success();
749}
750
751/// SystemZ null pointer content.
752extern const char NullPointerContent[8];
754 return {reinterpret_cast<const char *>(NullPointerContent),
755 G.getPointerSize()};
756}
757
758/// SystemZ pointer jump stub content.
759///
760/// Contains the instruction sequence for an indirect jump via an in-memory
761/// pointer:
762/// lgrl %r1, ptr
763/// j %r1
764constexpr size_t StubEntrySize = 8;
765extern const char Pointer64JumpStubContent[StubEntrySize];
767 auto StubContent = Pointer64JumpStubContent;
768 return {reinterpret_cast<const char *>(StubContent), StubEntrySize};
769}
770
771/// Creates a new pointer block in the given section and returns an
772/// Anonymous symbol pointing to it.
773///
774/// If InitialTarget is given then an Pointer64 relocation will be added to the
775/// block pointing at InitialTarget.
777 Symbol *InitialTarget = nullptr,
778 uint64_t InitialAddend = 0) {
779 auto &B = G.createContentBlock(PointerSection, getGOTEntryBlockContent(G),
780 orc::ExecutorAddr(), G.getPointerSize(), 0);
781 if (InitialTarget)
782 B.addEdge(Pointer64, 0, *InitialTarget, InitialAddend);
783 return G.addAnonymousSymbol(B, 0, G.getPointerSize(), false, false);
784}
785
786/// Create a jump stub block that jumps via the pointer at the given symbol.
787///
788/// The stub block will have the following default values:
789/// alignment: 16-bit
790/// alignment-offset: 0
792 Symbol &PointerSymbol) {
793 auto &B = G.createContentBlock(StubSection, getStubBlockContent(G),
794 orc::ExecutorAddr(), 16, 0);
795 B.addEdge(Delta32dbl, 2, PointerSymbol, 2);
796 return B;
797}
798
799/// Create a jump stub that jumps via the pointer at the given symbol and
800/// an anonymous symbol pointing to it. Return the anonymous symbol.
801///
802/// The stub block will be created by createPointerJumpStubBlock.
804 Section &StubSection,
805 Symbol &PointerSymbol) {
806 return G.addAnonymousSymbol(
807 createPointerJumpStubBlock(G, StubSection, PointerSymbol), 0,
808 StubEntrySize, true, false);
809}
810
811/// Global Offset Table Builder.
812class GOTTableManager : public TableManager<GOTTableManager> {
813public:
814 static StringRef getSectionName() { return "$__GOT"; }
815
817 if (E.getTarget().isDefined())
818 return false;
819 Edge::Kind KindToSet = Edge::Invalid;
820 switch (E.getKind()) {
822 KindToSet = systemz::Delta12FromGOT;
823 break;
825 KindToSet = systemz::Delta16FromGOT;
826 break;
828 KindToSet = systemz::Delta20FromGOT;
829 break;
831 KindToSet = systemz::Delta32FromGOT;
832 break;
834 KindToSet = systemz::Delta64FromGOT;
835 break;
837 KindToSet = systemz::DeltaPLT32dbl;
838 break;
839 default:
840 return false;
841 }
842 assert(KindToSet != Edge::Invalid &&
843 "Fell through switch, but no new kind to set");
844 DEBUG_WITH_TYPE("jitlink", {
845 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
846 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "
847 << formatv("{0:x}", E.getOffset()) << ")\n";
848 });
849 E.setKind(KindToSet);
850 E.setTarget(getEntryForTarget(G, E.getTarget()));
851 return true;
852 }
853
855 return createAnonymousPointer(G, getGOTSection(G), &Target);
856 }
857
858private:
859 Section &getGOTSection(LinkGraph &G) {
860 if (!GOTSection)
861 GOTSection = &G.createSection(getSectionName(),
863 return *GOTSection;
864 }
865
866 Section *GOTSection = nullptr;
867};
868
869/// Procedure Linkage Table Builder.
870class PLTTableManager : public TableManager<PLTTableManager> {
871public:
873
874 static StringRef getSectionName() { return "$__STUBS"; }
875
877 if (E.getTarget().isDefined())
878 return false;
879
880 switch (E.getKind()) {
890 break;
891 default:
892 return false;
893 }
894 DEBUG_WITH_TYPE("jitlink", {
895 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
896 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "
897 << formatv("{0:x}", E.getOffset()) << ")\n";
898 });
899 E.setTarget(getEntryForTarget(G, E.getTarget()));
900 return true;
901 }
902
905 GOT.getEntryForTarget(G, Target));
906 }
907
908public:
915
918};
919
920} // namespace systemz
921} // namespace jitlink
922} // namespace llvm
923
924#endif // LLVM_EXECUTIONENGINE_JITLINK_SYSTEMZ_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_UNLIKELY(EXPR)
Definition Compiler.h:336
#define G(x, y, z)
Definition MD5.cpp:55
#define P(N)
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition Debug.h:72
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Target - Wrapper for Target specific information.
LLVM Value Representation.
Definition Value.h:75
Represents an address in the executor process.
uint64_t getValue() const
void write16be(void *P, uint16_t V)
Definition Endian.h:481
void write32be(void *P, uint32_t V)
Definition Endian.h:484
uint32_t read32be(const void *P)
Definition Endian.h:441
void write64be(void *P, uint64_t V)
Definition Endian.h:487
uint16_t read16be(const void *P)
Definition Endian.h:438
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.
Definition MathExtras.h:165
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.
Definition Debug.cpp:207
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:189
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
#define N