13#ifndef LLVM_EXECUTIONENGINE_JITLINK_PPC64_H
14#define LLVM_EXECUTIONENGINE_JITLINK_PPC64_H
94template <llvm::endianness Endianness>
103 size_t Offset = isLE ? 0 : 2;
112 size_t Offset = isLE ? 4 : 6;
121 size_t Offset = isLE ? 16 : 18;
122 Edge::AddendT Addend = isLE ? 8 : 10;
133 Symbol *InitialTarget =
nullptr,
136 "LinkGraph's pointer size should be consistent with size of "
137 "NullPointerContent");
141 B.addEdge(
Pointer64, 0, *InitialTarget, InitialAddend);
142 return G.addAnonymousSymbol(
B, 0,
G.getPointerSize(),
false,
false);
145template <llvm::endianness Endianness>
153 for (
auto const &Reloc : StubInfo.
Relocs)
154 B.addEdge(Reloc.K, Reloc.Offset, PointerSymbol, Reloc.A);
155 return G.addAnonymousSymbol(
B, 0, StubInfo.
Content.
size(),
true,
false);
158template <llvm::endianness Endianness>
165 Edge::Kind K =
E.getKind();
174 getOrCreateTOCSection(
G);
200template <llvm::endianness Endianness>
212 bool isExternal =
E.getTarget().isExternal();
213 Edge::Kind K =
E.getKind();
242 return createAnonymousPointerJumpStub<Endianness>(
243 G, getOrCreateStubsSection(
G), TOC.getEntryForTarget(
G,
Target),
256 TOCTableManager<Endianness> &TOC;
270 return ((x + 0x8000) >> 16) & 0xffff;
274 return ((x + 0x8000) >> 32) & 0xffff;
285template <llvm::endianness Endianness>
288 uint64_t Inst = support::endian::read64<Endianness>(Loc);
289 return isLE ? (Inst << 32) | (Inst >> 32) : Inst;
292template <llvm::endianness Endianness>
295 Inst = isLE ? (Inst << 32) | (Inst >> 32) : Inst;
296 support::endian::write64<Endianness>(Loc, Inst);
299template <llvm::endianness Endianness>
305 support::endian::write16<Endianness>(FixupPtr,
Value);
309 support::endian::write16<Endianness>(FixupPtr,
Value & ~3);
314 support::endian::write16<Endianness>(FixupPtr,
ha(
Value));
319 support::endian::write16<Endianness>(FixupPtr,
hi(
Value));
322 support::endian::write16<Endianness>(FixupPtr,
high(
Value));
325 support::endian::write16<Endianness>(FixupPtr,
higha(
Value));
328 support::endian::write16<Endianness>(FixupPtr,
higher(
Value));
331 support::endian::write16<Endianness>(FixupPtr,
highera(
Value));
334 support::endian::write16<Endianness>(FixupPtr,
highest(
Value));
337 support::endian::write16<Endianness>(FixupPtr,
highesta(
Value));
342 support::endian::write16<Endianness>(FixupPtr,
lo(
Value));
346 support::endian::write16<Endianness>(FixupPtr,
lo(
Value) & ~3);
349 return make_error<JITLinkError>(
351 " relocation does not write at half16 field");
357template <llvm::endianness Endianness>
359 const Symbol *TOCSymbol) {
360 char *BlockWorkingMem =
B.getAlreadyMutableContent().data();
361 char *FixupPtr = BlockWorkingMem +
E.getOffset();
363 int64_t S =
E.getTarget().getAddress().getValue();
364 int64_t
A =
E.getAddend();
367 Edge::Kind K =
E.getKind();
370 dbgs() <<
" Applying fixup on " <<
G.getEdgeKindName(K)
371 <<
" edge, (S, A, P, .TOC.) = (" <<
formatv(
"{0:x}", S) <<
", "
373 <<
formatv(
"{0:x}", TOCBase) <<
")\n";
379 support::endian::write64<Endianness>(FixupPtr,
Value);
390 return relocateHalf16<Endianness>(FixupPtr,
Value, K);
393 support::endian::write64<Endianness>(FixupPtr, TOCBase);
411 return relocateHalf16<Endianness>(FixupPtr,
Value, K);
414 static const uint32_t Low14Mask = 0xfffc;
416 assert((
Value & 3) == 0 &&
"Pointer14 requires 4-byte alignment");
420 uint32_t Inst = support::endian::read32<Endianness>(FixupPtr);
421 support::endian::write32<Endianness>(FixupPtr, (Inst & ~Low14Mask) |
422 (
Value & Low14Mask));
431 int64_t
Value = S +
A - TOCBase;
435 return relocateHalf16<Endianness>(FixupPtr,
Value, K);
443 uint32_t Inst = support::endian::read32<Endianness>(FixupPtr);
444 support::endian::write32<Endianness>(FixupPtr, (Inst & 0xfc000003) |
445 (
Value & 0x03fffffc));
447 uint32_t NopInst = support::endian::read32<Endianness>(FixupPtr + 4);
448 assert(NopInst == 0x60000000 &&
449 "NOP should be placed here for restoring r2");
452 support::endian::write32<Endianness>(FixupPtr + 4, 0xe8410018);
458 support::endian::write64<Endianness>(FixupPtr,
Value);
465 static const uint64_t SI0Mask = 0x00000003ffff0000;
466 static const uint64_t SI1Mask = 0x000000000000ffff;
467 static const uint64_t FullMask = 0x0003ffff0000ffff;
468 uint64_t Inst = readPrefixedInstruction<Endianness>(FixupPtr) & ~FullMask;
469 writePrefixedInstruction<Endianness>(
470 FixupPtr, Inst | ((
Value & SI0Mask) << 16) | (
Value & SI1Mask));
478 support::endian::write32<Endianness>(FixupPtr,
Value);
486 support::endian::write32<Endianness>(FixupPtr,
Value);
490 return make_error<JITLinkError>(
491 "In graph " +
G.getName() +
", section " +
B.getSection().getName() +
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Target - Wrapper for Target specific information.
LLVM Value Representation.
An Addressable with content and edges.
Represents fixups and constraints in the LinkGraph.
Represents an object file section.
orc::ExecutorAddr getAddress() const
Returns the address of this symbol.
A CRTP base for tables that are built on demand, e.g.
Symbol & getEntryForTarget(LinkGraph &G, Symbol &Target)
Return the constructed entry.
static StringRef getSectionName()
bool visitEdge(LinkGraph &G, Block *B, Edge &E)
Symbol & createEntry(LinkGraph &G, Symbol &Target)
PLTTableManager(TOCTableManager< Endianness > &TOC)
static StringRef getSectionName()
bool visitEdge(LinkGraph &G, Block *B, Edge &E)
Symbol & createEntry(LinkGraph &G, Symbol &Target)
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.
static uint64_t lo(uint64_t x)
static uint64_t high(uint64_t x)
Error relocateHalf16(char *FixupPtr, int64_t Value, Edge::Kind K)
LLVM_ABI const char PointerJumpStubNoTOCContent_big[32]
static uint64_t higha(uint64_t x)
PLTCallStubInfo pickStub(PLTCallStubKind StubKind)
Symbol & createAnonymousPointer(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget=nullptr, uint64_t InitialAddend=0)
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const Symbol *TOCSymbol)
Apply fixup expression for edge to block content.
static uint16_t highesta(uint64_t x)
EdgeKind_ppc64
Represents ppc64 fixups and other ppc64-specific edge kinds.
@ RequestTLSDescInGOTAndTransformToTOCDelta16HA
@ CallBranchDeltaRestoreTOC
@ RequestGOTAndTransformToDelta34
@ RequestTLSDescInGOTAndTransformToTOCDelta16LO
@ RequestTLSDescInGOTAndTransformToDelta34
LLVM_ABI const char PointerJumpStubContent_little[20]
LLVM_ABI const char PointerJumpStubContent_big[20]
static uint64_t higher(uint64_t x)
LLVM_ABI const char NullPointerContent[8]
LLVM_ABI const char PointerJumpStubNoTOCContent_little[32]
static uint64_t readPrefixedInstruction(const char *Loc)
static void writePrefixedInstruction(char *Loc, uint64_t Inst)
Symbol & createAnonymousPointerJumpStub(LinkGraph &G, Section &StubSection, Symbol &PointerSymbol, PLTCallStubKind StubKind)
static uint16_t highest(uint64_t x)
static uint64_t highera(uint64_t x)
LLVM_ABI const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given ppc64 edge.
static uint16_t hi(uint64_t x)
static uint16_t ha(uint64_t x)
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.
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.
SmallVector< PLTCallStubReloc, 2 > Relocs