【问题标题】:llvm replace a function with another onellvm 用另一个函数替换一个函数
【发布时间】:2013-11-22 18:49:14
【问题描述】:

我正在尝试用另一个函数调用替换一个函数调用。例如这是具有 3 个函数的代码 - print1、print2 和 main:

#include <stdio.h>
extern "C" { 
int print1()
{
   printf("Inside print1\n");
   return 0xdeadbeef;
}
int print2()
{
   printf("Inside print2\n");
   return 0xbeefdead;
}
int main(void)
{
   return print1();
}
}"

我的目标是用 print2 替换 print1(主要)的使用。我将上面的代码编译成一个 llvm::Module*(在下面的代码中称为 main),然后用它创建一个执行引擎。

std::string errMsg;
llvm::ExecutionEngine *ee =
   llvm::EngineBuilder( main ).setErrorStr( &errMsg ).create();    
ASSERT_NE( ee, nullptr )<<"Execution engine is nullptr:"<<errMsg;

此时,我能够从执行引擎中获取所有 3 个函数(print1、print2 和 main),并且能够很好地执行它们。但是,当我尝试将函数“print1”替换为“print2”时出现问题,如下所示:

llvm::Function *print1f = main->getFunction( "print1" );
llvm::Function *print2f = main->getFunction( "print2" );
llvm::Function *mainf = main->getFunction( "main" );

//carry out the replacement
print2f->takeName( print1f );
ee->freeMachineCodeForFunction( mainf );
ee->freeMachineCodeForFunction( print1f );
print1f->replaceAllUsesWith( print2f );
print1f->deleteBody();
print1f->dropAllReferences();
print1f->eraseFromParent();

//run main
void *mainfPtr = ee->getPointerToFunction( mainf );
mainfPtr = ee->recompileAndRelinkFunction( mainf );
ASSERT_NE( mainfPtr, nullptr );
ret = ((int(*)(void))(mainfPtr))();
*EXPECT_EQ(0xbeefdead, ret);*

但是,ret 返回为 0xdeadbeef,就好像调用的是 print1 而不是 print2。如果我按照正确的步骤替换函数调用,有人可以告诉我。如果有其他方法,请告诉我。

谢谢 维卡斯。

===========

【问题讨论】:

  • 编译器可以在此之前进行任何内联吗? (如果是这样,main 将有效地将 print1 的代码粘贴到其中,并且用名称替换函数将无济于事......)
  • 好点 cHao,但是,我在编译模块时没有运行任何优化通道或内联。它只是使用 ParseAST 例程 (clang.llvm.org/doxygen/ParseAST_8h.html) 构造的,所以我猜测没有发生内联。有没有办法确保不发生内联?
  • cHao,你是对的。编译器确实是内联 print1。感谢您的帮助。
  • cHao,我似乎无法接受评论作为答案。请发表您的评论作为答案,我会接受。

标签: llvm jit


【解决方案1】:

如果编译器将print1 内联到main,则该函数将永远不会真正调用;相反,main 将粘贴自己的私有版本的print1 代码。由于它实际上不必再引用共享的print1,因此交换print2 可能不会影响main'的行为。

如果您想验证这是否是问题所在(和/或阻止它发生,如果是的话),请尝试告诉编译器不要内联。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多