Плагин GCC: можно ли переместить последовательность базового блока одной функции в базовый блок другой функции?

Я пытаюсь создать плагин для 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, вызывается после передачи "cfg":

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

Кто-нибудь может мне помочь?

0 ответов

Другие вопросы по тегам