void generate_CALL( quad* quad ){ quad->taddress = nextInstructionLabel(); ///print///printf("QUAD FUNC NUM: %d",quad->line ); instruction *t = malloc( sizeof( instruction ) ); t->result = malloc(sizeof(vmarg)); t->opcode = call_v; make_operand( quad->result, t->result ); reset_operand(t->arg1); reset_operand(t->arg2); t->srcLine = quad->line; t->result->val = FindFunctionUser((quad->result->sym)->name,deepestFunctionScope); if (t->result->val == -1){ if(isLibFunction((quad->result->sym)->name)){ int check = FindLibFunction((quad->result->sym)->name); if (check == -1){ instruction *t1 =(instruction *) InitInstruction(); expr * e = malloc(sizeof(expr)); e->type = libraryfunc_e; e->sym =createS( (quad->result->sym)->name, 0, 0, (quad->result->sym)->name, 0, 0, "lib_func", 1,currscopespace(),currscopeoffset()); make_operand(e,t1->arg1); } t->result->val = FindLibFunction((quad->result->sym)->name); t->result->type = libfunc_a; emitVmarg( t ); } } else { emitVmarg( t ); } return; }
///search the function body for call-log pairs void FindPatternVisitor::travelStmt(Stmt *stmt, Stmt *father){ if(!stmt || !father) return; ///Function return error (include Invalid input check) ///find if(foo()), stmt is located in the condexpr of ifstmt if(IfStmt *ifStmt = dyn_cast<IfStmt>(father)){ if(ifStmt->getCond() == stmt){ if(CallExpr *callExpr = searchCall(stmt)){ if(isLibFunction(callExpr)) searchLog(callExpr, father); } } } ///find switch(foo()), stmt is located in the condexpr of switchstmt if(SwitchStmt *switchStmt = dyn_cast<SwitchStmt>(father)){ if(switchStmt->getCond() == stmt){ if(CallExpr *callExpr = searchCall(stmt)){ if(isLibFunction(callExpr)) searchLog(callExpr, father); } } } ///find 'ret = foo()', when stmt = 'BinaryOperator', op == '=' and RHS == 'callexpr' if(BinaryOperator *binaryOperator = dyn_cast<BinaryOperator>(stmt)){ if(binaryOperator->getOpcode() == BO_Assign){ if(Expr *expr = binaryOperator->getRHS()){ expr = expr->IgnoreImpCasts(); expr = expr->IgnoreImplicit(); expr = expr->IgnoreParens(); if(CallExpr *callExpr = dyn_cast<CallExpr>(expr)){ if(isLibFunction(callExpr)){ bool isYoungBrother = false; for(Stmt::child_iterator bro = father->child_begin(); bro != father->child_end(); ++bro){ if(Stmt *brother = *bro){ if(brother == stmt){ isYoungBrother = true; continue; } if(isYoungBrother == false){ continue; } searchLog(callExpr, brother); break; } } } } } } } ///Unexpected cases falling into default if(SwitchStmt *switchStmt = dyn_cast<SwitchStmt>(stmt)){ SwitchCase *switchCase = switchStmt->getSwitchCaseList(); while(1){ if(!switchCase) break; if(DefaultStmt *defaultStmt = dyn_cast<DefaultStmt>(switchCase)){ searchLog("SwitchDefault", defaultStmt); break; } switchCase = switchCase->getNextSwitchCase(); } } ///Failed memory safety check if(BinaryOperator *binaryOperator = dyn_cast<BinaryOperator>(stmt)){ if(binaryOperator->getOpcode() == BO_Assign){ if(Expr *expr = binaryOperator->getRHS()){ expr = expr->IgnoreImpCasts(); expr = expr->IgnoreImplicit(); expr = expr->IgnoreParens(); if(CallExpr *callExpr = dyn_cast<CallExpr>(expr)){ string returnName = expr2str(binaryOperator->getLHS()); bool isYoungBrother = false; for(Stmt::child_iterator bro = father->child_begin(); bro != father->child_end(); ++bro){ if(Stmt *brother = *bro){ if(brother == stmt){ isYoungBrother = true; continue; } if(isYoungBrother == false){ continue; } if(IfStmt *ifStmt = dyn_cast<IfStmt>(brother)){ string ifCond = expr2str(ifStmt->getCond()); if(ifCond.find(returnName) != string::npos && (ifCond.find("null") != string::npos || ifCond.find("NULL") != string::npos)) searchLog(callExpr, brother); } break; } } } } } } for(Stmt::child_iterator it = stmt->child_begin(); it != stmt->child_end(); ++it){ if(Stmt *child = *it) travelStmt(child, stmt); } return; }