@@ -90,8 +90,8 @@ auto OTFResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
9090 LOG_IF_ENABLE (BOOST_LOG_SEV (lg::get (), DEBUG)
9191 << " Call virtual function: " << llvmIRToString (CallSite));
9292
93- auto VtableIndex = getVFTIndex (CallSite);
94- if (VtableIndex < 0 ) {
93+ auto RetrievedVtableIndex = getVFTIndex (CallSite);
94+ if (!RetrievedVtableIndex. has_value () ) {
9595 // An error occured
9696 LOG_IF_ENABLE (BOOST_LOG_SEV (lg::get (), DEBUG)
9797 << " Error with resolveVirtualCall : impossible to retrieve "
@@ -100,34 +100,42 @@ auto OTFResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
100100 return {};
101101 }
102102
103+ auto VtableIndex = RetrievedVtableIndex.value ();
104+
103105 LOG_IF_ENABLE (BOOST_LOG_SEV (lg::get (), DEBUG)
104106 << " Virtual function table entry is: " << VtableIndex);
105107
106108 const llvm::Value *Receiver = CallSite->getArgOperand (0 );
107109
108- // Use points-to information to resolve the indirect call
109- auto AllocSites = PT.getReachableAllocationSites (Receiver);
110- auto PossibleAllocatedTypes = getReachableTypes (*AllocSites);
111-
112- // Now we must check if we have found some allocated struct types
113- set<const llvm::StructType *> PossibleTypes;
114- for (const auto *Type : PossibleAllocatedTypes) {
115- if (const auto *StructType =
116- llvm::dyn_cast<llvm::StructType>(stripPointer (Type))) {
117- PossibleTypes.insert (StructType);
118- }
119- }
110+ if (CallSite->getCalledOperand () &&
111+ CallSite->getCalledOperand ()->getType ()->isPointerTy ()) {
112+ if (const auto *FTy = llvm::dyn_cast<llvm::FunctionType>(
113+ CallSite->getCalledOperand ()->getType ()->getPointerElementType ())) {
120114
121- for (const auto *PossibleTypeStruct : PossibleTypes) {
122- const auto *Target =
123- getNonPureVirtualVFTEntry (PossibleTypeStruct, VtableIndex, CallSite);
124- if (Target) {
125- PossibleCallTargets.insert (Target);
115+ auto PTS = PT.getPointsToSet (CallSite->getCalledOperand (), CallSite);
116+ for (const auto *P : *PTS) {
117+ if (auto *PGV = llvm::dyn_cast<llvm::GlobalVariable>(P)) {
118+ if (PGV->hasName () &&
119+ PGV->getName ().startswith (LLVMTypeHierarchy::VTablePrefix) &&
120+ PGV->hasInitializer ()) {
121+ if (auto *PCS = llvm::dyn_cast<llvm::ConstantStruct>(
122+ PGV->getInitializer ())) {
123+ auto VFs = LLVMVFTable::getVFVectorFromIRVTable (*PCS);
124+ if (VtableIndex >= VFs.size ()) {
125+ continue ;
126+ }
127+ auto *Callee = VFs[VtableIndex];
128+ if (Callee == nullptr || !Callee->hasName () ||
129+ Callee->getName () == LLVMTypeHierarchy::PureVirtualCallName) {
130+ continue ;
131+ }
132+ PossibleCallTargets.insert (Callee);
133+ }
134+ }
135+ }
136+ }
126137 }
127138 }
128- if (PossibleCallTargets.empty ()) {
129- return CHAResolver::resolveVirtualCall (CallSite);
130- }
131139
132140 return PossibleCallTargets;
133141}
0 commit comments