3

我正在尝试为 gcc 创建一个插件,该插件允许您检测函数的序言和结尾。
检测代码插入到两个函数“instrument_entry”和“instrument_exit”中。这两个函数写在一个名为 instrumentation.h 的文件中,该文件包含在我要检测的软件的源代码中。-finstrument-function简而言之,它与gcc 的非常相似

与 gcc 提供的选项不同,通过插件,我想获取函数“instrument_entry”中存在的代码(我检查过,这个函数只包含一个基本块)并将其插入到函数中存在的所有其他序言中软件。

我想将函数“instrument_entry”的基本块中存在的序列插入到要检测的函数的第一个基本块中。

这是代码:

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是“instrument_entry”函数的基本块

我为 gcc 创建的 pass 在 "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);

当我尝试使用该插件编译测试程序时,出现此错误:

during RTL pass: expand
test_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

有人可以帮助我吗?

4

0 回答 0