LLVM: include/llvm/ExecutionEngine/Orc/IndirectionUtils.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13#ifndef LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H

14#define LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H

15

27#include

28#include

29#include

30#include

31#include

32#include

33#include

34#include <system_error>

35#include

36#include

37

38namespace llvm {

39

52

56}

57

58namespace orc {

59

60

61

62

63

64

66public:

69

73

75

76

77

79 std::lock_guardstd::mutex Lock(TPMutex);

81 if (auto Err = grow())

82 return std::move(Err);

83 }

87 return TrampolineAddr;

88 }

89

90

92 std::lock_guardstd::mutex Lock(TPMutex);

94 }

95

96protected:

98

101};

102

103

104template class LocalTrampolinePool : public TrampolinePool {

105public:

106

107

108

112

113 auto LTP = std::unique_ptr(

114 new LocalTrampolinePool(std::move(ResolveLanding), Err));

115

116 if (Err)

117 return std::move(Err);

118 return std::move(LTP);

119 }

120

121private:

122 static JITTargetAddress reenter(void *TrampolinePoolPtr, void *TrampolineId) {

125

126 std::promise LandingAddressP;

127 auto LandingAddressF = LandingAddressP.get_future();

128

131 LandingAddressP.set_value(LandingAddress);

132 });

133 return LandingAddressF.get().getValue();

134 }

135

136 LocalTrampolinePool(ResolveLandingFunction ResolveLanding, Error &Err)

137 : ResolveLanding(std::move(ResolveLanding)) {

138

139 ErrorAsOutParameter _(Err);

140

141

142 std::error_code EC;

144 ORCABI::ResolverCodeSize, nullptr,

146 if (EC) {

148 return;

149 }

150

151 ORCABI::writeResolverCode(static_cast<char *>(ResolverBlock.base()),

155

159 if (EC) {

161 return;

162 }

163 }

164

167

168 std::error_code EC;

169 auto TrampolineBlock =

173 if (EC)

175

176 unsigned NumTrampolines =

178 ORCABI::TrampolineSize;

179

180 char *TrampolineMem = static_cast<char *>(TrampolineBlock.base());

181 ORCABI::writeTrampolines(

184

185 for (unsigned I = 0; I < NumTrampolines; ++I)

188

190 TrampolineBlock.getMemoryBlock(),

193

194 TrampolineBlocks.push_back(std::move(TrampolineBlock));

196 }

197

199

200 sys::OwningMemoryBlock ResolverBlock;

201 std::vectorsys::OwningMemoryBlock TrampolineBlocks;

202};

203

204

206public:

208

210

211

213

214

215

217

218protected:

219

223 : TP(std::move(TP)), ES(ES),

224 CallbacksJD(ES.createBareJITDylib("")),

225 ErrorHandlerAddress(ErrorHandlerAddress) {}

226

228 this->TP = std::move(TP);

229 }

230

231private:

232 std::mutex CCMgrMutex;

233 std::unique_ptr TP;

237 std::map<ExecutorAddr, SymbolStringPtr> AddrToSymbol;

238 size_t NextCallbackId = 0;

239};

240

241

242template

244public:

245

249 auto CCMgr = std::unique_ptr(

250 new LocalJITCompileCallbackManager(ES, ErrorHandlerAddress, Err));

251 if (Err)

252 return std::move(Err);

253 return std::move(CCMgr);

254 }

255

256private:

257

258

259

263 using NotifyLandingResolvedFunction =

265

269 NotifyLandingResolvedFunction NotifyLandingResolved) {

271 });

272

273 if (!TP) {

274 Err = TP.takeError();

275 return;

276 }

277

279 }

280};

281

282

284public:

285

287

289

290

293

294

295

297

298

299

300

302 bool ExportedStubsOnly) = 0;

303

304

306

307

309

310

312

313 void

315 SymbolMap InitialDests) override;

316

317private:

318 void anchor() override;

319};

320

322public:

324 : NumStubs(NumStubs), StubsMem(std::move(StubsMem)) {}

325

329

331 "StubBytes is not a page size multiple");

333

334

335 std::error_code EC;

336 auto StubsAndPtrsMem =

338 ISAS.StubBytes + PointerAlloc, nullptr,

340 if (EC)

342

343 sys::MemoryBlock StubsBlock(StubsAndPtrsMem.base(), ISAS.StubBytes);

