我有一个文件 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
}
我有一个 LLVM 传递,它迭代指令并在当前指令(加载/存储实例)之后添加 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 中的值。有可能吗?
EDITED:
Using
void printLoad(int32_t p)
and
Constant *hookLoadFunc = M.getOrInsertFunction("printLoad", Type::getVoidTy(M.getContext()), Type::getInt32Ty(M.getContext()));
.
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
store i32 0, i32* %1, align 4
call void @printStore(i32 0)
store i32 0, i32* %2, align 4
call void @printStore(i32 0)
store i32 5, i32* %2, align 4
call void @printStore(i32 5)
store i32 2, i32* %3, align 4
call void @printStore(i32 2)
store i32 4, i32* %3, align 4
call void @printStore(i32 4)
%4 = load i32, i32* %3, align 4
%5 = add nsw i32 %4, 5
store i32 %5, i32* %2, align 4
call void @printStore(i32 %5)
ret i32 0
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
call void @printStore(i32 %0)
%3 = load i32, i32* %2, align 4
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str, i32 0, i32 0), i32 %3)
ret void
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
call void @printStore(i32 %0)
%3 = load i32, i32* %2, align 4
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.1, i32 0, i32 0), i32 %3)
ret void
这会导致运行时出现分段错误:11。
SOLVED:
发现我有无限循环(由于递归)。打印商店实际上使用加载/存储指令,从而创建另一个调用打印商店等等。