Я пытаюсь заменить вызов функции другим. например Вот код с 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();
}
}"
Моя цель состоит в том, чтобы заменить использование print1 (в основной) с Print2. Я компилирую вышеуказанный код в 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 и основные) от исполнения двигателя и в состоянии выполнить их хорошо. Тем не менее, проблема возникает, когда я пытаюсь заменить функцию «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. Может кто-то, пожалуйста, сообщите мне, если я последую за правильными шагами, чтобы заменить вызов функции. Если есть другой метод, пожалуйста, дайте мне знать.
thx Vikas.
==========
Может ли компилятор делать какие-либо вставки до этого момента? (Если бы это произошло, 'main' эффективно ввел в него код' print1', и замена функции по имени не смогла бы многое сделать с этим ...) – cHao
Хорошая точка cHao, однако, я не запускать никаких проходов оптимизации или встраивания при компиляции модуля. Он просто построен с использованием процедуры ParseAST (http://clang.llvm.org/doxygen/ParseAST_8h.html), поэтому я предполагаю, что никакой инлайн-операции не произошло. Есть ли способ убедиться, что нет инлайн-событий? – vikas
c Хао, вы были правы. Компилятор действительно вставлял print1. Спасибо за вашу помощь. – vikas