예제 #1
0
파일: Utils.cpp 프로젝트: KDE/clazy
std::vector<CallExpr *> Utils::callListForChain(CallExpr *lastCallExpr)
{
    if (!lastCallExpr)
        return {};

    const bool isOperator = isa<CXXOperatorCallExpr>(lastCallExpr);

    vector<CallExpr *> callexprs = { lastCallExpr };
    Stmt *s = lastCallExpr;
    do {
        const int childCount = std::distance(s->child_begin(), s->child_end());
        if (isOperator && childCount > 1) {
            // for operator case, the chained call childs are in the second child
            s = *(++s->child_begin());
        } else {
            s = childCount > 0 ? *s->child_begin() : nullptr;
        }

        if (s) {
            CallExpr *callExpr = dyn_cast<CallExpr>(s);
            if (callExpr && callExpr->getCalleeDecl()) {
                callexprs.push_back(callExpr);
            } else if (MemberExpr *memberExpr = dyn_cast<MemberExpr>(s)) {
                if (isa<FieldDecl>(memberExpr->getMemberDecl()))
                    break; // accessing a public member via . or -> breaks the chain
            }
        }
    } while (s);

    return callexprs;
}
  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();
    }
  }
예제 #3
0
파일: Utils.cpp 프로젝트: KDE/clazy
const CXXRecordDecl *Utils::recordForMemberCall(CXXMemberCallExpr *call, string &implicitCallee)
{
    implicitCallee.clear();
    Expr *implicitArgument= call->getImplicitObjectArgument();
    if (!implicitArgument) {
        return nullptr;
    }

    Stmt *s = implicitArgument;
    while (s) {
        if (auto declRef = dyn_cast<DeclRefExpr>(s)) {
            if (declRef->getDecl()) {
                implicitCallee = declRef->getDecl()->getNameAsString();
                QualType qt = declRef->getDecl()->getType();
                return qt->getPointeeCXXRecordDecl();
            } else {
                return nullptr;
            }
        } else if (auto thisExpr = dyn_cast<CXXThisExpr>(s)) {
            implicitCallee = "this";
            return thisExpr->getType()->getPointeeCXXRecordDecl();
        } else if (auto memberExpr = dyn_cast<MemberExpr>(s)) {
            auto decl = memberExpr->getMemberDecl();
            if (decl) {
                implicitCallee = decl->getNameAsString();
                QualType qt = decl->getType();
                return qt->getPointeeCXXRecordDecl();
            } else {
                return nullptr;
            }
        }

        s = s->child_begin() == s->child_end() ? nullptr : *(s->child_begin());
    }

    return nullptr;
}
예제 #4
0
bool RewriteUtils::addLocalVarToFunc(const std::string &VarStr,
                                     FunctionDecl *FD)
{
  Stmt *Body = FD->getBody();
  TransAssert(Body && "NULL body for a function definition!");

  std::string IndentStr;
  StmtIterator I = Body->child_begin();

  if (I == Body->child_end())
    IndentStr = DefaultIndentStr;
  else
    IndentStr = getStmtIndentString((*I), SrcManager);

  std::string NewVarStr = "\n" + IndentStr + VarStr;
  SourceLocation StartLoc = Body->getLocStart();
  return !(TheRewriter->InsertTextAfterToken(StartLoc, NewVarStr));
}
    // Deal with all the call expr in the transaction.
    bool VisitCallExpr(CallExpr* TheCall) {
      if (FunctionDecl* FDecl = TheCall->getDirectCallee()) {
        std::bitset<32> ArgIndexs;
        for (FunctionDecl::redecl_iterator RI = FDecl->redecls_begin(),
             RE = FDecl->redecls_end(); RI != RE; ++RI) {
          for (specific_attr_iterator<NonNullAttr>
               I = RI->specific_attr_begin<NonNullAttr>(),
               E = RI->specific_attr_end<NonNullAttr>(); I != E; ++I) {
            NonNullAttr *NonNull = *I;

            // Store all the null attr argument's index into "ArgIndexs".
            for (NonNullAttr::args_iterator i = NonNull->args_begin(),
                 e = NonNull->args_end(); i != e; ++i) {

              // Get the argument with the nonnull attribute.
              const Expr* Arg = TheCall->getArg(*i);

              // Check whether we can get the argument'value. If the argument is
              // not null, then ignore this argument and continue to deal with the
              // next argument with the nonnull attribute.ArgIndexs.set(*i);
              bool Result;
              ASTContext& Context = m_Sema->getASTContext();
              if (Arg->EvaluateAsBooleanCondition(Result, Context) && Result) {
                continue;
              }
              ArgIndexs.set(*i);
            }
            break;
          }
        }

        if (ArgIndexs.any()) {

          // Get the function decl's name.
          std::string FName = getMangledName(FDecl);

          // Store the function decl's name into the vector.
          m_NonNullDeclNames.push_back(FName);

          // Store the function decl's name with its null attr args' indexes
          // into the map.
          m_NonNullArgIndexs.insert(std::make_pair(FName, ArgIndexs));
        }

        // FIXME: For now we will only work/check on declarations that are not
        // deserialized. We want to avoid our null deref transaformer to 
        // deserialize all the contents of a PCH/PCM.
        // We have to think of a better way to find the annotated 
        // declarations, without that to cause too much deserialization.
        Stmt* S = (FDecl->isFromASTFile()) ? 0 : FDecl->getBody();
        if (S) {
          for (Stmt::child_iterator II = S->child_begin(), EE = S->child_end();
               II != EE; ++II) {
            CallExpr* child = dyn_cast<CallExpr>(*II);
            if (child && child->getDirectCallee() != FDecl)
              VisitCallExpr(child);
          }
        }
      }
      return true; // returning false will abort the in-depth traversal.
    }
  bool VisitFunctionDecl(FunctionDecl *f) {
    // Only function definitions (with bodies), not declarations.
    if (f->hasBody()) {
      Stmt *FuncBody = f->getBody();

      // Type name as string
      QualType QT = f->getReturnType();
      std::string TypeStr = QT.getAsString();

      // Function name
      DeclarationName DeclName = f->getNameInfo().getName();
      std::string FuncName = DeclName.getAsString();

      // Add comment before
      std::stringstream SSBefore;
      SSBefore << "// Begin function " << FuncName << " returning " << TypeStr
               << "\n";
      SourceLocation ST = f->getSourceRange().getBegin();
      TheRewriter.InsertText(ST, SSBefore.str(), true, true);

      // And after
      std::stringstream SSAfter;
      SSAfter << "\n// End function " << FuncName;
      ST = FuncBody->getLocEnd().getLocWithOffset(1);
      TheRewriter.InsertText(ST, SSAfter.str(), true, true);
      
      int forCounter=0;
    Stmt::child_iterator CI, CE = FuncBody->child_end();
    for (CI = FuncBody->child_begin(); CI != CE; ++CI) {
      if (*CI != 0) {
        if (isa<ForStmt>(*CI)) 
        {
            forCounter++;
            std::stringstream MarkerBefore;
            std::stringstream MarkerAfter;
            MarkerBefore<<"\nMCPROF_ZONE_ENTER(" << forCounter << ");\n";
            MarkerAfter<<"\nMCPROF_ZONE_EXIT(" << forCounter << ");\n";
            ForStmt *For = cast<ForStmt>(*CI);
            SourceLocation ST = For->getLocStart();
            TheRewriter.InsertText(ST, MarkerBefore.str(), true, false);
            Stmt *ForBody = For->getBody();
            SourceLocation END = ForBody->getLocEnd();
            int offset = Lexer::MeasureTokenLength(END,
                                        TheRewriter.getSourceMgr(),
                                        TheRewriter.getLangOpts()) + 1;

            SourceLocation END1 = END.getLocWithOffset(offset);
            TheRewriter.InsertText(END1, MarkerAfter.str(), true, false);

//          llvm::errs() << " Detected for loop number " << forCounter 
//                       << " in function " << FuncName << "\n";

//             InstrumentStmt(ForBody);

//             Stmt *ForBody = CI->getBody();
//             SourceLocation ST = CI->getLocStart();
//             char *b = sourceManager->getCharacterData(_b)
//             llvm::errs()  << ST << " is location \n";
        }
      }
    }

    }

    return true;
  }
  void NetworkDriverRewriteVisitor::CreateCheckerFunction(FunctionDecl* funcDecl, string fdFile)
  {
    string device_str;
    Stmt *body = funcDecl->getBody();

    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 *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;

      NamedDecl *named = cast<NamedDecl>(varDecl);
      device_str = named->getNameAsString();
      break;
    }

    if (device_str.empty())
      return;

    string shared_struct_str = GetSharedStructStrInFunctionBody(body, true);
    if (shared_struct_str.empty())
      return;

    FileID fileId = Context->getSourceManager().getFileID(funcDecl->getLocation());
    SourceLocation loc = Context->getSourceManager().getLocForEndOfFile(fileId);

    RW.InsertText(loc, "\n", true, true);
    RW.InsertText(loc, "void whoop$checker(", true, true);

    map<string, string> func_params;
    for (auto i = funcDecl->param_begin(), e = funcDecl->param_end(); i != e; ++i)
    {
      ValueDecl *paramVal = cast<ValueDecl>(*i);
      NamedDecl *paramNam = cast<NamedDecl>(*i);

      string paramType = paramVal->getType().getAsString(Context->getPrintingPolicy());
      string paramName = paramNam->getNameAsString();

      func_params[paramType] = paramName;

      if (i == funcDecl->param_begin())
        RW.InsertText(loc, paramType + " " + paramName + ", ", true, true);
      else
        RW.InsertText(loc, paramType + " " + paramName, true, true);
    }

    RW.InsertText(loc, ")\n", true, true);
    RW.InsertText(loc, "{\n", true, true);

    RW.InsertText(loc, "\tstruct net_device *dev;\n", true, true);
    RW.InsertText(loc, "\t" + shared_struct_str + "shared;\n", true, true);
    RW.InsertText(loc, "\tdev = alloc_etherdev(sizeof(*shared));\n\n", true, true);

    RW.InsertText(loc, "\tstruct sk_buff *whoop_skb = (struct sk_buff *) malloc(sizeof(struct sk_buff));\n", true, true);
    RW.InsertText(loc, "\tstruct ethtool_wolinfo *whoop_wolinfo = (struct ethtool_wolinfo *) malloc(sizeof(struct ethtool_wolinfo));\n", true, true);
    RW.InsertText(loc, "\tstruct ethtool_cmd *whoop_ecmd = (struct ethtool_cmd *) malloc(sizeof(struct ethtool_cmd));\n", true, true);
    RW.InsertText(loc, "\tstruct ifreq *whoop_ifreq = (struct ifreq *) malloc(sizeof(struct ifreq));\n", true, true);
    RW.InsertText(loc, "\tstruct rtnl_link_stats64 *whoop_rtnlsts64 = (struct rtnl_link_stats64 *) malloc(sizeof(struct rtnl_link_stats64));\n", true, true);
    RW.InsertText(loc, "\tstruct ethtool_regs *whoop_ethtoolregs = (struct ethtool_regs *) malloc(sizeof(struct ethtool_regs));\n", true, true);
    RW.InsertText(loc, "\tstruct ethtool_stats *whoop_ethtoolsts = (struct ethtool_stats *) malloc(sizeof(struct ethtool_stats));\n", true, true);
    RW.InsertText(loc, "\tstruct ethtool_drvinfo *whoop_ethtooldrvinfo = (struct ethtool_drvinfo *) malloc(sizeof(struct ethtool_drvinfo));\n", true, true);
    RW.InsertText(loc, "\tnetdev_features_t whoop_netdevfeat = NETIF_F_RXCSUM;\n\n", true, true);

    RW.InsertText(loc, "\tint whoop_int = __SMACK_nondet();\n", true, true);
    RW.InsertText(loc, "\t__SMACK_code(\"assume @ >= @;\", whoop_int, 0);\n\n", true, true);

    auto entry_points = DI->getInstance().GetEntryPoints();
    for(auto i = entry_points.rbegin(); i != entry_points.rend(); i++)
    {
      string entry_point_call;
      entry_point_call = "" + i->first + "(";

      if (find(i->second.begin(), i->second.end(), "struct net_device *") == i->second.end())
        entry_point_call += device_str + ", ";

      for(auto j = i->second.begin(); j != i->second.end(); j++)
      {
        if (*j == "struct net_device *")
          entry_point_call += device_str + ", ";
        else if (*j == "struct pci_dev *")
          entry_point_call += func_params["struct pci_dev *"] + ", ";
        else if (*j == "struct device *")
          entry_point_call += "&" + func_params["struct pci_dev *"] + "->dev, ";
        else if (*j == "void *")
          entry_point_call += "NULL, ";
        else if (*j == "u64 *")
          entry_point_call += "NULL, ";
        else if (*j == "u8 *")
          entry_point_call += "NULL, ";
        else if (*j == "struct sk_buff *")
          entry_point_call += "whoop_skb, ";
        else if (*j == "struct ethtool_wolinfo *")
          entry_point_call += "whoop_wolinfo, ";
        else if (*j == "struct ethtool_cmd *")
          entry_point_call += "whoop_ecmd, ";
        else if (*j == "struct ifreq *")
          entry_point_call += "whoop_ifreq, ";
        else if (*j == "struct rtnl_link_stats64 *")
          entry_point_call += "whoop_rtnlsts64, ";
        else if (*j == "struct ethtool_regs *")
          entry_point_call += "whoop_ethtoolregs, ";
        else if (*j == "struct ethtool_stats *")
          entry_point_call += "whoop_ethtoolsts, ";
        else if (*j == "struct ethtool_drvinfo *")
          entry_point_call += "whoop_ethtooldrvinfo, ";
        else if (*j == "netdev_features_t")
          entry_point_call += "whoop_netdevfeat, ";
        else if (*j == "int")
          entry_point_call += "whoop_int, ";
        else if (*j == "u32")
          entry_point_call += "whoop_int, ";
        else
          entry_point_call += *j + ", ";
      }

      entry_point_call.resize(entry_point_call.size() - 2);

      RW.InsertText(loc, "\t" + entry_point_call + ");\n", true, true);
    }

    RW.InsertText(loc, "}", true, true);
  }
