Esempio n. 1
0
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;
}