How to insert a new function in plugin?

时彦辉 shiyanhui@qiyi.com
Tue Aug 20 12:41:00 GMT 2019


Hi,

I want to insert a new function `test_fn` in plugin and call it in `main`, but got `undefined reference to `test_fn’ in `ld`.  Could you please give some help? Thanks.

Here is the example code,

//====================== plugin.c

#include "gcc-plugin.h"
#include "plugin-version.h"
#include "tree.h"
#include "tree-iterator.h"
#include "toplev.h"
#include "c-family/c-common.h"
#include "cgraph.h"
#include "langhooks.h"

int plugin_is_GPL_compatible = 1;

// this example is from gcc/function-tests.c. The built function is 
// 
//      int test_fn (void) { return 42; }
//
static tree build_fn() {
  auto_vec<tree> param_types;
  tree fn_type = build_function_type_array(
      integer_type_node, param_types.length(), param_types.address());
  tree fndecl = build_fn_decl("test_fn", fn_type);
  TREE_PUBLIC(fndecl) = 1;

  tree retval =
      build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, integer_type_node);
  DECL_ARTIFICIAL(retval) = 1;
  DECL_IGNORED_P(retval) = 1;
  DECL_RESULT(fndecl) = retval;
  DECL_CONTEXT(retval) = fndecl;

  /* Create a BIND_EXPR, and within it, a statement list.  */
  tree stmt_list = alloc_stmt_list();
  tree_stmt_iterator stmt_iter = tsi_start(stmt_list);
  tree block = make_node(BLOCK);
  tree bind_expr = build3(BIND_EXPR, void_type_node, NULL, stmt_list, block);

  tree modify_retval = build2(MODIFY_EXPR, integer_type_node, retval,
                              build_int_cst(integer_type_node, 42));
  tree return_stmt = build1(RETURN_EXPR, integer_type_node, modify_retval);
  tsi_link_after(&stmt_iter, return_stmt, TSI_CONTINUE_LINKING);

  DECL_INITIAL(fndecl) = block;
  BLOCK_SUPERCONTEXT(block) = fndecl;

  /* how to add to function? the following appears to be how to
     set the body of a fndecl: */
  DECL_SAVED_TREE(fndecl) = bind_expr;

  /* Ensure that locals appear in the debuginfo.  */
  BLOCK_VARS(block) = BIND_EXPR_VARS(bind_expr);

  allocate_struct_function(fndecl, false);
  announce_function(fndecl);
  c_determine_visibility(fndecl);
  c_genericize(fndecl);
  cgraph_node::finalize_function(fndecl, true);

  return fndecl;
}

void on_start_parse_function(void *gcc_data, void *user_data) {
    build_fn();
}

int plugin_init(struct plugin_name_args *plugin_info,
                struct plugin_gcc_version *version) {
  if (!plugin_default_version_check(version, &gcc_version)) {
    return 1;
  }

  register_callback(NULL, PLUGIN_START_PARSE_FUNCTION, on_start_parse_function,
                    NULL);
  return 0;
}

// =================== main.c

int main() {
    test_fn();  // error: `undefined reference to `test_fn’` in ld
}




More information about the Gcc-help mailing list