LLVM  6.0.0svn
OrcCBindingsStack.h
Go to the documentation of this file.
1 //===- OrcCBindingsStack.h - Orc JIT stack for C bindings -----*- C++ -*---===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
11 #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
12 
13 #include "llvm-c/OrcBindings.h"
14 #include "llvm-c/TargetMachine.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/StringRef.h"
26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/IR/Mangler.h"
28 #include "llvm/IR/Module.h"
30 #include "llvm/Support/Error.h"
33 #include <algorithm>
34 #include <cstdint>
35 #include <functional>
36 #include <memory>
37 #include <set>
38 #include <string>
39 #include <vector>
40 
41 namespace llvm {
42 
43 class OrcCBindingsStack;
44 
45 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<Module>,
49 
50 namespace detail {
51 
52 
53  class GenericHandle {
54  public:
55  virtual ~GenericHandle() = default;
56 
57  virtual JITSymbol findSymbolIn(const std::string &Name,
58  bool ExportedSymbolsOnly) = 0;
59  virtual Error removeModule() = 0;
60  };
61 
62  template <typename LayerT> class GenericHandleImpl : public GenericHandle {
63  public:
64  GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleHandleT Handle)
65  : Layer(Layer), Handle(std::move(Handle)) {}
66 
67  JITSymbol findSymbolIn(const std::string &Name,
68  bool ExportedSymbolsOnly) override {
69  return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
70  }
71 
72  Error removeModule() override { return Layer.removeModule(Handle); }
73 
74  private:
75  LayerT &Layer;
76  typename LayerT::ModuleHandleT Handle;
77  };
78 
79  template <>
80  class GenericHandleImpl<orc::RTDyldObjectLinkingLayer>
81  : public GenericHandle {
82  private:
83  using LayerT = orc::RTDyldObjectLinkingLayer;
84  public:
85 
86  GenericHandleImpl(LayerT &Layer, typename LayerT::ObjHandleT Handle)
87  : Layer(Layer), Handle(std::move(Handle)) {}
88 
89  JITSymbol findSymbolIn(const std::string &Name,
90  bool ExportedSymbolsOnly) override {
91  return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
92  }
93 
94  Error removeModule() override { return Layer.removeObject(Handle); }
95 
96  private:
97  LayerT &Layer;
98  typename LayerT::ObjHandleT Handle;
99  };
100 
101 
102  template <typename LayerT, typename HandleT>
103  std::unique_ptr<GenericHandleImpl<LayerT>>
104  createGenericHandle(LayerT &Layer, HandleT Handle) {
105  return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
106  std::move(Handle));
107  }
108 
109 } // end namespace detail
110 
112 public:
113 
117  using CODLayerT =
119 
120  using CallbackManagerBuilder =
121  std::function<std::unique_ptr<CompileCallbackMgr>()>;
122 
124 
125 private:
126 
128 
129 public:
131 
133  std::unique_ptr<CompileCallbackMgr> CCMgr,
134  IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
135  : DL(TM.createDataLayout()), IndirectStubsMgr(IndirectStubsMgrBuilder()),
136  CCMgr(std::move(CCMgr)),
137  ObjectLayer(
138  []() {
139  return std::make_shared<SectionMemoryManager>();
140  }),
141  CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
142  CODLayer(CompileLayer,
143  [](Function &F) { return std::set<Function *>({&F}); },
144  *this->CCMgr, std::move(IndirectStubsMgrBuilder), false),
145  CXXRuntimeOverrides(
146  [this](const std::string &S) { return mangle(S); }) {}
147 
149  // Run any destructors registered with __cxa_atexit.
150  CXXRuntimeOverrides.runDestructors();
151  // Run any IR destructors.
152  for (auto &DtorRunner : IRStaticDestructorRunners)
153  if (auto Err = DtorRunner.runViaLayer(*this))
154  return mapError(std::move(Err));
155  return LLVMOrcErrSuccess;
156  }
157 
158  std::string mangle(StringRef Name) {
159  std::string MangledName;
160  {
161  raw_string_ostream MangledNameStream(MangledName);
162  Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
163  }
164  return MangledName;
165  }
166 
167  template <typename PtrTy>
168  static PtrTy fromTargetAddress(JITTargetAddress Addr) {
169  return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
170  }
171 
172 
176  void *CallbackCtx) {
177  if (auto CCInfoOrErr = CCMgr->getCompileCallback()) {
178  auto &CCInfo = *CCInfoOrErr;
179  CCInfo.setCompileAction([=]() -> JITTargetAddress {
180  return Callback(wrap(this), CallbackCtx);
181  });
182  RetAddr = CCInfo.getAddress();
183  return LLVMOrcErrSuccess;
184  } else
185  return mapError(CCInfoOrErr.takeError());
186  }
187 
189  JITTargetAddress Addr) {
190  return mapError(
191  IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported));
192  }
193 
195  JITTargetAddress Addr) {
196  return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
197  }
198 
199  std::shared_ptr<JITSymbolResolver>
201  void *ExternalResolverCtx) {
203  [this, ExternalResolver, ExternalResolverCtx](const std::string &Name)
204  -> JITSymbol {
205  // Search order:
206  // 1. JIT'd symbols.
207  // 2. Runtime overrides.
208  // 3. External resolver (if present).
209 
210  if (auto Sym = CODLayer.findSymbol(Name, true))
211  return Sym;
212  else if (auto Err = Sym.takeError())
213  return Sym.takeError();
214 
215  if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
216  return Sym;
217 
218  if (ExternalResolver)
219  return JITSymbol(
220  ExternalResolver(Name.c_str(), ExternalResolverCtx),
222 
223  return JITSymbol(nullptr);
224  },
225  [](const std::string &Name) -> JITSymbol {
226  return JITSymbol(nullptr);
227  });
228  }
229 
230  template <typename LayerT>
232  addIRModule(ModuleHandleT &RetHandle, LayerT &Layer,
233  std::shared_ptr<Module> M,
234  std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
235  LLVMOrcSymbolResolverFn ExternalResolver,
236  void *ExternalResolverCtx) {
237 
238  // Attach a data-layout if one isn't already present.
239  if (M->getDataLayout().isDefault())
240  M->setDataLayout(DL);
241 
242  // Record the static constructors and destructors. We have to do this before
243  // we hand over ownership of the module to the JIT.
244  std::vector<std::string> CtorNames, DtorNames;
245  for (auto Ctor : orc::getConstructors(*M))
246  CtorNames.push_back(mangle(Ctor.Func->getName()));
247  for (auto Dtor : orc::getDestructors(*M))
248  DtorNames.push_back(mangle(Dtor.Func->getName()));
249 
250  // Create the resolver.
251  auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
252 
253  // Add the module to the JIT.
255  if (auto LHOrErr = Layer.addModule(std::move(M), std::move(Resolver)))
256  H = createHandle(Layer, *LHOrErr);
257  else
258  return mapError(LHOrErr.takeError());
259 
260  // Run the static constructors, and save the static destructor runner for
261  // execution when the JIT is torn down.
262  orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), H);
263  if (auto Err = CtorRunner.runViaLayer(*this))
264  return mapError(std::move(Err));
265 
266  IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
267 
268  RetHandle = H;
269  return LLVMOrcErrSuccess;
270  }
271 
273  std::shared_ptr<Module> M,
274  LLVMOrcSymbolResolverFn ExternalResolver,
275  void *ExternalResolverCtx) {
276  return addIRModule(RetHandle, CompileLayer, std::move(M),
277  llvm::make_unique<SectionMemoryManager>(),
278  std::move(ExternalResolver), ExternalResolverCtx);
279  }
280 
282  std::shared_ptr<Module> M,
283  LLVMOrcSymbolResolverFn ExternalResolver,
284  void *ExternalResolverCtx) {
285  return addIRModule(RetHandle, CODLayer, std::move(M),
286  llvm::make_unique<SectionMemoryManager>(),
287  std::move(ExternalResolver), ExternalResolverCtx);
288  }
289 
291  if (auto Err = GenericHandles[H]->removeModule())
292  return mapError(std::move(Err));
293  GenericHandles[H] = nullptr;
294  FreeHandleIndexes.push_back(H);
295  return LLVMOrcErrSuccess;
296  }
297 
299  std::unique_ptr<MemoryBuffer> ObjBuffer,
300  LLVMOrcSymbolResolverFn ExternalResolver,
301  void *ExternalResolverCtx) {
302  if (auto ObjOrErr =
303  object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef())) {
304  auto &Obj = *ObjOrErr;
305  auto OwningObj =
306  std::make_shared<OwningObject>(std::move(Obj), std::move(ObjBuffer));
307 
308  // Create the resolver.
309  auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
310 
312  if (auto HOrErr = ObjectLayer.addObject(std::move(OwningObj),
313  std::move(Resolver)))
314  H = createHandle(ObjectLayer, *HOrErr);
315  else
316  return mapError(HOrErr.takeError());
317 
318  RetHandle = H;
319 
320  return LLVMOrcErrSuccess;
321  } else
322  return mapError(ObjOrErr.takeError());
323  }
324 
325  JITSymbol findSymbol(const std::string &Name,
326  bool ExportedSymbolsOnly) {
327  if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
328  return Sym;
329  return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
330  }
331 
333  bool ExportedSymbolsOnly) {
334  return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
335  }
336 
338  const std::string &Name,
339  bool ExportedSymbolsOnly) {
340  RetAddr = 0;
341  if (auto Sym = findSymbol(Name, ExportedSymbolsOnly)) {
342  // Successful lookup, non-null symbol:
343  if (auto AddrOrErr = Sym.getAddress()) {
344  RetAddr = *AddrOrErr;
345  return LLVMOrcErrSuccess;
346  } else
347  return mapError(AddrOrErr.takeError());
348  } else if (auto Err = Sym.takeError()) {
349  // Lookup failure - report error.
350  return mapError(std::move(Err));
351  }
352  // Otherwise we had a successful lookup but got a null result. We already
353  // set RetAddr to '0' above, so just return success.
354  return LLVMOrcErrSuccess;
355  }
356 
357  const std::string &getErrorMessage() const { return ErrMsg; }
358 
359 private:
360  template <typename LayerT, typename HandleT>
361  unsigned createHandle(LayerT &Layer, HandleT Handle) {
362  unsigned NewHandle;
363  if (!FreeHandleIndexes.empty()) {
364  NewHandle = FreeHandleIndexes.back();
365  FreeHandleIndexes.pop_back();
366  GenericHandles[NewHandle] =
367  detail::createGenericHandle(Layer, std::move(Handle));
368  return NewHandle;
369  } else {
370  NewHandle = GenericHandles.size();
371  GenericHandles.push_back(
372  detail::createGenericHandle(Layer, std::move(Handle)));
373  }
374  return NewHandle;
375  }
376 
377  LLVMOrcErrorCode mapError(Error Err) {
379  handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
380  // Handler of last resort.
381  Result = LLVMOrcErrGeneric;
382  ErrMsg = "";
383  raw_string_ostream ErrStream(ErrMsg);
384  EIB.log(ErrStream);
385  });
386  return Result;
387  }
388 
389  DataLayout DL;
390  SectionMemoryManager CCMgrMemMgr;
391 
392  std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr;
393 
394  std::unique_ptr<CompileCallbackMgr> CCMgr;
395  ObjLayerT ObjectLayer;
396  CompileLayerT CompileLayer;
397  CODLayerT CODLayer;
398 
399  std::vector<std::unique_ptr<detail::GenericHandle>> GenericHandles;
400  std::vector<unsigned> FreeHandleIndexes;
401 
402  orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
403  std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
404  std::string ErrMsg;
405 };
406 
407 } // end namespace llvm
408 
409 #endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
LLVMOrcErrorCode addObject(ModuleHandleT &RetHandle, std::unique_ptr< MemoryBuffer > ObjBuffer, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx)
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Create ObjectFile from path.
Definition: ObjectFile.cpp:152
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:109
CODLayerT::IndirectStubsManagerBuilderT IndirectStubsManagerBuilder
LLVMOrcErrorCode addIRModuleLazy(ModuleHandleT &RetHandle, std::shared_ptr< Module > M, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx)
Represents a symbol in the JIT.
Definition: JITSymbol.h:159
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
std::function< std::unique_ptr< CompileCallbackMgr >()> CallbackManagerBuilder
LLVMOrcErrorCode setIndirectStubPointer(StringRef Name, JITTargetAddress Addr)
Bare bones object linking layer.
F(f)
Base class for error info classes.
Definition: Error.h:47
Target-independent base class for compile callback management.
Definition: BitVector.h:920
struct LLVMOpaqueTargetMachine * LLVMTargetMachineRef
Definition: TargetMachine.h:28
std::function< std::unique_ptr< IndirectStubsManager >()> IndirectStubsManagerBuilderT
Builder for IndirectStubsManagers.
virtual void log(raw_ostream &OS) const =0
Print an error message to an output stream.
LLVMOrcErrorCode shutdown()
Simple compile functor: Takes a single IR module and returns an ObjectFile.
Definition: CompileUtils.h:40
Support class for static dtor execution.
struct LLVMOpaqueSharedModule * LLVMSharedModuleRef
Definition: OrcBindings.h:32
iterator_range< CtorDtorIterator > getDestructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
OrcCBindingsStack(TargetMachine &TM, std::unique_ptr< CompileCallbackMgr > CCMgr, IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
std::shared_ptr< JITSymbolResolver > createResolver(LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx)
LLVMOrcErrorCode
Definition: OrcBindings.h:40
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:37
LLVMOrcErrorCode removeModule(ModuleHandleT H)
JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, bool ExportedSymbolsOnly)
Convenience class for recording constructor/destructor names for later execution. ...
#define H(x, y, z)
Definition: MD5.cpp:57
LLVMOrcErrorCode createIndirectStub(StringRef StubName, JITTargetAddress Addr)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr< Module >, LLVMSharedModuleRef) namespace detail
std::string mangle(StringRef Name)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that it requires that all errors be handled by the given han...
Definition: Error.h:889
Module.h This file contains the declarations for the Module class.
LLVMOrcErrorCode createLazyCompileCallback(JITTargetAddress &RetAddr, LLVMOrcLazyCompileCallbackFn Callback, void *CallbackCtx)
uint64_t(* LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack, void *CallbackCtx)
Definition: OrcBindings.h:37
const std::string & getErrorMessage() const
static PtrTy fromTargetAddress(JITTargetAddress Addr)
uint64_t(* LLVMOrcSymbolResolverFn)(const char *Name, void *LookupCtx)
Definition: OrcBindings.h:36
LLVMAttributeRef wrap(Attribute Attr)
Definition: Attributes.h:190
iterator_range< CtorDtorIterator > getConstructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
This is a simple memory manager which implements the methods called by the RuntimeDyld class to alloc...
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:462
std::shared_ptr< LambdaResolver< DylibLookupFtorT, ExternalLookupFtorT > > createLambdaResolver(DylibLookupFtorT DylibLookupFtor, ExternalLookupFtorT ExternalLookupFtor)
JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly)
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:57
LLVMOrcErrorCode addIRModule(ModuleHandleT &RetHandle, LayerT &Layer, std::shared_ptr< Module > M, std::unique_ptr< RuntimeDyld::MemoryManager > MemMgr, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx)
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable&#39;s name.
Definition: Mangler.cpp:109
Error takeError()
Move the error field value out of this JITSymbol.
Definition: JITSymbol.h:227
LLVMOrcErrorCode addIRModuleEager(ModuleHandleT &RetHandle, std::shared_ptr< Module > M, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
struct LLVMOrcOpaqueJITStack * LLVMOrcJITStackRef
Definition: OrcBindings.h:33
LLVMOrcErrorCode findSymbolAddress(JITTargetAddress &RetAddr, const std::string &Name, bool ExportedSymbolsOnly)