How to insert functions?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I am trying to add a new destructor function to object files I compile. I'm doing this to instrument programs and then, once the program has finished I want to print out the statistics I've gathered. So, just before pass 'remove_useless_stmts' is called on each function I try to create a static destructor which will print stats for the current function (and obviously, I don't do it on the functions just created).

Below I've put a simpler form, which should work for a one function program. Calling createFnDecl() creates a new function called __my_new_function. It should print "It worked!" when the program exits. Now, with compiler flag -O0, this works just fine, but with -O1 or above it seg faults the compiler.

   Can anyone tell me what I'm doing wrong?

   Cheers,

   Hugh.

static tree createFnBody() {
   tree arg;
   tree argList;
   tree putsFn;
   tree call;
   tree bind;
   char msg[] = "It worked!";

   bind = build3( BIND_EXPR, void_type_node, NULL, NULL, NULL );
   TREE_SIDE_EFFECTS( bind ) = 1;

   putsFn = implicit_built_in_decls[ BUILT_IN_PUTS ];
   arg = build_string_literal( sizeof( msg ) + 1, msg );
   argList = tree_cons( NULL_TREE, arg, NULL_TREE );
     call = build_function_call_expr( putsFn, argList );
append_to_statement_list( call, &BIND_EXPR_BODY( bind ));
   return bind;
}

static tree createFnDecl() {
   tree callTypes;
   tree fnName;
   tree fnDecl;
   tree t;
   struct function* oldCfun = cfun;
fnName = get_identifier( "__my_new_function" );
   callTypes = build_function_type_list( void_type_node, NULL_TREE );
   fnDecl = build_decl( FUNCTION_DECL, fnName, callTypes );
   fnDecl = lang_hooks.decls.pushdecl( fnDecl );

   TREE_STATIC( fnDecl ) = 1;
   TREE_USED( fnDecl ) = 1;
   DECL_ARTIFICIAL( fnDecl ) = 1;
   DECL_IGNORED_P( fnDecl ) = 0;
   TREE_PUBLIC( fnDecl ) = 0;
   DECL_UNINLINABLE( fnDecl ) = 1;
   DECL_EXTERNAL( fnDecl ) = 0;
   DECL_CONTEXT( fnDecl ) = NULL_TREE;
   DECL_INITIAL( fnDecl ) = make_node ( BLOCK );
   DECL_STATIC_DESTRUCTOR( fnDecl ) = 1;
   DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT( fnDecl ) = 1;
t = build_decl( RESULT_DECL, NULL_TREE, void_type_node );
   DECL_ARTIFICIAL( t ) = 1;
   DECL_IGNORED_P( t ) = 1;
   DECL_RESULT( fnDecl ) = t;

   DECL_SAVED_TREE( fnDecl ) = createFnBody();

   allocate_struct_function( fnDecl );
cgraph_add_new_function( fnDecl ); cfun = oldCfun;
   return fnDecl;
}



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux