Lang Hames | b1cd98a | 2015-04-02 04:34:45 +0000 | [diff] [blame] | 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 | |
| 10 | #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" |
| 11 | |
| 12 | #include "llvm/IR/Constants.h" |
| 13 | #include "llvm/IR/Function.h" |
| 14 | #include "llvm/IR/GlobalVariable.h" |
| 15 | #include "llvm/IR/Module.h" |
| 16 | |
| 17 | namespace llvm { |
| 18 | namespace orc { |
| 19 | |
| 20 | CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End) |
| 21 | : InitList( |
| 22 | GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr), |
| 23 | I((InitList && End) ? InitList->getNumOperands() : 0) { |
| 24 | } |
| 25 | |
| 26 | bool CtorDtorIterator::operator==(const CtorDtorIterator &Other) const { |
| 27 | assert(InitList == Other.InitList && "Incomparable iterators."); |
| 28 | return I == Other.I; |
| 29 | } |
| 30 | |
| 31 | bool CtorDtorIterator::operator!=(const CtorDtorIterator &Other) const { |
| 32 | return !(*this == Other); |
| 33 | } |
| 34 | |
| 35 | CtorDtorIterator& CtorDtorIterator::operator++() { |
| 36 | ++I; |
| 37 | return *this; |
| 38 | } |
| 39 | |
| 40 | CtorDtorIterator CtorDtorIterator::operator++(int) { |
| 41 | CtorDtorIterator Temp = *this; |
| 42 | ++I; |
| 43 | return Temp; |
| 44 | } |
| 45 | |
| 46 | CtorDtorIterator::Element CtorDtorIterator::operator*() const { |
| 47 | ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(I)); |
| 48 | assert(CS && "Unrecognized type in llvm.global_ctors/llvm.global_dtors"); |
| 49 | |
| 50 | Constant *FuncC = CS->getOperand(1); |
| 51 | Function *Func = nullptr; |
| 52 | |
| 53 | // Extract function pointer, pulling off any casts. |
| 54 | while (FuncC) { |
| 55 | if (Function *F = dyn_cast_or_null<Function>(FuncC)) { |
| 56 | Func = F; |
| 57 | break; |
| 58 | } else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) { |
| 59 | if (CE->isCast()) |
| 60 | FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0)); |
| 61 | else |
| 62 | break; |
| 63 | } else { |
| 64 | // This isn't anything we recognize. Bail out with Func left set to null. |
| 65 | break; |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0)); |
Lang Hames | 5721ee4 | 2018-03-15 00:30:14 +0000 | [diff] [blame] | 70 | Value *Data = CS->getNumOperands() == 3 ? CS->getOperand(2) : nullptr; |
Lang Hames | b1cd98a | 2015-04-02 04:34:45 +0000 | [diff] [blame] | 71 | return Element(Priority->getZExtValue(), Func, Data); |
| 72 | } |
| 73 | |
| 74 | iterator_range<CtorDtorIterator> getConstructors(const Module &M) { |
| 75 | const GlobalVariable *CtorsList = M.getNamedGlobal("llvm.global_ctors"); |
| 76 | return make_range(CtorDtorIterator(CtorsList, false), |
| 77 | CtorDtorIterator(CtorsList, true)); |
| 78 | } |
| 79 | |
| 80 | iterator_range<CtorDtorIterator> getDestructors(const Module &M) { |
| 81 | const GlobalVariable *DtorsList = M.getNamedGlobal("llvm.global_dtors"); |
| 82 | return make_range(CtorDtorIterator(DtorsList, false), |
| 83 | CtorDtorIterator(DtorsList, true)); |
| 84 | } |
| 85 | |
| 86 | void LocalCXXRuntimeOverrides::runDestructors() { |
| 87 | auto& CXXDestructorDataPairs = DSOHandleOverride; |
| 88 | for (auto &P : CXXDestructorDataPairs) |
| 89 | P.first(P.second); |
| 90 | CXXDestructorDataPairs.clear(); |
| 91 | } |
| 92 | |
| 93 | int LocalCXXRuntimeOverrides::CXAAtExitOverride(DestructorPtr Destructor, |
| 94 | void *Arg, void *DSOHandle) { |
| 95 | auto& CXXDestructorDataPairs = |
| 96 | *reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle); |
| 97 | CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg)); |
| 98 | return 0; |
| 99 | } |
| 100 | |
| 101 | } // End namespace orc. |
| 102 | } // End namespace llvm. |