LLVM中是否有内置库可用于提取这些信息?如果没有,请建议我如何编写函数来实现这一点。(现有源代码、参考资料、教程、示例...)
我想的是,首先将源代码转换为LLVM字节码(bc),然后对其进行插桩以进行分析,但不知道具体如何操作。
我试图自己找出应该为我的目的使用哪种IR(Clang的抽象语法树(AST)还是LLVM的SSA中间表示(IR)),但无法真正确定使用哪个。这是我正在尝试做的事情。给定任何C/C++程序(例如下面给出的程序),我正在尝试在每个读/写/从内存读/写指令之前和之后插入对某些函数的调用。例如,考虑以下C++程序(Account.cpp)。
#include <stdio.h>
class Account {
int balance;
public:
Account(int b) {
balance = b;
}
int read() {
int r;
r = balance;
return r;
}
void deposit(int n) {
balance = balance + n;
}
void withdraw(int n) {
int r = read();
balance = r - n;
}
};
int main () {
Account* a = new Account(10);
a->deposit(1);
a->withdraw(2);
delete a;
}
因此,在仪器调试之后,我的程序应该如下所示:
#include <stdio.h>
class Account {
int balance;
public:
Account(int b) {
balance = b;
}
int read() {
int r;
foo();
r = balance;
foo();
return r;
}
void deposit(int n) {
foo();
balance = balance + n;
foo();
}
void withdraw(int n) {
foo();
int r = read();
foo();
foo();
balance = r - n;
foo();
}
};
int main () {
Account* a = new Account(10);
a->deposit(1);
a->withdraw(2);
delete a;
}
foo()可以是任何函数,例如获取当前系统时间或递增计数器等。因此,我了解到要插入像上面那样的函数,首先必须获取IR,然后在IR上运行插桩传递,这将向IR中插入这些调用,但我不知道如何实现。请举例说明如何操作。
另外,我了解到一旦将程序编译为IR,将很难获得原始程序和插装IR之间的1:1映射。因此,是否有可能反映IR中所做的更改(由于插装)到原始程序中。
为了开始学习LLVM pass以及如何自己制作pass,我查看了一个示例,该示例向LLVM IR加载和存储添加运行时检查,即SAFECode的load/store instrumentation pass (http://llvm.org/viewvc/llvm-project/safecode/trunk/include/safecode/LoadStoreChecks.h?view=markup和http://llvm.org/viewvc/llvm-project/safecode/trunk/lib/InsertPoolChecks/LoadStoreChecks.cpp?view=markup)。但我无法弄清楚如何运行此pass。请告诉我如何在某个程序上运行此pass,例如上面的Account.cpp。
opt
插件运行)的相关内容?http://llvm.org/docs/WritingAnLLVMPass.html - SK-logic