17#define DEBUG_TYPE "jitlink" 
   24                                    0x00, 0x00, 0x00, 0x00};
 
 
   27    0x10, 0x00, 0x00, (
char)0x90u, 
 
   28    0x10, 0x02, 0x40, (
char)0xf9u, 
 
   29    0x00, 0x02, 0x1f, (
char)0xd6u  
 
 
   33    (
char)0xfd, 0x7b, (
char)0xbf, (
char)0xa9, 
 
   34    0x00,       0x00, 0x00,       (
char)0x94  
 
 
   42    return "Pointer64Authenticated";
 
   54    return "Branch26PCRel";
 
   58    return "LDRLiteral19";
 
   60    return "TestAndBranch14PCRel";
 
   62    return "CondBranch19PCRel";
 
   64    return "ADRLiteral21";
 
   68    return "PageOffset12";
 
   70    return "GotPageOffset15";
 
   72    return "RequestGOTAndTransformToPage21";
 
   74    return "RequestGOTAndTransformToPageOffset12";
 
   76    return "RequestGOTAndTransformToPageOffset15";
 
   78    return "RequestGOTAndTransformToDelta32";
 
   80    return "RequestTLVPAndTransformToPage21";
 
   82    return "RequestTLVPAndTransformToPageOffset12";
 
   84    return "RequestTLSDescEntryAndTransformToPage21";
 
   86    return "RequestTLSDescEntryAndTransformToPageOffset12";
 
 
   93template <
typename AppendFtor>
 
   96  assert(DstReg < 32 && 
"Dst reg out of range");
 
   97  assert(SrcReg < 32 && 
"Src reg out of range");
 
  102  constexpr uint32_t MOVGPR64Template = 0xaa0003e0;
 
  104  constexpr uint32_t SrcRegIndex = 16;
 
  106  Instr |= DstReg << DstRegIndex;
 
  107  Instr |= SrcReg << SrcRegIndex;
 
  108  return Append(Instr);
 
 
  112template <
typename AppendFtor>
 
  115  assert(
Reg < 32 && 
"Invalid register number");
 
  117  constexpr uint32_t MovRegImm64Template = 0xd2800000;
 
  118  constexpr unsigned PreserveBitIndex = 29;
 
  119  constexpr unsigned ShiftBitsIndex = 21;
 
  120  constexpr unsigned ImmBitsIndex = 5;
 
  122  bool PreserveRegValue = 
