bool llvm::slicing::findInitialCriterion(Function &F, FunctionStaticSlicer &ss, bool starting) { bool added = false; #ifdef DEBUG_INITCRIT errs() << __func__ << " ============ BEGIN\n"; #endif const Function *Fklee_assume = F.getParent()->getFunction("klee_assume"); const Function *F__assert_fail = F.getParent()->getFunction("__assert_fail"); if (!F__assert_fail) /* no cookies in this module */ return false; for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { const Instruction *i = &*I; if (const StoreInst *SI = dyn_cast<StoreInst>(i)) { const Value *LHS = SI->getPointerOperand(); if (LHS->hasName() && LHS->getName().startswith("__ai_state_")) { #ifdef DEBUG_INITCRIT errs() << " adding\n"; #endif ss.addInitialCriterion(SI, ptr::PointsToSets::Pointee(LHS, -1)); } } else if (const CallInst *CI = dyn_cast<CallInst>(i)) { Function *callie = CI->getCalledFunction(); if (callie == F__assert_fail) { added = handleAssert(F, ss, CI); } else if (callie == Fklee_assume) { // this is kind of hack const Value *l = elimConstExpr(CI->getArgOperand(0)); ss.addInitialCriterion(CI, ptr::PointsToSets::Pointee(l, -1)); } } else if (const ReturnInst *RI = dyn_cast<ReturnInst>(i)) { if (starting) { const Module *M = F.getParent(); for (Module::const_global_iterator II = M->global_begin(), EE = M->global_end(); II != EE; ++II) { const GlobalVariable &GV = *II; if (!GV.hasName() || !GV.getName().startswith("__ai_state_")) continue; #ifdef DEBUG_INITCRIT errs() << "adding " << GV.getName() << " into " << F.getName() << " to \n"; RI->dump(); #endif ss.addInitialCriterion(RI, ptr::PointsToSets::Pointee(&GV, -1), false); } } } } #ifdef DEBUG_INITCRIT errs() << __func__ << " ============ END\n"; #endif return added; }
bool llvm::slicing::findInitialCriterion(Function &F, FunctionStaticSlicer &ss, bool starting) { bool added = false; #ifdef DEBUG_INITCRIT errs() << __func__ << " ============ BEGIN\n"; #endif for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { const Instruction *i = &*I; i->dump(); if (const StoreInst *SI = dyn_cast<StoreInst>(i)) { const Value *LHS = SI->getPointerOperand(); if (LHS->hasName() && LHS->getName().startswith("product")) { #ifdef DEBUG_INITCRIT errs() << " adding\n"; #endif ss.addInitialCriterion(SI, LHS); } /* } else if (const CallInst *CI = dyn_cast<CallInst>(i)) { Function *callie = CI->getCalledFunction(); if (callie == F__assert_fail) { added = handleAssert(F, ss, CI); } */ } else if (const ReturnInst *RI = dyn_cast<ReturnInst>(i)) { if (starting) { const Module *M = F.getParent(); for (Module::const_global_iterator II = M->global_begin(), EE = M->global_end(); II != EE; ++II) { const GlobalVariable &GV = *II; if (!GV.hasName() || !GV.getName().startswith("__ai_state_")) continue; #ifdef DEBUG_INITCRIT errs() << "adding " << GV.getName() << " into " << F.getName() << " to \n"; RI->dump(); #endif ss.addInitialCriterion(RI, &GV, false); } } } } #ifdef DEBUG_INITCRIT errs() << __func__ << " ============ END\n"; #endif return added; }
bool llvm::slicing::handleCall(Function &F, FunctionStaticSlicer &ss, const CallInst *CI) { const char *ass_file = getenv("SLICE_ASSERT_FILE"); const char *ass_line = getenv("SLICE_ASSERT_LINE"); const ConstantExpr *fileArg = dyn_cast<ConstantExpr>(CI->getArgOperand(1)); //const ConstantInt *lineArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)); const ConstantInt *lineArg = dyn_cast<ConstantInt>(CI->getArgOperand(1)); if (ass_file && ass_line) { if (fileArg && fileArg->getOpcode() == Instruction::GetElementPtr && lineArg) { const GlobalVariable *strVar = dyn_cast<GlobalVariable>(fileArg->getOperand(0)); assert(strVar && strVar->hasInitializer()); const ConstantDataArray *str = dyn_cast<ConstantDataArray>(strVar->getInitializer()); assert(str && str->isCString()); /* trim the NUL terminator */ StringRef fileArgStr = str->getAsString().drop_back(1); const int ass_line_int = atoi(ass_line); errs() << "ASSERT at " << fileArgStr << ":" << lineArg->getValue() << "\n"; if (fileArgStr.equals(ass_file) && lineArg->equalsInt(ass_line_int)) { errs() << "\tMATCH\n"; goto count; } } ss.addSkipAssert(CI); return false; } count: #ifdef DEBUG_INITCRIT errs() << " adding\n"; #endif ss.addInitialCriterion(CI, Pointee(F.getParent()->getGlobalVariable("__ai_init_functions", true), -1)); // Add all the arguments of the call instruction for( int i = 0; i< CI->getNumArgOperands(); i++){ ss.addInitialCriterion(CI, Pointee(CI->getArgOperand(i), -1)); } return true; }
static bool handleAssert(Function &F, FunctionStaticSlicer &ss, const CallInst *CI) { const char *ass_file = getenv("SLICE_ASSERT_FILE"); const char *ass_line = getenv("SLICE_ASSERT_LINE"); const ConstantExpr *fileArg = dyn_cast<ConstantExpr>(CI->getArgOperand(1)); const ConstantInt *lineArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)); if (ass_file && ass_line) { if (fileArg && fileArg->getOpcode() == Instruction::GetElementPtr && lineArg) { const GlobalVariable *strVar = dyn_cast<GlobalVariable>(fileArg->getOperand(0)); assert(strVar && strVar->hasInitializer()); const ConstantArray *str = dyn_cast<ConstantArray>(strVar->getInitializer()); assert(str && str->isCString()); /* trim the NUL terminator */ StringRef tmpStr(str->getAsString()); StringRef fileArgStr = tmpStr.substr(0,tmpStr.size() - 1); const int ass_line_int = atoi(ass_line); errs() << "ASSERT at " << fileArgStr << ":" << lineArg->getValue() << "\n"; if (fileArgStr.equals(ass_file) && lineArg->equalsInt(ass_line_int)) { errs() << "\tMATCH\n"; goto count; } } ss.addSkipAssert(CI); return false; } count: #ifdef DEBUG_INITCRIT errs() << " adding\n"; #endif ss.addInitialCriterion(CI, F.getParent()->getGlobalVariable("__ai_init_functions", true)); return true; }