virtual void visit(SgNode* n) { SgReturnStmt* rs = isSgReturnStmt(n); if (rs) { // std::cout << "Converting return statement " << rs->unparseToString(); // std::cout << " into possible assignment to " << where_to_write_answer->unparseToString(); // std::cout << " and jump to " << label->get_name().getString() << std::endl; SgExpression* return_expr = rs->get_expression(); SgBasicBlock* block = SageBuilder::buildBasicBlock(); // printf ("Building IR node #1: new SgBasicBlock = %p \n",block); if (return_expr) { SgExpression* assignment = generateAssignmentMaybe(where_to_write_answer,return_expr); if (where_to_write_answer) where_to_write_answer->set_parent(assignment); if (return_expr != assignment) return_expr->set_parent(assignment); SgStatement* assign_stmt = SageBuilder::buildExprStatement(assignment); SageInterface::appendStatement(assign_stmt, block); } // block->get_statements().push_back(new SgGotoStatement(SgNULL_FILE, label)); SgGotoStatement* gotoStatement = new SgGotoStatement(SgNULL_FILE, label); gotoStatement->set_endOfConstruct(SgNULL_FILE); ROSE_ASSERT(n->get_parent() != NULL); SageInterface::appendStatement(gotoStatement, block); isSgStatement(n->get_parent())->replace_statement(rs, block); block->set_parent(n->get_parent()); ROSE_ASSERT(gotoStatement->get_parent() != NULL); } }
/** Makes a CFG edge, adding appropriate labels. */ void makeEdge(SgAsmInstruction* from, SgAsmInstruction* to, const AuxiliaryInformation* info, vector<CFGEdge>& result) { #if 0 SgAsmNode* fromNode = from.getNode(); unsigned int fromIndex = from.getIndex(); SgAsmNode* toNode = to.getNode(); unsigned int toIndex = to.getIndex(); #if 0 // Exit early if the edge should not exist because of a control flow discontinuity if (fromIndex == 1 && (isSgGotoStatement(fromNode) || isSgBreakStmt(fromNode) || isSgContinueStmt(fromNode))) { return; } if (isSgReturnStmt(fromNode) && toNode == fromNode->get_parent()) { SgReturnStmt* rs = isSgReturnStmt(fromNode); if (fromIndex == 1 || fromIndex == 0 && !rs->get_expression()) return; } if (fromIndex == 1 && isSgSwitchStatement(fromNode) && isSgSwitchStatement(fromNode)->get_body() == toNode) return; #endif #endif // Create the edge result.push_back(CFGEdge(CFGNode(from, info), CFGNode(to, info), info)); }
bool TaintAnalysis::transfer(const Function& func, const DataflowNode& node_, NodeState& state, const std::vector<Lattice*>& dfInfo) { static size_t ncalls = 0; if (debug) { *debug <<"TaintAnalysis::transfer-" <<++ncalls <<"(func=" <<func.get_name() <<",\n" <<" node={" <<StringUtility::makeOneLine(node_.toString()) <<"},\n" <<" state={" <<state.str(this, " ") <<",\n" <<" dfInfo[" <<dfInfo.size() <<"]={...})\n"; } SgNode *node = node_.getNode(); assert(!dfInfo.empty()); FiniteVarsExprsProductLattice *prodLat = dynamic_cast<FiniteVarsExprsProductLattice*>(dfInfo.front()); bool modified = magic_tainted(node, prodLat); // some values are automatically tainted based on their name // Process AST nodes that transfer taintedness. Most of these operations have one or more inputs from which a result // is always calculated the same way. So we just gather up the inputs and do the calculation at the very end of this // function. The other operations are handled individually within their "if" bodies. TaintLattice *result = NULL; // result pointer into the taint lattice std::vector<TaintLattice*> inputs; // input pointers into the taint lattice if (isSgAssignInitializer(node)) { // as in "int a = b" SgAssignInitializer *xop = isSgAssignInitializer(node); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop->get_operand()))); inputs.push_back(in1); } else if (isSgAggregateInitializer(node)) { // as in "int a[1] = {b}" SgAggregateInitializer *xop = isSgAggregateInitializer(node); const SgExpressionPtrList &exprs = xop->get_initializers()->get_expressions(); for (size_t i=0; i<exprs.size(); ++i) { varID in_id = SgExpr2Var(exprs[i]); TaintLattice *in = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in_id)); inputs.push_back(in); } } else if (isSgInitializedName(node)) { SgInitializedName *xop = isSgInitializedName(node); if (xop->get_initializer()) { varID in1_id = SgExpr2Var(xop->get_initializer()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } } else if (isSgValueExp(node)) { // numeric and character constants SgValueExp *xop = isSgValueExp(node); result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop))); if (result) modified = result->set_vertex(TaintLattice::VERTEX_UNTAINTED); } else if (isSgAddressOfOp(node)) { // as in "&x". The result taintedness has nothing to do with the value in x. /*void*/ } else if (isSgBinaryOp(node)) { // as in "a + b" SgBinaryOp *xop = isSgBinaryOp(node); varID in1_id = SgExpr2Var(isSgExpression(xop->get_lhs_operand())); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); varID in2_id = SgExpr2Var(isSgExpression(xop->get_rhs_operand())); TaintLattice *in2 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in2_id)); inputs.push_back(in2); if (isSgAssignOp(node)) { // copy the rhs lattice to the lhs lattice (as well as the entire '=' expression result) assert(in1 && in2); modified = in1->meetUpdate(in2); } } else if (isSgUnaryOp(node)) { // as in "-a" SgUnaryOp *xop = isSgUnaryOp(node); varID in1_id = SgExpr2Var(xop->get_operand()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } else if (isSgReturnStmt(node)) { // as in "return a". The result will always be dead, so we're just doing this to get some debugging output. Most // of our test inputs are functions, and the test examines the function's returned taintedness. SgReturnStmt *xop = isSgReturnStmt(node); varID in1_id = SgExpr2Var(xop->get_expression()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } // Update the result lattice (unless dead) with the inputs (unless dead) by using the meedUpdate() method. All this // means is that the new result will be the maximum of the old result and all inputs, where "maximum" is defined such // that "tainted" is greater than "untainted" (and both of them are greater than bottom/unknown). for (size_t i=0; i<inputs.size(); ++i) if (debug) *debug <<"TaintAnalysis::transfer: input " <<(i+1) <<" is " <<lattice_info(inputs[i]) <<"\n"; if (!result && varID::isValidVarExp(node)) { varID result_id(node); // NOTE: constructor doesn't handle all SgExpression nodes, thus the next "if" result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id)); } if (!result && isSgExpression(node)) { varID result_id = SgExpr2Var(isSgExpression(node)); result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id)); } if (result) { for (size_t i=0; i<inputs.size(); ++i) { if (inputs[i]) modified = result->meetUpdate(inputs[i]) || modified; } } if (debug) *debug <<"TaintAnalysis::transfer: result is " <<lattice_info(result) <<(modified?" (modified)":" (not modified)") <<"\n"; return modified; }
ExprSynAttr *examineStatement(SgStatement *stmt, ostream &out) { SgExpression *expr; SgExprStatement *expr_stmt; ExprSynAttr *expr_attr = NULL; ExprSynAttr *attr1 = NULL; stringstream fake; int i; if (NULL == stmt) return NULL; //out << "/* " << stmt->unparseToString() << " */" << endl; switch(stmt->variantT()) { case V_SgExprStatement: { expr_stmt = isSgExprStatement(stmt); expr_attr = examineExpr(expr_stmt->get_expression(), fake); //out << ";"; if (NULL != expr_attr) { expr_attr->output_comments(out); } break; } case V_SgVariableDeclaration: { SgVariableDeclaration *vardecl = isSgVariableDeclaration(stmt); expr_attr = examineVariableDeclaration(vardecl, out); break; } case V_SgBreakStmt: { out << "break;"; expr_attr->code << "break;"; break; } case V_SgContinueStmt: { out << "continue;"; expr_attr->code << "continue;"; break; } case V_SgReturnStmt: { SgReturnStmt *retstmt = isSgReturnStmt(stmt); expr_attr = new ExprSynAttr(); out << "return "; expr = retstmt->get_expression(); if (expr) { attr1 = examineExpr(expr, out); expr_attr->union_tmp_decls(attr1); expr_attr->code << attr1->code.str(); } out << ";"; expr_attr->code << "return "; if (attr1) { expr_attr->result_var = attr1->result_var; expr_attr->code << expr_attr->result_var; } expr_attr->code << ";"; break; } case V_SgForStatement: { stringstream head; head << "for ("; SgForStatement *forstmt = isSgForStatement(stmt); SgStatementPtrList &init_stmt_list = forstmt->get_init_stmt(); SgStatementPtrList::const_iterator init_stmt_iter; for (init_stmt_iter = init_stmt_list.begin(); init_stmt_iter != init_stmt_list.end(); init_stmt_iter++) { stmt = *init_stmt_iter; if (init_stmt_iter != init_stmt_list.begin()) head << ", "; expr_stmt = isSgExprStatement(stmt); if (expr_stmt) examineExpr(expr_stmt->get_expression(), head); } head << "; "; expr_stmt = isSgExprStatement(forstmt->get_test()); if (expr_stmt) examineExpr(expr_stmt->get_expression(), head); head << "; "; expr = forstmt->get_increment(); examineExpr(expr, head); head << ")" << endl; /* Loop body */ stmt = forstmt->get_loop_body(); expr_attr = examineStatement(stmt, fake); attr1 = new ExprSynAttr(); attr1->code << head.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "{" << endl; } expr_attr->output_tmp_decls(attr1->code); attr1->code << expr_attr->code.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "}" << endl; } delete expr_attr; expr_attr = attr1; attr1 = NULL; out << head.str(); out << fake.str(); break; } case V_SgBasicBlock: { SgScopeStatement *scope = isSgScopeStatement(stmt); expr_attr = examineScopeStatement(scope, "scope", out); break; } case V_SgIfStmt: { stringstream head; SgIfStmt *ifstmt = isSgIfStmt(stmt); head << "if ("; stmt = ifstmt->get_conditional(); expr_stmt = isSgExprStatement(stmt); if (expr_stmt) { attr1 = examineExpr(expr_stmt->get_expression(), head); if (attr1 != NULL) delete attr1; } head << ")" << endl; out << head.str(); /* True body */ stmt = ifstmt->get_true_body(); expr_attr = examineStatement(stmt, fake); attr1 = new ExprSynAttr(); attr1->code << head.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "{" << endl; } expr_attr->output_tmp_decls(attr1->code); attr1->code << expr_attr->code.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "}" << endl; } delete expr_attr; expr_attr = attr1; attr1 = NULL; out << head.str(); out << fake.str(); /* False body */ stmt = ifstmt->get_false_body(); if (stmt) { out << endl << "else" << endl; expr_attr->code << endl << "else" << endl; attr1 = examineStatement(stmt, out); if (!isSgScopeStatement(stmt)) { expr_attr->code << "{" << endl; } attr1->output_tmp_decls(expr_attr->code); expr_attr->code << attr1->code.str(); if (!isSgScopeStatement(stmt)) { expr_attr->code << "}" << endl; } } break; } case V_SgWhileStmt: { stringstream head; SgWhileStmt *whilestmt = isSgWhileStmt(stmt); expr_stmt = isSgExprStatement(whilestmt->get_condition()); head << "while ("; if (expr_stmt) { attr1 = examineExpr(expr_stmt->get_expression(), head); if (NULL != attr1) delete attr1; } out << head.str() << ")" << endl; head << ")" << endl; if (!isSgScopeStatement(stmt)) { head << "{" << endl; } expr_attr = new ExprSynAttr(); expr_attr->code << head.str(); /* Loop Body */ stmt = whilestmt->get_body(); attr1 = examineStatement(stmt, out); attr1->output_tmp_decls(expr_attr->code); expr_attr->code << attr1->code.str(); if (!isSgScopeStatement(stmt)) { expr_attr->code << "}" << endl; } delete attr1; break; } case V_SgDoWhileStmt: { stringstream head; SgDoWhileStmt *dowhilestmt = isSgDoWhileStmt(stmt); expr_stmt = isSgExprStatement(dowhilestmt->get_condition()); stmt = dowhilestmt->get_body(); out << "do"; head << "do" << endl; if (!isSgScopeStatement(stmt)) { head << "{" << endl; } expr_attr = new ExprSynAttr(); expr_attr->code << head.str(); attr1 = examineStatement(stmt, out); attr1->output_tmp_decls(expr_attr->code); expr_attr->code << attr1->code.str(); if (!isSgScopeStatement(stmt)) { expr_attr->code << "}" << endl; } expr_attr->code << " while ("; delete attr1; out << " while ("; head.str(""); if (expr_stmt) { attr1 = examineExpr(expr_stmt->get_expression(), head); delete attr1; out << head.str(); expr_attr->code << head.str(); } out << ");" << endl; expr_attr->code << ");" << endl; break; } } return expr_attr; }
std::string getSgStatement(SgStatement* stat) { VariantT var = stat->variantT(); std::string statStr = ""; if (isSgDeclarationStatement(stat)) { getSgDeclarationStatement(isSgDeclarationStatement(stat)); } else if (isSgScopeStatement(stat)) { getSgScopeStatement(isSgScopeStatement(stat)); } else if (isSgIOStatement(stat)) { statStr = getSgIOStatement(isSgIOStatement(stat)); } else { switch (var) { case V_SgAllocateStatement: { std::cout << "SgAllocateStatement is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgArithmeticIfStatement: { std::cout << "SgArithmeticIfStatement is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgAssertStmt: { std::cout << "SgAssertStmt is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgAssignedGotoStatement: { std::cout << "SgAssignedGotoStatement is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgAssignStatement: { std::cout << "SgAssignStatement is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgBreakStmt: { std::cout << "SgBreakStmt is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgCaseOptionStmt: { std::cout << "SgCaseOptionStmt is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgCatchStatementSeq: { std::cout << "SgCatchStatementSeq is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgComputedGotoStatement: { std::cout << "SgComputedGotoStatement is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgContinueStmt: { std::cout << "SgContinueStmt is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgDeallocateStatement: { std::cout << "SgDeallocateStatement is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgDefaultOptionStmt: { std::cout << "SgDefaultOptionStmt is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgExprStatement: { statStr = getSgExprStatement(isSgExprStatement(stat)); break; } case V_SgForInitStatement: { std::cout << "SgForInitStatement is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgFunctionTypeTable: { std::cout << "SgFunctionTypeTable is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgGotoStatement: { std::cout << "SgGotoStatement is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgLabelStatement: { std::cout << "SgLabelStatement is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgReturnStmt: { SgReturnStmt* ret = isSgReturnStmt(stat); SgExpression* retExp = ret->get_expression(); std::string retExpStr = getSgExpressionString(retExp); statStr = "; return statement not yet linked to function\n ;" + retExpStr + "\n"; break; } case V_SgSequenceStatement: { std::cout << "SgSequenceStatement is not yet implemented" << std::endl; ; ROSE_ASSERT(false); break; } case V_SgPassStatement: { std::cout << "SgPassStatement is not yet implemented" << std::endl; ; ROSE_ASSERT(false); break; } case V_SgNullStatement: { std::cout << "SgNullStatement is not yet implemented" << std::endl; ; ROSE_ASSERT(false); break; } case V_SgNullifyStatement: { std::cout << "SgNullifyStatement is not yet implemented" << std::endl; ; ROSE_ASSERT(false); break; } case V_SgExecStatement: { std::cout << "SgExecStatement is not yet implemented" << std::endl; ; ROSE_ASSERT(false); break; } case V_SgElseWhereStatement: { std::cout << "SgElseWhereStatement is not yet implemented" << std::endl; ; ROSE_ASSERT(false); break; } case V_SgScopeStatement: { std::cout << "SgScopeStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgDeclarationStatement: { std::cout << "SgDeclarationStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgIOStatement: { std::cout << "SgIOStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgJavaThrowStatement: { std::cout << "SgJavaThrowStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgJavaSynchronizedStatement: { std::cout << "SgJavaSynchronizedStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgOmpBarrierStatement: { std::cout << "SgOmpBarrierStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgOmpBodyStatement: { std::cout << "SgOmpBodyStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgOmpFlushStatement: { std::cout << "SgOmpFlushStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgOmpTaskwaitStatement: { std::cout << "SgOmpTaskwaitStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } default: std::cout << "unknown SgStatement type!: " << stat->class_name() << std::endl; ROSE_ASSERT(false); } } return statStr; }