How to insert functions?

Hugh Leather hughleat@hotmail.com
Tue Apr 22 12:28:00 GMT 2008


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_TREE, NULL_TREE, 
NULL_TREE );
   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;
}




More information about the Gcc mailing list