简体   繁体   English

LoadInst和StoreInst值和地址LLVM

[英]LoadInst and StoreInst Values and addresses LLVM

I have a file print.c, which has two functions: 我有一个文件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 
}

I have an LLVM pass which iterates over the instructions and adds CallInst instruction either printLoad or printStore (depending on the instruction type) after the current one (load/store inst). 我有一个LLVM遍历,它遍历指令,并在当前指令(加载/存储指令)之后添加CallInst指令printLoad或printStore(取决于指令类型)。

In order to call this printStore or printLoad I need to add appropriate arguments to CallInst::Create function, which are the address and the value of the memory location. 为了调用此printStore或printLoad,我需要向CallInst :: Create函数添加适当的参数,这些参数是内存位置的地址和值。

This is an example of what I want to achieve: 这是我要实现的示例:

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

Progress so far: 到目前为止的进展:

I am able to get the addresses of the operands using getPointerOperand() on LoadInst/StoreInst. 我可以使用LoadInst / StoreInst上的getPointerOperand()获取操作数的地址。

I can also get the value of StoreInst in the first 4 store instructions by casting the operand to ConstantInt, but I don't know how to extract the value in the last StoreInst. 通过将操作数强制转换为ConstantInt,我还可以在前4个存储指令中获得StoreInst的值,但是我不知道如何在最后一个StoreInst中提取值。 Is it even possible? 可能吗?

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

This causes Segmentation fault: 11 when run. 这会导致分段错误:运行时为11。

SOLVED: 解决了:

Figured out that I had infinity loop (due to recursion). 弄清楚我有无限循环(由于递归)。 printStore actually uses load/store instructions, thus creating another call to printStore and so on. printStore实际上使用加载/存储指令,从而创建另一个对printStore的调用,依此类推。

Assuming that you have an llvm::Function that represents printLoad() and printStore() : 假设您有一个llvm::Function ,它代表printLoad()printStore()

llvm::Function * print_load = ....
llvm::Function * print_store = ...

You can emit a CallInst for each LoadInst and StoreInst . 您可以发出CallInst每个LoadInstStoreInst

For LoadInst : 对于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 );

Remember that in llvm the value loaded by the LoadInst is the same thing as the LoadInst itself. 请记住,在llvm中, LoadInst加载的值与LoadInst本身相同。

For StoreInst : 对于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);

This will work if all the types match. 如果所有类型都匹配,这将起作用。 Otherwise, you have to insert BitCast instructions just before calling printStore() or printLoad() . 否则,您必须在调用printStore()printLoad()之前插入BitCast指令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM