| 9 | : Handler(std::move(Handler)) {} |
| 10 | |
| 11 | std::set<const Function *> TBAAVirtSolver::solve(const CallBase &CB) const { |
| 12 | const MDNode *TBAA = nullptr; |
| 13 | unsigned Index = 0; |
| 14 | const auto *CO = CB.getCalledOperand(); |
| 15 | assert(CO && "Unexpected LLVM API Behavior"); |
| 16 | |
| 17 | const auto *T = CO->getType(); |
| 18 | if (!T) |
| 19 | return {}; |
| 20 | |
| 21 | const auto *CT = dyn_cast_or_null<FunctionType>(T->getPointerElementType()); |
| 22 | if (!CT) |
| 23 | return {}; |
| 24 | |
| 25 | if (!isVirtCall(CB, &TBAA, &Index)) |
| 26 | return {}; |
| 27 | |
| 28 | auto VirtTables = Handler.get(TBAA); |
| 29 | if (VirtTables.size() == 0) |
| 30 | return {}; |
| 31 | |
| 32 | std::set<const Function *> Result; |
| 33 | for (const auto *VirtTable : VirtTables) { |
| 34 | const auto *T = VirtTable->getType(); |
| 35 | assert(T && "Unexpected LLVM API Behavior"); |
| 36 | assert(T->isArrayTy() && "Unexpected Program State"); |
| 37 | |
| 38 | if (Index + 2 >= T->getArrayNumElements()) |
| 39 | continue; |
| 40 | |
| 41 | const auto *E = VirtTable->getAggregateElement(Index + 2); |
| 42 | assert(E && "Unexpected LLVM API Behavior"); |
| 43 | |
| 44 | const auto *F = dyn_cast<Function>(E->stripPointerCasts()); |
| 45 | assert(F && "Unexpected LLVM API Behavior"); |
| 46 | |
| 47 | if (F->getName() == "__cxa_pure_virtual") |
| 48 | continue; |
| 49 | |
| 50 | const auto *FT = F->getFunctionType(); |
| 51 | assert(FT && "Unexpected LLVM API Behavior"); |
| 52 | |
| 53 | if (!isCallableType(*CT, *FT)) |
| 54 | continue; |
| 55 | |
| 56 | Result.emplace(F); |
| 57 | } |
| 58 | return Result; |
| 59 | } |
| 60 | |
| 61 | bool TBAAVirtSolver::isCallableType(const FunctionType &CallerType, |
| 62 | const FunctionType &CalleeType) const { |