I'm trying to create a plugin for gcc that allows you to instrument the prologue and the epilogue of a function.
The instrumentation code is inserted in two functions "instrument_entry" and "instrument_exit". These two functions are written in a file called instrumentation.h, which is included in the source code of the software I want to instrument.in a nutshell, it's very similar to the -finstrument-function
of gcc
Unlike the option provided by gcc, through the plugin, I would like to take the code present in the function "instrument_entry" (I checked and this function contains only one basic block) and insert it in all other prologues of the functions present in the software.
I thought to take the sequence present in the basic block of the function "instrument_entry" and insert it in the first basic block of the function to be instrumented.
This is the code:
static basic_block bb_entry_instr;static unsigned int instrument_functions(function *fun){ std::string func_name = function_name(fun); if(func_name == "instrument_entry"){ basic_block bb; bb = ENTRY_BLOCK_PTR_FOR_FN(fun); bb = bb->next_bb; bb_entry_instr = bb; std::cout << "Instrumentation code found! "<< std::endl; } if(func_name != "instrument_entry"&& func_name != "instrument_exit"){ basic_block bb; bb = ENTRY_BLOCK_PTR_FOR_FN(fun); bb = bb->next_bb; gimple_stmt_iterator gsi = gsi_start_bb(bb); gsi_insert_seq_before(&gsi, bb_seq(bb_entry_instr), GSI_NEW_STMT); }} // end of instrument_functions()
bb_entry_instr
is the basic block of the "instrument_entry" function
The pass I created for gcc is called after the "cfg" pass:
namespace { const pass_data instrumentation_pass_data = { GIMPLE_PASS,"instr_pass2", /* name */ OPTGROUP_NONE, /* optinfo_flags */ TV_NONE, /* tv_id */ PROP_gimple_any, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ 0 /* todo_flags_finish */ }; struct instrumentation_pass : gimple_opt_pass { instrumentation_pass(gcc::context *ctx) : gimple_opt_pass(instrumentation_pass_data, ctx){} unsigned int execute(function *fun) { return instrument_functions(fun); } }; }int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version){ ... // plugin_default_version_check struct register_pass_info instr_pass_info; instr_pass_info.pass = new instrumentation_pass(g); instr_pass_info.reference_pass_name = "cfg"; instr_pass_info.ref_pass_instance_number = 1; instr_pass_info.pos_op = PASS_POS_INSERT_AFTER;}register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &instr_pass_info);
When I try to compile a test program with the plugin, I get this error:
during RTL pass: expandtest_01.c: In function ‘instrument_entry’:test_01.c:13:9: internal compiler error: in get_rtx_for_ssa_name, at tree-outof-ssa.h:62 13 | fgets(name, 0xff, stdin); | ^~~~~~~~~~~~~~~~~~~~~~~~Please submit a full bug report,with preprocessed source if appropriate.See <file:///usr/share/doc/gcc-9/README.Bugs> for instructions.make: *** [Makefile:14: test] Error 1
Can somebody help me?