void ClassHierarchyUtils::cacheAllCalleesForVirtualCalls(Module& M) { if (!cachingDone) { for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { if (CallInst* C = dyn_cast<CallInst>(&*I)) { GlobalVariable* definingTypeVTableVar = NULL; GlobalVariable* staticTypeVTableVar = NULL; bool hasMetadata = false; if (MDNode* N = I->getMetadata("soaap_defining_vtable_var")) { definingTypeVTableVar = cast<GlobalVariable>(N->getOperand(0)); hasMetadata = true; } else if (MDNode* N = I->getMetadata("soaap_defining_vtable_name")) { ConstantDataArray* definingTypeVTableConstant = cast<ConstantDataArray>(N->getOperand(0)); string definingTypeVTableConstantStr = definingTypeVTableConstant->getAsString().str(); //dbgs() << "definingTypeVTableConstantStr: " << definingTypeVTableConstantStr << "\n"; definingTypeVTableVar = M.getGlobalVariable(definingTypeVTableConstantStr, true); hasMetadata = true; } if (MDNode* N = I->getMetadata("soaap_static_vtable_var")) { staticTypeVTableVar = cast<GlobalVariable>(N->getOperand(0)); hasMetadata = true; } else if (MDNode* N = I->getMetadata("soaap_static_vtable_name")) { ConstantDataArray* staticTypeVTableConstant = cast<ConstantDataArray>(N->getOperand(0)); string staticTypeVTableConstantStr = staticTypeVTableConstant->getAsString().str(); //dbgs() << "staticTypeVTableConstantStr: " << staticTypeVTableConstantStr << "\n"; staticTypeVTableVar = M.getGlobalVariable(staticTypeVTableConstantStr, true); hasMetadata = true; } if (definingTypeVTableVar != NULL) { SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found definingVTableVar: " << *definingTypeVTableVar << "\n"); if (staticTypeVTableVar == NULL) { dbgs() << "definingVTableVar is not null, but staticTypeVTableVar is NULL\n"; // This could be the case if no instance of the static type is ever created staticTypeVTableVar = definingTypeVTableVar; } callToCalleesCache[C] = findAllCalleesForVirtualCall(C, definingTypeVTableVar, staticTypeVTableVar, M); } else if (hasMetadata) { dbgs() << "Defining VTable is NULL!\n"; I->dump(); } } } } cachingDone = true; } }
void AssertionSiteInstrumenter::ParseAssertionLocation( Location *Loc, CallInst *Call) { assert(Call->getCalledFunction()->getName() == INLINE_ASSERTION); if (Call->getNumArgOperands() < 4) panic("TESLA assertion must have at least 4 arguments"); // The filename (argument 1) should be a global variable. GlobalVariable *NameVar = dyn_cast<GlobalVariable>(Call->getOperand(1)->stripPointerCasts()); ConstantDataArray *A; if (!NameVar || !(A = dyn_cast_or_null<ConstantDataArray>(NameVar->getInitializer()))) { Call->dump(); panic("unable to parse filename from TESLA assertion"); } *Loc->mutable_filename() = A->getAsString(); // The line and counter values should be constant integers. ConstantInt *Line = dyn_cast<ConstantInt>(Call->getOperand(2)); if (!Line) { Call->getOperand(2)->dump(); panic("assertion line must be a constant int"); } Loc->set_line(Line->getLimitedValue(INT_MAX)); ConstantInt *Count = dyn_cast<ConstantInt>(Call->getOperand(3)); if (!Count) { Call->getOperand(3)->dump(); panic("assertion count must be a constant int"); } Loc->set_counter(Count->getLimitedValue(INT_MAX)); }