ExecutionUtils.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. //===---- ExecutionUtils.cpp - Utilities for executing functions in Orc ---===//
  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. #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
  10. #include "llvm/IR/Constants.h"
  11. #include "llvm/IR/Function.h"
  12. #include "llvm/IR/GlobalVariable.h"
  13. #include "llvm/IR/Module.h"
  14. #include "llvm/Support/TargetRegistry.h"
  15. #include "llvm/Target/TargetMachine.h"
  16. namespace llvm {
  17. namespace orc {
  18. CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End)
  19. : InitList(
  20. GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr),
  21. I((InitList && End) ? InitList->getNumOperands() : 0) {
  22. }
  23. bool CtorDtorIterator::operator==(const CtorDtorIterator &Other) const {
  24. assert(InitList == Other.InitList && "Incomparable iterators.");
  25. return I == Other.I;
  26. }
  27. bool CtorDtorIterator::operator!=(const CtorDtorIterator &Other) const {
  28. return !(*this == Other);
  29. }
  30. CtorDtorIterator& CtorDtorIterator::operator++() {
  31. ++I;
  32. return *this;
  33. }
  34. CtorDtorIterator CtorDtorIterator::operator++(int) {
  35. CtorDtorIterator Temp = *this;
  36. ++I;
  37. return Temp;
  38. }
  39. CtorDtorIterator::Element CtorDtorIterator::operator*() const {
  40. ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(I));
  41. assert(CS && "Unrecognized type in llvm.global_ctors/llvm.global_dtors");
  42. Constant *FuncC = CS->getOperand(1);
  43. Function *Func = nullptr;
  44. // Extract function pointer, pulling off any casts.
  45. while (FuncC) {
  46. if (Function *F = dyn_cast_or_null<Function>(FuncC)) {
  47. Func = F;
  48. break;
  49. } else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) {
  50. if (CE->isCast())
  51. FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0));
  52. else
  53. break;
  54. } else {
  55. // This isn't anything we recognize. Bail out with Func left set to null.
  56. break;
  57. }
  58. }
  59. ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
  60. Value *Data = CS->getNumOperands() == 3 ? CS->getOperand(2) : nullptr;
  61. if (Data && !isa<GlobalValue>(Data))
  62. Data = nullptr;
  63. return Element(Priority->getZExtValue(), Func, Data);
  64. }
  65. iterator_range<CtorDtorIterator> getConstructors(const Module &M) {
  66. const GlobalVariable *CtorsList = M.getNamedGlobal("llvm.global_ctors");
  67. return make_range(CtorDtorIterator(CtorsList, false),
  68. CtorDtorIterator(CtorsList, true));
  69. }
  70. iterator_range<CtorDtorIterator> getDestructors(const Module &M) {
  71. const GlobalVariable *DtorsList = M.getNamedGlobal("llvm.global_dtors");
  72. return make_range(CtorDtorIterator(DtorsList, false),
  73. CtorDtorIterator(DtorsList, true));
  74. }
  75. void CtorDtorRunner::add(iterator_range<CtorDtorIterator> CtorDtors) {
  76. if (empty(CtorDtors))
  77. return;
  78. MangleAndInterner Mangle(
  79. JD.getExecutionSession(),
  80. (*CtorDtors.begin()).Func->getParent()->getDataLayout());
  81. for (const auto &CtorDtor : CtorDtors) {
  82. assert(CtorDtor.Func && CtorDtor.Func->hasName() &&
  83. "Ctor/Dtor function must be named to be runnable under the JIT");
  84. // FIXME: Maybe use a symbol promoter here instead.
  85. if (CtorDtor.Func->hasLocalLinkage()) {
  86. CtorDtor.Func->setLinkage(GlobalValue::ExternalLinkage);
  87. CtorDtor.Func->setVisibility(GlobalValue::HiddenVisibility);
  88. }
  89. if (CtorDtor.Data && cast<GlobalValue>(CtorDtor.Data)->isDeclaration()) {
  90. dbgs() << " Skipping because why now?\n";
  91. continue;
  92. }
  93. CtorDtorsByPriority[CtorDtor.Priority].push_back(
  94. Mangle(CtorDtor.Func->getName()));
  95. }
  96. }
  97. Error CtorDtorRunner::run() {
  98. using CtorDtorTy = void (*)();
  99. SymbolNameSet Names;
  100. for (auto &KV : CtorDtorsByPriority) {
  101. for (auto &Name : KV.second) {
  102. auto Added = Names.insert(Name).second;
  103. (void)Added;
  104. assert(Added && "Ctor/Dtor names clashed");
  105. }
  106. }
  107. auto &ES = JD.getExecutionSession();
  108. if (auto CtorDtorMap =
  109. ES.lookup(JITDylibSearchList({{&JD, true}}), std::move(Names),
  110. NoDependenciesToRegister, true)) {
  111. for (auto &KV : CtorDtorsByPriority) {
  112. for (auto &Name : KV.second) {
  113. assert(CtorDtorMap->count(Name) && "No entry for Name");
  114. auto CtorDtor = reinterpret_cast<CtorDtorTy>(
  115. static_cast<uintptr_t>((*CtorDtorMap)[Name].getAddress()));
  116. CtorDtor();
  117. }
  118. }
  119. return Error::success();
  120. } else
  121. return CtorDtorMap.takeError();
  122. CtorDtorsByPriority.clear();
  123. return Error::success();
  124. }
  125. void LocalCXXRuntimeOverridesBase::runDestructors() {
  126. auto& CXXDestructorDataPairs = DSOHandleOverride;
  127. for (auto &P : CXXDestructorDataPairs)
  128. P.first(P.second);
  129. CXXDestructorDataPairs.clear();
  130. }
  131. int LocalCXXRuntimeOverridesBase::CXAAtExitOverride(DestructorPtr Destructor,
  132. void *Arg,
  133. void *DSOHandle) {
  134. auto& CXXDestructorDataPairs =
  135. *reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle);
  136. CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg));
  137. return 0;
  138. }
  139. Error LocalCXXRuntimeOverrides::enable(JITDylib &JD,
  140. MangleAndInterner &Mangle) {
  141. SymbolMap RuntimeInterposes;
  142. RuntimeInterposes[Mangle("__dso_handle")] =
  143. JITEvaluatedSymbol(toTargetAddress(&DSOHandleOverride),
  144. JITSymbolFlags::Exported);
  145. RuntimeInterposes[Mangle("__cxa_atexit")] =
  146. JITEvaluatedSymbol(toTargetAddress(&CXAAtExitOverride),
  147. JITSymbolFlags::Exported);
  148. return JD.define(absoluteSymbols(std::move(RuntimeInterposes)));
  149. }
  150. DynamicLibrarySearchGenerator::DynamicLibrarySearchGenerator(
  151. sys::DynamicLibrary Dylib, const DataLayout &DL, SymbolPredicate Allow)
  152. : Dylib(std::move(Dylib)), Allow(std::move(Allow)),
  153. GlobalPrefix(DL.getGlobalPrefix()) {}
  154. Expected<DynamicLibrarySearchGenerator>
  155. DynamicLibrarySearchGenerator::Load(const char *FileName, const DataLayout &DL,
  156. SymbolPredicate Allow) {
  157. std::string ErrMsg;
  158. auto Lib = sys::DynamicLibrary::getPermanentLibrary(FileName, &ErrMsg);
  159. if (!Lib.isValid())
  160. return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
  161. return DynamicLibrarySearchGenerator(std::move(Lib), DL, std::move(Allow));
  162. }
  163. SymbolNameSet DynamicLibrarySearchGenerator::
  164. operator()(JITDylib &JD, const SymbolNameSet &Names) {
  165. orc::SymbolNameSet Added;
  166. orc::SymbolMap NewSymbols;
  167. bool HasGlobalPrefix = (GlobalPrefix != '\0');
  168. for (auto &Name : Names) {
  169. if ((*Name).empty())
  170. continue;
  171. if (Allow && !Allow(Name))
  172. continue;
  173. if (HasGlobalPrefix && (*Name).front() != GlobalPrefix)
  174. continue;
  175. std::string Tmp((*Name).data() + (HasGlobalPrefix ? 1 : 0), (*Name).size());
  176. if (void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str())) {
  177. Added.insert(Name);
  178. NewSymbols[Name] = JITEvaluatedSymbol(
  179. static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(Addr)),
  180. JITSymbolFlags::Exported);
  181. }
  182. }
  183. // Add any new symbols to JD. Since the generator is only called for symbols
  184. // that are not already defined, this will never trigger a duplicate
  185. // definition error, so we can wrap this call in a 'cantFail'.
  186. if (!NewSymbols.empty())
  187. cantFail(JD.define(absoluteSymbols(std::move(NewSymbols))));
  188. return Added;
  189. }
  190. } // End namespace orc.
  191. } // End namespace llvm.