void NetworkDriverRewriteVisitor::InstrumentEntryPoints(FunctionDecl* funcDecl, string fdFile) { if (funcDecl->getStorageClass() == SC_Static) RW.RemoveText(funcDecl->getInnerLocStart(), 7); if (DI->getInstance().GetInitFunction() == funcDecl->getNameInfo().getName().getAsString()) return; if (funcDecl->getParamDecl(0)->getOriginalType().getAsString() != "struct device *" && funcDecl->getParamDecl(0)->getOriginalType().getAsString() != "struct pci_dev *") return; SourceRange sr = funcDecl->getParamDecl(0)->getSourceRange(); RW.InsertTextBefore(sr.getBegin(), "struct net_device *dev, "); Stmt *body = funcDecl->getBody(); list<DeclStmt*> stmtsToRewrite; for (auto i = body->child_begin(), e = body->child_end(); i != e; ++i) { if (!isa<DeclStmt>(*i)) continue; DeclStmt *declStmt = cast<DeclStmt>(*i); if (!declStmt->isSingleDecl() && !isa<VarDecl>(declStmt->getSingleDecl())) continue; VarDecl *var = cast<VarDecl>(declStmt->getSingleDecl()); if (!var->hasInit()) continue; Expr *expr = var->getInit(); if (!isa<ImplicitCastExpr>(expr)) continue; ImplicitCastExpr *implicit = cast<ImplicitCastExpr>(expr); if (!isa<CallExpr>(implicit->getSubExpr())) continue; CallExpr *call = cast<CallExpr>(implicit->getSubExpr()); DeclRefExpr *callee = cast<DeclRefExpr>(cast<ImplicitCastExpr>(call->getCallee())->getSubExpr()); if (callee->getNameInfo().getName().getAsString() == "to_pci_dev" || callee->getNameInfo().getName().getAsString() == "pci_get_drvdata") { stmtsToRewrite.push_back(declStmt); } } while (!stmtsToRewrite.empty()) { DeclStmt *stmt = stmtsToRewrite.back(); RW.RemoveText(stmt->getSourceRange()); stmtsToRewrite.pop_back(); } }
virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) { ProgramStateRef state = getReplayWithoutInliningState(Pred, CE); // First, try to inline the call. if (state == 0 && Eng.InlineCall(Dst, CE, Pred)) return; // First handle the return value. StmtNodeBuilder Bldr(Pred, Dst, *Eng.currentBuilderContext); // Get the callee. const Expr *Callee = CE->getCallee()->IgnoreParens(); if (state == 0) state = Pred->getState(); SVal L = state->getSVal(Callee, Pred->getLocationContext()); // Figure out the result type. We do this dance to handle references. QualType ResultTy; if (const FunctionDecl *FD = L.getAsFunctionDecl()) ResultTy = FD->getResultType(); else ResultTy = CE->getType(); if (CE->isLValue()) ResultTy = Eng.getContext().getPointerType(ResultTy); // Conjure a symbol value to use as the result. SValBuilder &SVB = Eng.getSValBuilder(); unsigned Count = Eng.currentBuilderContext->getCurrentBlockCount(); const LocationContext *LCtx = Pred->getLocationContext(); SVal RetVal = SVB.getConjuredSymbolVal(0, CE, LCtx, ResultTy, Count); // Generate a new state with the return value set. state = state->BindExpr(CE, LCtx, RetVal); // Invalidate the arguments. state = Eng.invalidateArguments(state, CallOrObjCMessage(CE, state, LCtx), LCtx); // And make the result node. Bldr.generateNode(CE, Pred, state); }
string NetworkDriverRewriteVisitor::GetSharedStructStrInFunctionBody(Stmt *body, bool doLog) { string shared_struct_str = ""; for (auto i = body->child_begin(), e = body->child_end(); i != e; ++i) { if (isa<DeclStmt>(*i)) { DeclStmt *declStmt = cast<DeclStmt>(*i); if (!declStmt->isSingleDecl() && !isa<VarDecl>(declStmt->getSingleDecl())) continue; VarDecl *varDecl = cast<VarDecl>(declStmt->getSingleDecl()); if (!isa<ValueDecl>(varDecl)) continue; ValueDecl *value = cast<ValueDecl>(varDecl); if (value->getType().getAsString(Context->getPrintingPolicy()) != "struct net_device *") continue; if (!isa<NamedDecl>(varDecl)) continue; if (varDecl->getInit() == 0 || !isa<CallExpr>(varDecl->getInit())) continue; CallExpr *callExpr = cast<CallExpr>(varDecl->getInit()); shared_struct_str = GetSharedStructStr(callExpr); if (shared_struct_str != "") { if (doLog) { Expr *callee = callExpr->getCallee(); ImplicitCastExpr *calleeImplExpr = cast<ImplicitCastExpr>(callee); DeclRefExpr *calleeDeclExpr = cast<DeclRefExpr>(calleeImplExpr->getSubExpr()); DI->getInstance().AddSharedStructInformation("whoop_network_shared_struct", calleeDeclExpr->getNameInfo().getAsString()); } break; } } else if (isa<BinaryOperator>(*i)) { BinaryOperator *binOp = cast<BinaryOperator>(*i); if (!isa<CallExpr>(binOp->getRHS())) continue; CallExpr *callExpr = cast<CallExpr>(binOp->getRHS()); shared_struct_str = GetSharedStructStr(callExpr); if (shared_struct_str != "") { if (doLog) { Expr *callee = callExpr->getCallee(); ImplicitCastExpr *calleeImplExpr = cast<ImplicitCastExpr>(callee); DeclRefExpr *calleeDeclExpr = cast<DeclRefExpr>(calleeImplExpr->getSubExpr()); DI->getInstance().AddSharedStructInformation("whoop_network_shared_struct", calleeDeclExpr->getNameInfo().getAsString()); } break; } } } return shared_struct_str; }