C++ LoadInst和StoreInst值和地址LLVM
我有一个文件print.c,它有两个功能:C++ LoadInst和StoreInst值和地址LLVM,c++,c,llvm,C++,C,Llvm,我有一个文件print.c,它有两个功能: void printLoad(...) { // print address and value of memory location from which value printf("address=... value=...", ...); } void printStore(...) { // print address and value of memory location from which value } 我有一个L
void printLoad(...) {
// print address and value of memory location from which value
printf("address=... value=...", ...);
}
void printStore(...) {
// print address and value of memory location from which value
}
我有一个LLVM过程,它迭代指令并在当前指令(load/store inst)之后添加CallInst指令printLoad或printStore(取决于指令类型)
为了调用这个printStore或printLoad,我需要向CallInst::Create函数添加适当的参数,这些参数是内存位置的地址和值
这是我想要实现的一个例子:
define void @mains() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 5, i32* %1, align 4
store i32 2, i32* %2, align 4
store i32 4, i32* %2, align 4
%3 = load i32, i32* %2, align 4
%4 = add nsw i32 %3, 5
store i32 %4, i32* %1, align 4
ret void
}
The output should be:
store instruction:
address=... // address of %1
value=0
...
...
...
load instruction:
address=... // address of %2
value=4
store instruction:
address=... // address of %1
value=9
迄今为止的进展情况:
我能够在LoadInst/StoreInst上使用getPointerOperand()获取操作数的地址
通过将操作数强制转换为ConstantInt,我还可以在前4条存储指令中获得StoreInst的值,但我不知道如何提取最后一条StoreInst中的值。有可能吗
编辑:
使用
void printLoad(int32_t p)
及
这会导致分段错误:运行时为11
已解决:
发现我有无限循环(由于递归)printStore实际上使用加载/存储指令,从而创建另一个对printStore的调用,依此类推。假设您有一个
llvm::函数
表示printLoad()
和printStore()
:
您可以为每个LoadInst
和StoreInst
发出CallInst
对于LoadInst
:
LoadInst * some_load = ...
Value * address_of_load = some_load->getOperand(0);
Value * print_load_arguments[] = { address_of_load, some_load };
// Insert a CallInst just after the load.
CallInst::Create(print_load, print_load_arguments )->insertAfter( some_load );
StoreInst * some_store = ...
Value * value_to_store = some_store->getOperand(0);
Value * address_of_store = some_store->getOperand(1);
Value * print_store_arguments[] = { address_of_store, value_to_store };
// Insert a CallInst just after the store.
CallInst::Create(print_store, print_store_arguments)->insertAfter(some_store);
请记住,在llvm中,LoadInst
加载的值与LoadInst
本身是相同的
对于StoreInst
:
LoadInst * some_load = ...
Value * address_of_load = some_load->getOperand(0);
Value * print_load_arguments[] = { address_of_load, some_load };
// Insert a CallInst just after the load.
CallInst::Create(print_load, print_load_arguments )->insertAfter( some_load );
StoreInst * some_store = ...
Value * value_to_store = some_store->getOperand(0);
Value * address_of_store = some_store->getOperand(1);
Value * print_store_arguments[] = { address_of_store, value_to_store };
// Insert a CallInst just after the store.
CallInst::Create(print_store, print_store_arguments)->insertAfter(some_store);
如果所有类型都匹配,这将起作用。否则,您必须在调用
printStore()
或printLoad()
之前插入BitCast
指令操作数应该是AddInst或类似的东西。请记住,INSN与其表示的值相等。也许?为了获得实际的叶int值,您可以尝试一个常量传播转换(包括前面的mem2reg传递,以删除指针而使用寄存器)。但是我仍然不确定你想要完成什么。您是想实际运行代码,还是想进行静态分析?是否可以进行通用解决方案,而不仅仅是针对二进制运算符?听起来您想实际运行代码,而不是分析代码?这意味着你不需要做任何特别的事情。只需将值操作数作为参数传递给调用insns。并将函数的参数设为int32_t。我这样做了,但得到了“指令并不支配所有用途!%3=load i32,i32*%2,align 4调用void@printLoad(i32%3)LLVM错误:发现函数已损坏,编译已中止!”
StoreInst * some_store = ...
Value * value_to_store = some_store->getOperand(0);
Value * address_of_store = some_store->getOperand(1);
Value * print_store_arguments[] = { address_of_store, value_to_store };
// Insert a CallInst just after the store.
CallInst::Create(print_store, print_store_arguments)->insertAfter(some_store);