LLVM  3.7.0
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 "JITSymbol.h"
19 #include "llvm/ADT/StringMap.h"
21 #include <vector>
22 
23 namespace llvm {
24 
25 class ConstantArray;
26 class GlobalVariable;
27 class Function;
28 class Module;
29 class Value;
30 
31 namespace orc {
32 
33 /// @brief This iterator provides a convenient way to iterate over the elements
34 /// of an llvm.global_ctors/llvm.global_dtors instance.
35 ///
36 /// The easiest way to get hold of instances of this class is to use the
37 /// getConstructors/getDestructors functions.
39 public:
40 
41  /// @brief Accessor for an element of the global_ctors/global_dtors array.
42  ///
43  /// This class provides a read-only view of the element with any casts on
44  /// the function stripped away.
45  struct Element {
46  Element(unsigned Priority, const Function *Func, const Value *Data)
47  : Priority(Priority), Func(Func), Data(Data) {}
48 
49  unsigned Priority;
50  const Function *Func;
51  const Value *Data;
52  };
53 
54  /// @brief Construct an iterator instance. If End is true then this iterator
55  /// acts as the end of the range, otherwise it is the beginning.
56  CtorDtorIterator(const GlobalVariable *GV, bool End);
57 
58  /// @brief Test iterators for equality.
59  bool operator==(const CtorDtorIterator &Other) const;
60 
61  /// @brief Test iterators for inequality.
62  bool operator!=(const CtorDtorIterator &Other) const;
63 
64  /// @brief Pre-increment iterator.
66 
67  /// @brief Post-increment iterator.
69 
70  /// @brief Dereference iterator. The resulting value provides a read-only view
71  /// of this element of the global_ctors/global_dtors list.
72  Element operator*() const;
73 
74 private:
75  const ConstantArray *InitList;
76  unsigned I;
77 };
78 
79 /// @brief Create an iterator range over the entries of the llvm.global_ctors
80 /// array.
82 
83 /// @brief Create an iterator range over the entries of the llvm.global_ctors
84 /// array.
86 
87 /// @brief Convenience class for recording constructor/destructor names for
88 /// later execution.
89 template <typename JITLayerT>
91 public:
92 
93  /// @brief Construct a CtorDtorRunner for the given range using the given
94  /// name mangling function.
95  CtorDtorRunner(std::vector<std::string> CtorDtorNames,
96  typename JITLayerT::ModuleSetHandleT H)
97  : CtorDtorNames(std::move(CtorDtorNames)), H(H) {}
98 
99  /// @brief Run the recorded constructors/destructors through the given JIT
100  /// layer.
101  bool runViaLayer(JITLayerT &JITLayer) const {
102  typedef void (*CtorDtorTy)();
103 
104  bool Error = false;
105  for (const auto &CtorDtorName : CtorDtorNames)
106  if (auto CtorDtorSym = JITLayer.findSymbolIn(H, CtorDtorName, false)) {
107  CtorDtorTy CtorDtor =
108  reinterpret_cast<CtorDtorTy>(
109  static_cast<uintptr_t>(CtorDtorSym.getAddress()));
110  CtorDtor();
111  } else
112  Error = true;
113  return !Error;
114  }
115 
116 private:
117  std::vector<std::string> CtorDtorNames;
118  typename JITLayerT::ModuleSetHandleT H;
119 };
120 
121 /// @brief Support class for static dtor execution. For hosted (in-process) JITs
122 /// only!
123 ///
124 /// If a __cxa_atexit function isn't found C++ programs that use static
125 /// destructors will fail to link. However, we don't want to use the host
126 /// process's __cxa_atexit, because it will schedule JIT'd destructors to run
127 /// after the JIT has been torn down, which is no good. This class makes it easy
128 /// to override __cxa_atexit (and the related __dso_handle).
129 ///
130 /// To use, clients should manually call searchOverrides from their symbol
131 /// resolver. This should generally be done after attempting symbol resolution
132 /// inside the JIT, but before searching the host process's symbol table. When
133 /// the client determines that destructors should be run (generally at JIT
134 /// teardown or after a return from main), the runDestructors method should be
135 /// called.
137 public:
138 
139  /// Create a runtime-overrides class.
140  template <typename MangleFtorT>
141  LocalCXXRuntimeOverrides(const MangleFtorT &Mangle) {
142  addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride));
143  addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride));
144  }
145 
146  /// Search overrided symbols.
148  auto I = CXXRuntimeOverrides.find(Name);
149  if (I != CXXRuntimeOverrides.end())
151  return nullptr;
152  }
153 
154  /// Run any destructors recorded by the overriden __cxa_atexit function
155  /// (CXAAtExitOverride).
156  void runDestructors();
157 
158 private:
159 
160  template <typename PtrTy>
161  TargetAddress toTargetAddress(PtrTy* P) {
162  return static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(P));
163  }
164 
165  void addOverride(const std::string &Name, TargetAddress Addr) {
166  CXXRuntimeOverrides.insert(std::make_pair(Name, Addr));
167  }
168 
169  StringMap<TargetAddress> CXXRuntimeOverrides;
170 
171  typedef void (*DestructorPtr)(void*);
172  typedef std::pair<DestructorPtr, void*> CXXDestructorDataPair;
173  typedef std::vector<CXXDestructorDataPair> CXXDestructorDataPairList;
174  CXXDestructorDataPairList DSOHandleOverride;
175  static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg,
176  void *DSOHandle);
177 };
178 
179 } // End namespace orc.
180 } // End namespace llvm.
181 
182 #endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
Accessor for an element of the global_ctors/global_dtors array.
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:114
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
bool runViaLayer(JITLayerT &JITLayer) const
Run the recorded constructors/destructors through the given JIT layer.
iterator find(StringRef Key)
Definition: StringMap.h:265
void runDestructors()
Run any destructors recorded by the overriden __cxa_atexit function (CXAAtExitOverride).
CtorDtorIterator & operator++()
Pre-increment iterator.
CtorDtorRunner(std::vector< std::string > CtorDtorNames, typename JITLayerT::ModuleSetHandleT H)
Construct a CtorDtorRunner for the given range using the given name mangling function.
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:591
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.
RuntimeDyld::SymbolInfo searchOverrides(const std::string &Name)
Search overrided symbols.
Convenience class for recording constructor/destructor names for later execution. ...
#define P(N)
Element(unsigned Priority, const Function *Func, const Value *Data)
This iterator provides a convenient way to iterate over the elements of an llvm.global_ctors/llvm.global_dtors instance.
uint64_t TargetAddress
Represents an address in the target process's address space.
Definition: JITSymbol.h:26
bool operator!=(const CtorDtorIterator &Other) const
Test iterators for inequality.
bool operator==(const CtorDtorIterator &Other) const
Test iterators for equality.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:298
A range adaptor for a pair of iterators.
ConstantArray - Constant Array Declarations.
Definition: Constants.h:356
Element operator*() const
Dereference iterator.
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:54
Information about a named symbol.
Definition: RuntimeDyld.h:47
LLVM Value Representation.
Definition: Value.h:69
iterator end()
Definition: StringMap.h:255