344 auto StubsBlockMem = static_cast<char *>(StubsAndPtrsMem.base());

345 auto PtrBlockAddress =

347

348 ORCABI::writeIndirectStubsBlock(StubsBlockMem,

350 PtrBlockAddress, ISAS.NumStubs);

351

355

357 }

358

360

362 return static_cast<char *>(StubsMem.base()) + Idx * ORCABI::StubSize;

363 }

364

365 void **getPtr(unsigned Idx) const {

366 char *PtrsBase =

367 static_cast<char *>(StubsMem.base()) + NumStubs * ORCABI::StubSize;

368 return reinterpret_cast<void **>(PtrsBase) + Idx;

369 }

370

371private:

372 unsigned NumStubs = 0;

374};

375

376

377

378template

380public:

383 std::lock_guardstd::mutex Lock(StubsMutex);

384 if (auto Err = reserveStubs(1))

385 return Err;

386

387 createStubInternal(StubName, StubAddr, StubFlags);

388

390 }

391

393 std::lock_guardstd::mutex Lock(StubsMutex);

394 if (auto Err = reserveStubs(StubInits.size()))

395 return Err;

396

397 for (const auto &Entry : StubInits)

398 createStubInternal(Entry.first(), Entry.second.first,

399 Entry.second.second);

400

402 }

403

405 std::lock_guardstd::mutex Lock(StubsMutex);

406 auto I = StubIndexes.find(Name);

407 if (I == StubIndexes.end())

409 auto Key = I->second.first;

410 void *StubPtr = IndirectStubsInfos[Key.first].getStub(Key.second);

411 assert(StubPtr && "Missing stub address");

414 if (ExportedStubsOnly && !StubSymbol.getFlags().isExported())

416 return StubSymbol;

417 }

418

420 std::lock_guardstd::mutex Lock(StubsMutex);

421 auto I = StubIndexes.find(Name);

422 if (I == StubIndexes.end())

424 auto Key = I->second.first;

425 void *PtrPtr = IndirectStubsInfos[Key.first].getPtr(Key.second);

426 assert(PtrPtr && "Missing pointer address");

429 }

430

432 using AtomicIntPtr = std::atomic<uintptr_t>;

433

434 std::lock_guardstd::mutex Lock(StubsMutex);

435 auto I = StubIndexes.find(Name);

436 assert(I != StubIndexes.end() && "No stub pointer for symbol");

437 auto Key = I->second.first;

438 AtomicIntPtr *AtomicStubPtr = reinterpret_cast<AtomicIntPtr *>(

439 IndirectStubsInfos[Key.first].getPtr(Key.second));

440 *AtomicStubPtr = static_cast<uintptr_t>(NewAddr.getValue());

442 }

443

444private:

445 Error reserveStubs(unsigned NumStubs) {

446 if (NumStubs <= FreeStubs.size())

448

449 unsigned NewStubsRequired = NumStubs - FreeStubs.size();

450 unsigned NewBlockId = IndirectStubsInfos.size();

451 auto ISI =

453 if (!ISI)

454 return ISI.takeError();

455 for (unsigned I = 0; I < ISI->getNumStubs(); ++I)

456 FreeStubs.push_back(std::make_pair(NewBlockId, I));

457 IndirectStubsInfos.push_back(std::move(*ISI));

459 }

460

461 void createStubInternal(StringRef StubName, ExecutorAddr InitAddr,

463 auto Key = FreeStubs.back();

464 FreeStubs.pop_back();

465 *IndirectStubsInfos[Key.first].getPtr(Key.second) =

466 InitAddr.toPtr<void *>();

467 StubIndexes[StubName] = std::make_pair(Key, StubFlags);

468 }

469

471 std::mutex StubsMutex;

472 std::vector<LocalIndirectStubsInfo> IndirectStubsInfos;

473 using StubKey = std::pair<uint16_t, uint16_t>;

474 std::vector FreeStubs;

475 StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes;

476};

477

478

479

480

481

482

483LLVM_ABI Expected<std::unique_ptr>

486

487

488

489

490LLVM_ABI std::function<std::unique_ptr()>

492

493

494

495

496

497

499

500

501

503 const Twine &Name,

504 Constant *Initializer);

505

506

507

509

510

511

512

514public:

515

516

518

519private:

520 unsigned NextId = 0;

521};

522

523

524

525

526

527

528

