LLVM  6.0.0svn
ExecutionUtils.h
Go to the documentation of this file.
1 //===- ExecutionUtils.h - Utilities for executing code in Orc ---*- 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 // Contains utilities for executing code in Orc.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
15 #define LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
16 
17 #include "llvm/ADT/StringMap.h"
22 #include <algorithm>
23 #include <cstdint>
24 #include <string>
25 #include <vector>
26 #include <utility>
27 
28 namespace llvm {
29 
30 class ConstantArray;
31 class GlobalVariable;
32 class Function;
33 class Module;
34 class Value;
35 
36 namespace orc {
37 
38 /// @brief This iterator provides a convenient way to iterate over the elements
39 /// of an llvm.global_ctors/llvm.global_dtors instance.
40 ///
41 /// The easiest way to get hold of instances of this class is to use the
42 /// getConstructors/getDestructors functions.
44 public:
45  /// @brief Accessor for an element of the global_ctors/global_dtors array.
46  ///
47  /// This class provides a read-only view of the element with any casts on
48  /// the function stripped away.
49  struct Element {
51  : Priority(Priority), Func(Func), Data(Data) {}
52 
53  unsigned Priority;
56  };
57 
58  /// @brief Construct an iterator instance. If End is true then this iterator
59  /// acts as the end of the range, otherwise it is the beginning.
60  CtorDtorIterator(const GlobalVariable *GV, bool End);
61 
62  /// @brief Test iterators for equality.
63  bool operator==(const CtorDtorIterator &Other) const;
64 
65  /// @brief Test iterators for inequality.
66  bool operator!=(const CtorDtorIterator &Other) const;
67 
68  /// @brief Pre-increment iterator.
70 
71  /// @brief Post-increment iterator.
73 
74  /// @brief Dereference iterator. The resulting value provides a read-only view
75  /// of this element of the global_ctors/global_dtors list.
76  Element operator*() const;
77 
78 private:
79  const ConstantArray *InitList;
80  unsigned I;
81 };
82 
83 /// @brief Create an iterator range over the entries of the llvm.global_ctors
84 /// array.
86 
87 /// @brief Create an iterator range over the entries of the llvm.global_ctors
88 /// array.
90 
91 /// @brief Convenience class for recording constructor/destructor names for
92 /// later execution.
93 template <typename JITLayerT>
95 public:
96  /// @brief Construct a CtorDtorRunner for the given range using the given
97  /// name mangling function.
98  CtorDtorRunner(std::vector<std::string> CtorDtorNames,
99  typename JITLayerT::ModuleHandleT H)
100  : CtorDtorNames(std::move(CtorDtorNames)), H(H) {}
101 
102  /// @brief Run the recorded constructors/destructors through the given JIT
103  /// layer.
104  Error runViaLayer(JITLayerT &JITLayer) const {
105  using CtorDtorTy = void (*)();
106 
107  for (const auto &CtorDtorName : CtorDtorNames)
108  if (auto CtorDtorSym = JITLayer.findSymbolIn(H, CtorDtorName, false)) {
109  if (auto AddrOrErr = CtorDtorSym.getAddress()) {
110  CtorDtorTy CtorDtor =
111  reinterpret_cast<CtorDtorTy>(static_cast<uintptr_t>(*AddrOrErr));
112  CtorDtor();
113  } else
114  return AddrOrErr.takeError();
115  } else {
116  if (auto Err = CtorDtorSym.takeError())
117  return Err;
118  else
119  return make_error<JITSymbolNotFound>(CtorDtorName);
120  }
121  return Error::success();
122  }
123 
124 private:
125  std::vector<std::string> CtorDtorNames;
126  typename JITLayerT::ModuleHandleT H;
127 };
128 
129 /// @brief Support class for static dtor execution. For hosted (in-process) JITs
130 /// only!
131 ///
132 /// If a __cxa_atexit function isn't found C++ programs that use static
133 /// destructors will fail to link. However, we don't want to use the host
134 /// process's __cxa_atexit, because it will schedule JIT'd destructors to run
135 /// after the JIT has been torn down, which is no good. This class makes it easy
136 /// to override __cxa_atexit (and the related __dso_handle).
137 ///
138 /// To use, clients should manually call searchOverrides from their symbol
139 /// resolver. This should generally be done after attempting symbol resolution
140 /// inside the JIT, but before searching the host process's symbol table. When
141 /// the client determines that destructors should be run (generally at JIT
142 /// teardown or after a return from main), the runDestructors method should be
143 /// called.
145 public:
146  /// Create a runtime-overrides class.
147  template <typename MangleFtorT>
148  LocalCXXRuntimeOverrides(const MangleFtorT &Mangle) {
149  addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride));
150  addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride));
151  }
152 
153  /// Search overrided symbols.
155  auto I = CXXRuntimeOverrides.find(Name);
156  if (I != CXXRuntimeOverrides.end())
158  return nullptr;
159  }
160 
161  /// Run any destructors recorded by the overriden __cxa_atexit function
162  /// (CXAAtExitOverride).
163  void runDestructors();
164 
165 private:
166  template <typename PtrTy>
167  JITTargetAddress toTargetAddress(PtrTy* P) {
168  return static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(P));
169  }
170 
171  void addOverride(const std::string &Name, JITTargetAddress Addr) {
172  CXXRuntimeOverrides.insert(std::make_pair(Name, Addr));
173  }
174 
175  StringMap<JITTargetAddress> CXXRuntimeOverrides;
176 
177  using DestructorPtr = void (*)(void *);
178  using CXXDestructorDataPair = std::pair<DestructorPtr, void *>;
179  using CXXDestructorDataPairList = std::vector<CXXDestructorDataPair>;
180  CXXDestructorDataPairList DSOHandleOverride;
181  static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg,
182  void *DSOHandle);
183 };
184 
185 } // end namespace orc
186 
187 } // end namespace llvm
188 
189 #endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
Accessor for an element of the global_ctors/global_dtors array.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
bool operator==(const CtorDtorIterator &Other) const
Test iterators for equality.
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:63
CtorDtorRunner(std::vector< std::string > CtorDtorNames, typename JITLayerT::ModuleHandleT H)
Construct a CtorDtorRunner for the given range using the given name mangling function.
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
Element(unsigned Priority, Function *Func, Value *Data)
CtorDtorIterator & operator++()
Pre-increment iterator.
Definition: BitVector.h:920
JITEvaluatedSymbol searchOverrides(const std::string &Name)
Search overrided symbols.
Support class for static dtor execution.
iterator_range< CtorDtorIterator > getDestructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
CtorDtorIterator(const GlobalVariable *GV, bool End)
Construct an iterator instance.
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:37
Error runViaLayer(JITLayerT &JITLayer) const
Run the recorded constructors/destructors through the given JIT layer.
Convenience class for recording constructor/destructor names for later execution. ...
#define P(N)
#define H(x, y, z)
Definition: MD5.cpp:57
static const unsigned End
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
This iterator provides a convenient way to iterate over the elements of an llvm.global_ctors/llvm.global_dtors instance.
A range adaptor for a pair of iterators.
ConstantArray - Constant Array Declarations.
Definition: Constants.h:405
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:135
amdgpu Simplify well known AMD library false Value Value * Arg
LocalCXXRuntimeOverrides(const MangleFtorT &Mangle)
Create a runtime-overrides class.
iterator_range< CtorDtorIterator > getConstructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
#define I(x, y, z)
Definition: MD5.cpp:58
LLVM Value Representation.
Definition: Value.h:73
Element operator*() const
Dereference iterator.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
bool operator!=(const CtorDtorIterator &Other) const
Test iterators for inequality.