LoadInst 和 StoreInst 值和地址 LLVM

Man*_*tas 2 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 
}
Run Code Online (Sandbox Code Playgroud)

我有一个 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
Run Code Online (Sandbox Code Playgroud)

迄今为止的进展:

我能够在 LoadInst/StoreInst 上使用 getPointerOperand() 获取操作数的地址。

我还可以通过将操作数强制转换为 ConstantInt 来获取前 4 条存储指令中 StoreInst 的值,但我不知道如何提取最后一条 StoreInst 中的值。甚至有可能吗?

编辑:

使用

void printLoad(int32_t p) 
Run Code Online (Sandbox Code Playgroud)

Constant *hookLoadFunc = M.getOrInsertFunction("printLoad", Type::getVoidTy(M.getContext()), Type::getInt32Ty(M.getContext()));
Run Code Online (Sandbox Code Playgroud)

.

  %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
Run Code Online (Sandbox Code Playgroud)

这会导致 Segmentation fault: 11 运行时。

解决了:

发现我有无限循环(由于递归)。printStore实际上使用加载/存储指令,从而创建对printStore 的另一个调用等等。

sba*_*bbi 6

假设您有一个llvm::Function代表printLoad()printStore()

llvm::Function * print_load = ....
llvm::Function * print_store = ...
Run Code Online (Sandbox Code Playgroud)

您可以CallInst为每个LoadInst和发出一个StoreInst

对于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 );
Run Code Online (Sandbox Code Playgroud)

请记住,在 llvm 中,加载的值与加载的值本身LoadInst相同LoadInst

对于StoreInst

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);
Run Code Online (Sandbox Code Playgroud)

如果所有类型都匹配,这将起作用。否则,您必须BitCast在调用printStore()或之前插入说明printLoad()