529

530

531

532

533

534

537

538

542

543

547

548

549

550

551

552

553

554

555

556

557

558

559

560

561

562

563

564

565

566

567

568

569

573

574}

575

576}

577

578#endif

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

This file defines the StringMap class.

static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096), cl::Hidden)

Machine Check Debug Module

Provides a library for accessing information about this process and other processes on the operating ...

This is an important base class in LLVM.

Helper for Errors used as out-parameters.

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.

Class to represent function types.

Flags for symbols in the JIT.

Superclass for all disassemblers.

A Module instance is used to store all the information related to an LLVM module.

Class to represent pointers.

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

StringRef - Represent a constant reference to a string, i.e.

Triple - Helper class for working with autoconf configuration names.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM Value Representation.

An ExecutionSession represents a running JIT program.

Represents an address in the executor process.

uint64_t getValue() const

static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap=UnwrapFn())

Create an ExecutorAddr from the given pointer.

Represents a defining location for a JIT symbol.

Base class for managing collections of named indirect stubs.

Definition IndirectionUtils.h:283

virtual Error createStub(StringRef StubName, ExecutorAddr StubAddr, JITSymbolFlags StubFlags)=0

Create a single stub with the given name, target address and flags.

virtual ExecutorSymbolDef findStub(StringRef Name, bool ExportedStubsOnly)=0

Find the stub with the given name.

~IndirectStubsManager() override=default

StringMap< std::pair< ExecutorAddr, JITSymbolFlags > > StubInitsMap

Map type for initializing the manager. See init.

Definition IndirectionUtils.h:286

virtual ExecutorSymbolDef findPointer(StringRef Name)=0

Find the implementation-pointer for the stub.

virtual Error updatePointer(StringRef Name, ExecutorAddr NewAddr)=0

Change the value of the implementation pointer for the stub.

virtual Error createStubs(const StubInitsMap &StubInits)=0

Create StubInits.size() stubs with the given names, target addresses, and flags.

void emitRedirectableSymbols(std::unique_ptr< MaterializationResponsibility > MR, SymbolMap InitialDests) override

Emit redirectable symbol.

Error redirect(JITDylib &JD, const SymbolMap &NewDests) override

— RedirectableSymbolManager implementation —

Target-independent base class for compile callback management.

Definition IndirectionUtils.h:205

JITCompileCallbackManager(std::unique_ptr< TrampolinePool > TP, ExecutionSession &ES, ExecutorAddr ErrorHandlerAddress)

Construct a JITCompileCallbackManager.

Definition IndirectionUtils.h:220

LLVM_ABI ExecutorAddr executeCompileCallback(ExecutorAddr TrampolineAddr)

Execute the callback for the given trampoline id.

virtual ~JITCompileCallbackManager()=default

LLVM_ABI Expected< ExecutorAddr > getCompileCallback(CompileFunction Compile)

Reserve a compile callback.

void setTrampolinePool(std::unique_ptr< TrampolinePool > TP)

Definition IndirectionUtils.h:227

std::function< ExecutorAddr()> CompileFunction

Definition IndirectionUtils.h:207

Represents a JIT'd dynamic library.

unsigned getNumStubs() const

Definition IndirectionUtils.h:359

void * getStub(unsigned Idx) const

Definition IndirectionUtils.h:361

LocalIndirectStubsInfo(unsigned NumStubs, sys::OwningMemoryBlock StubsMem)

Definition IndirectionUtils.h:323

static Expected< LocalIndirectStubsInfo > create(unsigned MinStubs, unsigned PageSize)

Definition IndirectionUtils.h:326

void ** getPtr(unsigned Idx) const

Definition IndirectionUtils.h:365

IndirectStubsManager implementation for the host architecture, e.g.

Definition IndirectionUtils.h:379

Error createStub(StringRef StubName, ExecutorAddr StubAddr, JITSymbolFlags StubFlags) override

Create a single stub with the given name, target address and flags.

Definition IndirectionUtils.h:381

ExecutorSymbolDef findPointer(StringRef Name) override

Find the implementation-pointer for the stub.

Definition IndirectionUtils.h:419

Error updatePointer(StringRef Name, ExecutorAddr NewAddr) override

Change the value of the implementation pointer for the stub.

Definition IndirectionUtils.h:431

ExecutorSymbolDef findStub(StringRef Name, bool ExportedStubsOnly) override

