I am hacking in the gcc code and come to a point where I cant come any further: I want to expand the "-finstrument-functions" to create a dynamic dump function in the background, instead of calling a fixed __cyg_profile_func_enter/exit I.e: if I have f1(int a,int b) { } I would like to create a dynamic function _trace_f1(int a,int b) { __trace_int(a); __trace_int(b); } I apended the code I use below. the function gimplify_create_trace_func (shown below) is called from: gimplify_function_tree (tree fndecl)-> gimplify_create_trace_func(fndecl,"_trace_f1"); These are the steps I do in gimplify_create_trace_func(): 1. Build function definition for _trace_f1: build_decl (FUNCTION_DECL, get_identifier (n), fntyp); 2. Declare function parameters for "a" and "b": build_decl (PARM_DECL, get_identifier (argname), TREE_TYPE(param)); 3. Output each parameter: build_function_call_expr (trace , thisparaml ); where "thisparaml" is "a" or "b" and trace is a external function ref repending on the typ: The problem now is this: The assembler output is: _trace_f1: pushl %ebp movl %esp, %ebp subl $8, %esp movl $0, (%esp) call __trace__int movl $0, (%esp) call __trace__int leave ret whereas I would expect: _trace_f1: pushl %ebp movl %esp, %ebp subl $8, %esp movl 8(%ebp), %eax movl %eax, (%esp) call __trace__int movl 12(%ebp), %eax movl %eax, (%esp) call __trace__int ... Can anyone tell me what I am doing wrong. The compiler oututs __trace__int(0) instead of using the function parameter as an argument: _trace_f1(int a,int b) { __trace_int(a); ... Or can somebody point me to a codesnippet in gcc that does the same (create functions dynamically on the fly) so I can take a look and learn... Greetings ----------- create a dynamic funtion ------------------------ void gimplify_create_trace_func (tree fndecl, char *n) { int i; tree body = NULL; tree ir, prev, param, fn, fntyp, parm, tdef, argstyp = NULL_TREE, argslist = NULL_TREE ; char argname[256]; /* create function type */ for (i = 0,param = DECL_ARGUMENTS (fndecl); param ; i++,param = TREE_CHAIN (param)) { argstyp = tree_cons (NULL_TREE, TREE_TYPE(param), argstyp); } if (argstyp == NULL_TREE) argstyp = void_list_node; else { tree last = argstyp; argstyp = nreverse (argstyp); TREE_CHAIN (last) = void_list_node; } fntyp = build_function_type (void_type_node, argstyp); /* build function prototype */ fn = build_decl (FUNCTION_DECL, get_identifier (n), fntyp); pushdecl (fn); prev = current_function_decl; current_function_decl = fn; push_scope(); declare_parm_level (); /* build function argument list */ for (i = 0,param = DECL_ARGUMENTS (fndecl); param ; i++,param = TREE_CHAIN (param)) { tree argdecl; sprintf(argname,"a%d",i); argdecl = build_decl (PARM_DECL, get_identifier (argname), TREE_TYPE(param)); argslist = chainon (argdecl, argslist); printf("decl:%x\n",argdecl); pushdecl(argdecl); DECL_ARTIFICIAL(argdecl) = 1; /* if (DECL_NAME (argdecl)) { */ /* bind (DECL_NAME (decl), decl, current_scope, */ /* /\*invisible=*\/false, /\*nested=*\/false); */ /* } */ DECL_CONTEXT (argdecl) = fn; } argslist = nreverse (argslist); DECL_ARGUMENTS (fn) = argslist; ir = build_decl (RESULT_DECL, NULL_TREE, void_type_node); DECL_CONTEXT (ir) = fn; DECL_ARTIFICIAL (ir) = 1; DECL_IGNORED_P (ir) = 1; DECL_RESULT (fn) = ir; TREE_STATIC (fn) = 0; TREE_USED (fn) = 1; DECL_ARTIFICIAL (fn) = 1; DECL_IGNORED_P (fn) = 1; DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fn) = 1; allocate_struct_function (fn); if (tracetype == trace_out_none) { DECL_SAVED_TREE (fn) = build_empty_stmt(); } else if (tracetype == trace_out_all) { tree thisp, stmts; stmts = alloc_stmt_list(); /* output one call for each argument */ for (i = 0,thisp = argslist, param = DECL_ARGUMENTS (fndecl); param ; i++,thisp = TREE_CHAIN (thisp), param = TREE_CHAIN (param)) { tree trace, thisparaml = NULL, x; char *name = gen_aux_info_type_str_canonical(TREE_TYPE(param)); name = concat("__trace__", name, NULL); fprintf(stderr, "typ: \"%s\" \n", name); trace = build_function_type_list (void_type_node, TREE_TYPE(thisp), NULL); trace = build_decl (FUNCTION_DECL, get_identifier (name), trace); TREE_PUBLIC (trace) = 1; DECL_EXTERNAL (trace) = 1; thisparaml = tree_cons (NULL, thisp, thisparaml); x = build_function_call_expr (trace , thisparaml ); dump_node(x, 0, stderr); append_to_statement_list (x, &stmts); } DECL_SAVED_TREE (fn) = stmts /*body*/; } TREE_PUBLIC (fn) = 1; /*! targetm.have_ctors_dtors;*/ DECL_UNINLINABLE (fn) = 1; DECL_INITIAL (fn) = make_node (BLOCK); TREE_USED (DECL_INITIAL (fn)) = 1; pop_scope(); /* output function */ gimplify_function_tree (fn); if (cgraph_global_info_ready) { tree_lowering_passes (fn); tree_rest_of_compilation (fn); } else cgraph_finalize_function (fn, 0); current_function_decl = prev; }