llvm replace a function with another one
jit, llvm
Solution
If the compiler were to inline `print1` in `main`, the function would never actually be called; Instead, `main` would have its own private version of `print1`'s code pasted in. Since it doesn't actually have to refer to the shared `print1` anymore, swapping in `print2` might not affect `main`'s behavior.
If you want to verify that this is the problem (and/or keep it from happening, if it is), try telling the compiler not to inline.
Problem
I am trying to replace a function call with another one. e.g. here is the code with 3 functions - print1, print2 and 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(); } }" ``` My goal is to replace use of print1 (in main) with print2. I compile the above code into an llvm::Module* (called main in the code below) and then create an execution engine out of it. ``` std::string errMsg; llvm::ExecutionEngine *ee = llvm::EngineBuilder( main ).setErrorStr( &errMsg ).create(); ASSERT_NE( ee, nullptr )<<"Execution engine is nullptr:"<<errMsg; ``` At this point, I am able to get all the 3 functions (print1, print2 and main) from the execution engine and am able to execute them fine. However, problem occurs when I try to replace function "print1" with "print2", as follows: ``` 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);* ``` However, ret is returned as 0xdeadbeef, as if print1 is being called and not print2. Can someone please let me know if I am following the right steps to replace the function call. If there is other method, please let me know. thx Vikas. ==========