如何使用LLVM在某些指令后插入一个调用?

时间:2016-03-13 12:51:45

标签: x86 llvm instrumentation

我是LLVM的新手,并尝试使用LLVM来执行检测。具体来说,预计在 SP-Update指令之后插入执行某些检查工作的调用。 SP-Update指令是隐式或显式修改 esp 寄存器的指令。例如, mov esp,eax 是显式SP-Update指令, pop eax 是隐式指令。我必须本地化这些说明并在其后添加我的检查代码。直观地说,我需要修改后端部分。但我不知道应该挖掘哪些类或功能。如果有人能帮助我?非常感谢。

1 个答案:

答案 0 :(得分:2)

通常llvm为生成的函数准备帧,我认为你对内联汇编比对esp寄存器的正常更新更感兴趣。

无论如何,你可以转到lib / Target / X86 / InstPrinter / X86ATTInstPrinter.cpp源并修改函数X86ATTInstPrinter :: printInst,这样对于有问题的指令,它会打印一些额外的代码。

类似的东西:

if (MI->getOpcode() == X86::PUSH16r
    || MI->getOpcode() == X86::PUSH32r
    || MI->getOpcode() == X86::PUSH64r) {
     OS << "\tcall your_function\n";
  }

假设您在该位置添加了代码并编译了llvm的llc二进制文件。 有一个关于你如何使用它的例子:

M.C:

#include <stdio.h>

void your_function() {
  printf("your_function called\n");
}

void foo();

int main() {
  foo();
}

T.C:

void foo() {
  asm("push %rax");
  asm("pop %rax");
}

然后使用构建的llvm二进制文件执行以下命令:

clang t.c -c -emit-llvm
llc t.bc
llvm-mc t.s   -o t.o  -filetype=obj
clang m.c t.o -o ttt

现在您可以运行该文件并获得所需的结果:

./ttt 
your_function called
your_function called
请注意,这两个打印来自push指令,其中一个是在内联汇编中,而另一个是在fl函数的llvm生成帧中,而不是来自pop指令