false;
 
  123  for (
unsigned I = 0; 
I != 4; ++
I) {
 
  128    if (PreserveRegValue && !ImmBits)
 
  131    uint32_t Instr = MovRegImm64Template;
 
  132    Instr |= PreserveRegValue << PreserveBitIndex;
 
  133    Instr |= (
I << ShiftBitsIndex);
 
  134    Instr |= ImmBits << ImmBitsIndex;
 
  136    if (
auto Err = Append(Instr))
 
  138    PreserveRegValue = 
true;
 
 
  144template <
typename AppendFtor>
 
  147                unsigned RawAddrReg, 
unsigned DiscriminatorReg, 
unsigned Key,
 
  148                uint64_t EncodedDiscriminator, 
bool AddressDiversify) {
 
  149  assert(DstReg < 32 && 
"DstReg out of range");
 
  150  assert(RawAddrReg < 32 && 
"AddrReg out of range");
 
  151  assert(DiscriminatorReg < 32 && 
"DiscriminatorReg out of range");
 
  152  assert(EncodedDiscriminator < 0x10000 && 
"EncodedDiscriminator out of range");
 
  154  if (AddressDiversify) {
 
  159    if (EncodedDiscriminator) {
 
  160      constexpr uint32_t MOVKTemplate = 0xf2e00000;
 
  161      constexpr unsigned ImmIndex = 5;
 
  163      BlendInstr |= EncodedDiscriminator << ImmIndex;
 
  164      BlendInstr |= DiscriminatorReg;
 
  165      if (
auto Err = Append(BlendInstr))
 
  168  } 
else if (EncodedDiscriminator) {
 
  174    DiscriminatorReg = 31; 
 
  176  constexpr uint32_t PACTemplate = 0xdac10000;
 
  177  constexpr unsigned ZBitIndex = 13;
 
  178  constexpr unsigned KeyIndex = 10;
 
  179  constexpr unsigned DiscriminatorRegIndex = 5;
 
  182  Instr |= (DiscriminatorReg == 31) << ZBitIndex;
 
  183  Instr |= 
Key << KeyIndex;
 
  184  Instr |= DiscriminatorReg << DiscriminatorRegIndex;
 
  187  return Append(Instr);
 
 
  190template <
typename AppendFtor>
 
  193  assert(DstLocReg < 32 && 
"DstLocReg out of range");
 
  194  assert(SrcReg < 32 && 
"SrcReg out of range");
 
  196  constexpr uint32_t STRTemplate = 0xf9000000;
 
  197  constexpr unsigned DstLocRegIndex = 5;
 
  198  constexpr unsigned SrcRegIndex = 0;
 
  201  Instr |= DstLocReg << DstLocRegIndex;
 
  202  Instr |= SrcReg << SrcRegIndex;
 
  204  return Append(Instr);
 
 
  207void GOTTableManager::registerExistingEntries() {
 
  208  for (
auto *EntrySym : GOTSection->
symbols()) {
 
  209    assert(EntrySym->getBlock().edges_size() == 1 &&
 
  210           "GOT block edge count != 1");
 
  218    assert(EntrySym->getBlock().edges_size() == 2 &&
 
  219           "PLT block edge count != 2");
 
  220    auto &GOTSym = EntrySym->getBlock().edges().begin()->getTarget();
 
  221    assert(GOTSym.getBlock().edges_size() == 1 && 
"GOT block edge count != 1");
 
 
  235    dbgs() << 
"Creating empty pointer signing function for " << 
G.getName()
 
  242  size_t NumPtrAuthFixupLocations = 0;
 
  243  for (
auto &Sec : 
G.sections()) {
 
  251    for (
auto *
B : Sec.blocks()) {
 
  252      for (
auto &
E : 
B->edges())
 
  253        NumPtrAuthFixupLocations +=
 
  258  constexpr size_t MaxPtrSignSeqLength =
 
  267  size_t NumSigningInstrs = NumPtrAuthFixupLocations * MaxPtrSignSeqLength + 3;
 
  270  auto &SigningSection =
 
  275  size_t SigningFunctionSize = NumSigningInstrs * 4;
 
  276  auto &SigningFunctionBlock = 
G.createMutableContentBlock(
 
  277      SigningSection, 
G.allocateBuffer(SigningFunctionSize),
 
  279  G.addAnonymousSymbol(SigningFunctionBlock, 0, SigningFunctionBlock.getSize(),
 
  283    dbgs() << 
"  " << NumPtrAuthFixupLocations << 
" location(s) to sign, up to " 
  284           << NumSigningInstrs << 
" instructions required (" 
  285           << 
formatv(
"{0:x}", SigningFunctionBlock.getSize()) << 
" bytes)\n";
 
 
  299    dbgs() << 
"Writing pointer signing function for " << 
G.getName() << 
"\n";
 
  302  constexpr unsigned Reg1 = 8;  
 
  303  constexpr unsigned Reg2 = 9;  
 
  304  constexpr unsigned Reg3 = 10; 
 
  307  auto *SigningSection =
 
  309  assert(SigningSection && 
"Siging section missing");
 
  310  assert(SigningSection->blocks_size() == 1 &&
 
  311         "Unexpected number of blocks in signing section");
 
  312  assert(SigningSection->symbols_size() == 1 &&
 
  313         "Unexpected number of symbols in signing section");
 
  315  auto &SigningFunctionSym = **SigningSection->symbols().begin();
 
  316  auto &SigningFunctionBlock = SigningFunctionSym.getBlock();
 
  317  auto SigningFunctionBuf = SigningFunctionBlock.getAlreadyMutableContent();
 
  321      {
reinterpret_cast<uint8_t *
>(SigningFunctionBuf.data()),
 
  322       SigningFunctionBuf.size()},
 
  325  auto AppendInstr = [&](
uint32_t Instr) {
 
  329  for (
auto &Sec : 
G.sections()) {
 
  334    for (
auto *
B : Sec.blocks()) {
 
  335      for (
auto &
E : 
B->edges()) {
 
  341        int32_t RealAddend = (
uint32_t)(EncodedInfo & 0xffffffff);
 
  342        auto ValueToSign = 
E.getTarget().getAddress() + RealAddend;
 
  345          E.setAddend(RealAddend);
 
  350        uint32_t InitialDiscriminator = (EncodedInfo >> 32) & 0xffff;
 
  351        bool AddressDiversify = (EncodedInfo >> 48) & 0x1;
 
  353        uint32_t HighBits = EncodedInfo >> 51;
 
  355        if (HighBits != 0x1000)
 
  357              "Pointer64Auth edge at " +
 
  358              formatv(
"{0:x}", 
B->getFixupAddress(
E).getValue()) +
 
  359              " has invalid encoded addend  " + 
formatv(
"{0:x}", EncodedInfo));
 
  362          const char *
const KeyNames[] = {
"IA", 
"IB", 
"DA", 
"DB"};
 
  363          dbgs() << 
"  " << 
B->getFixupAddress(
E) << 
" <- " << ValueToSign
 
  364                 << 
" : key = " << KeyNames[
Key] << 
", discriminator = " 
  365                 << 
formatv(
"{0:x4}", InitialDiscriminator)
 
  366                 << 
", address diversified = " 
  367                 << (AddressDiversify ? 
"yes" : 
"no") << 
"\n";
 
  376                                     B->getFixupAddress(
E).getValue()));
 
  380                                 Key, InitialDiscriminator, AddressDiversify));
 
  386        E.setKind(Edge::KeepAlive);
 
  392  constexpr uint32_t RETInstr = 0xd65f03c0;
 
  399  G.allocActions().push_back(
 
  400      {
cantFail(WrapperFunctionCall::Create<SPSArgList<>>(
 
  401           SigningFunctionSym.getAddress())),
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
 
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
 
Provides write only access to a subclass of WritableBinaryStream.
 
Error writeInteger(T Value)
Write the integer Value to the underlying stream in the specified endianness.
 
Lightweight error class with error context and mandatory checking.
 
static ErrorSuccess success()
Create a success value.
 
iterator_range< symbol_iterator > symbols()
Returns an iterator over the symbols defined in this section.
 
bool registerPreExistingEntry(Symbol &Target, Symbol &Entry)
 
LLVM_ABI void registerExistingEntries()
 
Represents an address in the executor process.
 
LLVM_ABI const char NullPointerContent[PointerSize]
AArch64 null pointer content.
 
static Error writeMovRegImm64Seq(AppendFtor &Append, uint64_t Reg, uint64_t Imm)
 
LLVM_ABI const char ReentryTrampolineContent[8]
AArch64 reentry trampoline.
 
static Error writeMovRegRegSeq(AppendFtor &Append, uint64_t DstReg, uint64_t SrcReg)
 
LLVM_ABI const char PointerJumpStubContent[12]
 
LLVM_ABI Error createEmptyPointerSigningFunction(LinkGraph &G)
Creates a pointer signing function section, block, and symbol to reserve space for a signing function...
 
LLVM_ABI Error lowerPointer64AuthEdgesToSigningFunction(LinkGraph &G)
Given a LinkGraph containing Pointer64Authenticated edges, transform those edges to Pointer64 and add...
 
LLVM_ABI const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given aarch64 edge.
 
LLVM_ABI const char * getPointerSigningFunctionSectionName()
Returns the name of the pointer signing function section.
 
static Error writeStoreRegSeq(AppendFtor &Append, unsigned DstLocReg, unsigned SrcReg)
 
@ LDRLiteral19
The signed 21-bit delta from the fixup to the target.
 
@ Pointer64Authenticated
An arm64e authenticated pointer relocation.
 
@ RequestGOTAndTransformToPageOffset15
A GOT entry getter/constructor, transformed to Pageoffset15 pointing at the GOT entry for the origina...
 
@ CondBranch19PCRel
A 19-bit PC-relative conditional branch.
 
@ RequestTLVPAndTransformToPageOffset12
A TLVP entry getter/constructor, transformed to PageOffset12.
 
@ RequestTLSDescEntryAndTransformToPageOffset12
A TLSDesc entry getter/constructor, transformed to PageOffset12.
 
@ Page21
The signed 21-bit delta from the fixup page to the page containing the target.
 
@ Branch26PCRel
A 26-bit PC-relative branch.
 
@ Pointer64
A plain 64-bit pointer value relocation.
 
@ Pointer32
A plain 32-bit pointer value relocation.
 
@ RequestTLVPAndTransformToPage21
A TLVP entry getter/constructor, transformed to Page21.
 
@ GotPageOffset15
The 15-bit offset of the GOT entry from the GOT table.
 
@ MoveWide16
A 16-bit slice of the target address (which slice depends on the instruction at the fixup location).
 
@ TestAndBranch14PCRel
A 14-bit PC-relative test and branch.
 
@ RequestGOTAndTransformToPage21
A GOT entry getter/constructor, transformed to Page21 pointing at the GOT entry for the original targ...
 
@ ADRLiteral21
The signed 21-bit delta from the fixup to the target.
 
@ RequestGOTAndTransformToPageOffset12
A GOT entry getter/constructor, transformed to Pageoffset12 pointing at the GOT entry for the origina...
 
@ NegDelta32
A 32-bit negative delta.
 
@ NegDelta64
A 64-bit negative delta.
 
@ RequestGOTAndTransformToDelta32
A GOT entry getter/constructor, transformed to Delta32 pointing at the GOT entry for the original tar...
 
@ PageOffset12
The 12-bit (potentially shifted) offset of the target within its page.
 
@ RequestTLSDescEntryAndTransformToPage21
A TLSDesc entry getter/constructor, transformed to Page21.
 
static Error writePACSignSeq(AppendFtor &Append, unsigned DstReg, orc::ExecutorAddr RawAddr, unsigned RawAddrReg, unsigned DiscriminatorReg, unsigned Key, uint64_t EncodedDiscriminator, bool AddressDiversify)
 
LLVM_ABI const char * getGenericEdgeKindName(Edge::Kind K)
Returns the string name of the given generic edge kind, or "unknown" otherwise.
 
@ NoAlloc
NoAlloc memory should not be allocated by the JITLinkMemoryManager at all.
 
@ Finalize
Finalize memory should be allocated by the allocator, and then be overwritten and deallocated after a...
 
This is an optimization pass for GlobalISel generic memory operations.
 
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.
 
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
 
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
 
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.