Find the stub with the given name.

Definition IndirectionUtils.h:404

Error createStubs(const StubInitsMap &StubInits) override

Create StubInits.size() stubs with the given names, target addresses, and flags.

Definition IndirectionUtils.h:392

Manage compile callbacks for in-process JITs.

Definition IndirectionUtils.h:243

static Expected< std::unique_ptr< LocalJITCompileCallbackManager > > Create(ExecutionSession &ES, ExecutorAddr ErrorHandlerAddress)

Create a new LocalJITCompileCallbackManager.

Definition IndirectionUtils.h:247

A trampoline pool for trampolines within the current process.

Definition IndirectionUtils.h:104

static Expected< std::unique_ptr< LocalTrampolinePool > > Create(ResolveLandingFunction ResolveLanding)

Creates a LocalTrampolinePool with the given RunCallback function.

Definition IndirectionUtils.h:110

Base class for managing redirectable symbols in which a call gets redirected to another symbol in run...

Base class for pools of compiler re-entry trampolines.

Definition IndirectionUtils.h:65

std::vector< ExecutorAddr > AvailableTrampolines

Definition IndirectionUtils.h:100

std::mutex TPMutex

Definition IndirectionUtils.h:99

virtual ~TrampolinePool()

unique_function< void( ExecutorAddr TrampolineAddr, NotifyLandingResolvedFunction OnLandingResolved) const > ResolveLandingFunction

Definition IndirectionUtils.h:70

unique_function< void(ExecutorAddr) const > NotifyLandingResolvedFunction

Definition IndirectionUtils.h:67

void releaseTrampoline(ExecutorAddr TrampolineAddr)

Returns the given trampoline to the pool for re-use.

Definition IndirectionUtils.h:91

Expected< ExecutorAddr > getTrampoline()

Get an available trampoline address.

Definition IndirectionUtils.h:78

This class encapsulates the notion of a memory block which has an address and a size.

static LLVM_ABI std::error_code protectMappedMemory(const MemoryBlock &Block, unsigned Flags)

This method sets the protection flags for a block of memory to the state specified by /p Flags.

static LLVM_ABI MemoryBlock allocateMappedMemory(size_t NumBytes, const MemoryBlock *const NearBlock, unsigned Flags, std::error_code &EC)

This method allocates a block of memory that is suitable for loading dynamically generated code (e....

Owning version of MemoryBlock.

static unsigned getPageSizeEstimate()

Get the process's estimated page size.

unique_function is a type-erasing functor similar to std::function.

IndirectStubsAllocationSizes getIndirectStubsBlockSizes(unsigned MinStubs, unsigned RoundToMultipleOf=0)

LLVM_ABI Constant * createIRTypedAddress(FunctionType &FT, ExecutorAddr Addr)

Build a function pointer of FunctionType with the given constant address.

LLVM_ABI Expected< std::unique_ptr< JITCompileCallbackManager > > createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, ExecutorAddr ErrorHandlerAddress)

Create a local compile callback manager.

LLVM_ABI void makeStub(Function &F, Value &ImplPointer)

Turn a function declaration into a stub function that makes an indirect call using the given function...

LLVM_ABI Error addFunctionPointerRelocationsToCurrentSymbol(jitlink::Symbol &Sym, jitlink::LinkGraph &G, MCDisassembler &Disassembler, MCInstrAnalysis &MIA)

Introduce relocations to Sym in its own definition if there are any pointers formed via PC-relative a...

LLVM_ABI GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)

Clone a global variable declaration into a new module.

DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap

A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).

LLVM_ABI Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)

Clone a function declaration into a new module.

LLVM_ABI std::function< std::unique_ptr< IndirectStubsManager >()> createLocalIndirectStubsManagerBuilder(const Triple &T)

Create a local indirect stubs manager builder.

LLVM_ABI GlobalAlias * cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, ValueToValueMapTy &VMap)

Clone a global alias declaration into a new module.

LLVM_ABI GlobalVariable * createImplPointer(PointerType &PT, Module &M, const Twine &Name, Constant *Initializer)

Create a function pointer with the given type, name, and initializer in the given Module.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

uint64_t JITTargetAddress

Represents an address in the target process's address space.

LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI Error errorCodeToError(std::error_code EC)

Helper for converting an std::error_code to a Error.

Implement std::hash so that hash_code can be used in STL containers.