//---------------------------------------------------------------------- // trace a function call. // adjuct the stack, determine the execution flow // returns: // true - the called function returns to the caller // false - the called function doesn't return to the caller static bool handle_function_call(ea_t callee) { bool funcflow = true; if ( !func_does_return(callee) ) funcflow = false; if ( should_trace_sp() ) { func_t *caller = get_func(cmd.ea); if ( func_contains(caller, cmd.ea+cmd.size) ) { sval_t delta = calc_func_call_delta(callee); if ( delta != 0 ) add_stkpnt(delta); } } return funcflow; }
//-------------------------------------------------------------------------- int callgraph_t::walk_func(func_t *func, funcs_walk_options_t *opt, int level) { // add a node for this function ea_t func_start = func->startEA; int id = add(func_start); func_item_iterator_t fii; for ( bool fi_ok=fii.set(func); fi_ok; fi_ok=fii.next_code() ) { xrefblk_t xb; for ( bool xb_ok = xb.first_from(fii.current(), XREF_FAR); xb_ok && xb.iscode; xb_ok = xb.next_from() ) { func_t *f = get_func(xb.to); if ( f == NULL ) continue; int id2; if ( !visited(f->startEA, &id2) ) { if ( func_contains(func, xb.to) ) continue; bool skip = false; if ( opt != NULL ) { skip = // skip lib funcs? (((f->flags & FUNC_LIB) != 0) && ((opt->flags & FWO_SKIPLIB) != 0)) // max recursion is off, and limit is reached? || ( ((opt->flags & FWO_RECURSE_UNLIM) == 0) && (level > opt->recurse_limit) ); } if ( skip ) id2 = add(f->startEA); else id2 = walk_func(f, opt, level+1); } create_edge(id, id2); } } return id; }