예제 #8
0
bool FindGPUMacro::VisitForStmt(ForStmt *fstmt) {
 
  Stmt *body = fstmt->getBody();

  analyze_data_struct(body);

  int tx = 1, ty = 1, tz = 1 , bx = 1, by = 1, bz = 1, gpu_time = 0, cpu_time = 0, instanceNum = 0;
  for (Stmt::child_iterator it = body->child_begin(), eit = body->child_end();
      it != eit;
      it++) {

    Stmt *s = *it; 

    if (DeclStmt *ds = dyn_cast<DeclStmt>(s)){
      if (VarDecl *vd = dyn_cast<VarDecl>(ds->getSingleDecl())){
        string className = vd->getTypeSourceInfo()->getType().getBaseTypeIdentifier()->getName();
				if (className == "profile_time") {
	 				if (CXXConstructExpr *ce = dyn_cast<CXXConstructExpr>(vd->getInit()->IgnoreImpCasts())) {					 
	 	 				if (MaterializeTemporaryExpr *me = dyn_cast<MaterializeTemporaryExpr>(ce->getArg(0)->IgnoreImpCasts())) {
							if (CXXTemporaryObjectExpr *co = dyn_cast<CXXTemporaryObjectExpr>(me->GetTemporaryExpr()->IgnoreImpCasts())) {

								IntegerLiteral *x = dyn_cast<IntegerLiteral>(co->getArg(0));
								IntegerLiteral *y = dyn_cast<IntegerLiteral>(co->getArg(1));
	  						IntegerLiteral *z = dyn_cast<IntegerLiteral>(co->getArg(2));

								instanceNum = x->getValue().getSExtValue();
	  						gpu_time = y->getValue().getSExtValue();
	  						cpu_time = z->getValue().getSExtValue();
	 						}	 
						}
				}
		}	
		
    if (className == "sc_gpu_thread_hierarchy") {   
    	if (CXXConstructExpr *ce = dyn_cast<CXXConstructExpr>(vd->getInit()->IgnoreImpCasts())) {
				if (MaterializeTemporaryExpr *me = dyn_cast<MaterializeTemporaryExpr>(ce->getArg(0)->IgnoreImpCasts())) {
					if (CXXTemporaryObjectExpr *co = dyn_cast<CXXTemporaryObjectExpr>(me->GetTemporaryExpr()->IgnoreImpCasts())) {
          	IntegerLiteral *x = dyn_cast<IntegerLiteral>(co->getArg(1)); 
          	IntegerLiteral *y = dyn_cast<IntegerLiteral>(co->getArg(2));
          	IntegerLiteral *z = dyn_cast<IntegerLiteral>(co->getArg(3)); 
						IntegerLiteral *w = dyn_cast<IntegerLiteral>(co->getArg(4));
          	instanceNum = x->getValue().getSExtValue();
						tx = x->getValue().getSExtValue();
          	ty = y->getValue().getSExtValue();
          	tz = z->getValue().getSExtValue();          
         	}        
        }
			}
		}
    if (className == "sc_gpu_block_hierarchy") {   
    	if (CXXConstructExpr *ce = dyn_cast<CXXConstructExpr>(vd->getInit()->IgnoreImpCasts())) {
				if (MaterializeTemporaryExpr *me = dyn_cast<MaterializeTemporaryExpr>(ce->getArg(0)->IgnoreImpCasts())) {
					if (CXXTemporaryObjectExpr *co = dyn_cast<CXXTemporaryObjectExpr>(me->GetTemporaryExpr()->IgnoreImpCasts())) {
          	IntegerLiteral *x = dyn_cast<IntegerLiteral>(co->getArg(1)); 
          	IntegerLiteral *y = dyn_cast<IntegerLiteral>(co->getArg(2));
          	IntegerLiteral *z = dyn_cast<IntegerLiteral>(co->getArg(3)); 
          	IntegerLiteral *w = dyn_cast<IntegerLiteral>(co->getArg(4));
				  
						instanceNum = x->getValue().getSExtValue();	
						bx = y->getValue().getSExtValue();
          	by = z->getValue().getSExtValue();
          	bz = w->getValue().getSExtValue();           
         			}        
        		}
					}
				}
  		}
		}
	
		//_os <<"\n gpu_time : " <<gpu_time<<" cpu_time : " <<cpu_time<<" instanceNum : " <<_instanceNum<<" " <<instanceNum;
  	if (tx && ty && tz && bx && by && bz && gpu_time && cpu_time && (_instanceNum == instanceNum)) {
			//_os <<"\n instance num : " <<_instanceNum<<" " <<instanceNum;
  	  GPUMacro *gm = new GPUMacro(bx, by, bz, tx, ty, tz, gpu_time, cpu_time);
			//_os <<"\n for stmt : " <<fstmt;
			forStmtInstanceIdPairType forStmtInstanceId = make_pair(_instanceNum, fstmt);
			_forStmtGPUMacroMap.insert(forStmtGPUMacroPairType(forStmtInstanceId, gm)); 			
			break;
		}
	}
  return true;
}