GCC插件:复制函数的参数

时间:2014-06-18 08:29:21

标签: c gcc plugins instrumentation

我开发了一个GCC插件,用于检测正在编译的应用程序。这些应用程序是用C语言编写的,并且在x86 Linux系统上使用GCC 4.7(4.8和4.9也是一个选项)构建。

我的插件实现了一个编译传递,它放在" ssa"之后。标准传递并在GIMPLE表示上运行。除此之外,我需要实现以下内容,但目前无法弄清楚如何正确地做到这一点。

在处理C函数时,我需要在其开头插入代码,将其参数复制到我创建的局部变量,以备将来处理。

我的第一个天真实现如下:

tree p;
gimple_seq seq = NULL;
gimple_stmt_iterator gsi = gsi_start_bb(single_succ(ENTRY_BLOCK_PTR));

for (p = DECL_ARGUMENTS(current_function_decl); p; p = DECL_CHAIN(param)) {
    tree copy_par;
    copy_par = create_tmp_var(TREE_TYPE(p), NULL);
    add_referenced_var(copy_par);
    copy_par = make_ssa_name(copy_par, NULL);
    g = gimple_build_assign(copy_par, p);
    SSA_NAME_DEF_STMT(copy_par) = g;
    gimple_seq_add_stmt_without_update (&seq, g);
    ... // more processing here
}
...
gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);

但是,这样,根据转储创建了参数声明到变量的无效分配:

gimple_assign <parm_decl, D.2206_11, par, NULL>

D.2206_11对应于我创建的局部变量par - 我要复制的函数的参数。

GCC在之后的一些传递中崩溃,试图处理这个添加的语句。我想这是因为p不是变量保存相应参数的值而是该变量的声明。这样吗?以及如何获得该变量?

我尝试使用gimple_build_assign_with_ops(NOP_EXPR, copy_par, p, NULL_TREE)代替gimple_build_assign(),但它没有做到。海湾合作委员会仍然在同一个地方崩溃。我可以提供回溯,但我觉得我只是缺少一些基本的东西。

我还查看了从TYPE_ARG_TYPES (TREE_TYPE (current_function_decl))开始到TREE_CHAIN(...)的树遍历,但这似乎给出了参数的类型而不是相应的变量。

所以,问题是,如何正确添加函数参数的复制。

注意 也许,这可以在MELT或GCC Python插件的帮助下完成,但在这个项目中,我需要仅使用GCC本身提供的代码执行所有转换。

1 个答案:

答案 0 :(得分:2)

我发现复制参数适用于GCC 4.8和4.9但不适用于4.7。 Here is the code现在适合我(instrument_fentry()执行复制)。

为避免在以后的编译过程中删除副本,我将相应的变量设置为volatile。

此外,如果没有为给定参数指定默认定义语句的SSA_NAME(请参阅SSA_NAME_IS_DEFAULT_DEF()),我添加了带有GIMPLE_NOPs的SSA_NAME作为定义语句。

到目前为止,这已经适用于GCC 4.8和4.9,所以它看起来像是GCC 4.7中的错误或者GCC 4.7和4.8之间的一些规则变化。我无法确定确切的提交。