1
我想用另一个替换函数调用。例如这里是3个函数的代码 - PRINT1,print2和主:llvm替换另一个函数
#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和主)和我能够精细执行它们。然而,当我尝试用“print2”来替换功能“PRINT1”出现问题,具体如下:
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。如果我按照正确的步骤更换函数调用,是否有人可以让我知道。如果有其他方法,请让我知道。
thx Vikas。
==========
编译器可以在此之前做任何内联吗? (如果是这样,'main'将会有效地将'print1'的代码粘贴到它中,并且用名称替换函数将无法做到这一点...) – cHao
好点cHao,但是,我是在编译模块时不会运行任何优化传递或内联。它只是使用ParseAST例程(http://clang.llvm.org/doxygen/ParseAST_8h.html)构建的,所以我猜测没有发生内联。有没有办法确保内联不会发生? – vikas
cHao,你是对的。编译器的确在内联print1。谢谢你的帮助。 – vikas