12

我一直在寻找几个小时,我找不到任何可以帮助我的东西。我正在做一个涉及 FunctionPass 的项目。我已经实现了一个 runOnFunction(Function &f) 方法,并且工作正常。基本上它需要:

1)检测存储指令

2)将store指令的内存地址转换为Integer

3) 使用按位与运算 (0000FFFF) 更改整数

4) 将整数转换回指针

到目前为止,我有以下内容:

 virtual bool runOnFunction(Function &F) {
  for (Function::iterator bb = F.begin(), bbe = F.end(); bb != bbe; ++bb) {
    BasicBlock& b = *bb;
    for (BasicBlock::iterator i = b.begin(), ie = b.end(); i != ie; ++i) {
      if(StoreInst *si = dyn_cast<StoreInst>(&*i)) {
        PtrToIntInst* ptrToInt = new PtrToIntInst(si->getPointerOperand(), IntegerType::get(si->getContext(), 32), "", si);
      }
    }
  }
  return true;
}

我一生都无法弄清楚如何实际插入指令,甚至无法找到创建 AND 指令的方法。如果有人能指出我正确的方向,那就太好了。

提前致谢。

4

3 回答 3

7

我建议看一下程序员手册——它对基础知识的覆盖面相当不错。

特别是,有一个关于创建和插入新指令的部分。最简单的方法是提供一条现有指令作为新指令的构造函数的最后一个参数,然后它将在现有指令之前立即插入该指令。

或者,如果您只想添加到它的末尾,您可以传递封闭的基本块(但请记住,您需要照顾终结者!)。最后,您可以只调用getInstList()封闭的基本块,然后insertpush_back在那里插入新指令。

顺便说一句,您不必遍历所有块,然后遍历每个块中的所有指令,您可以直接遍历指令;请参阅程序员手册中有关指令迭代器的部分

于 2012-11-14T13:01:57.590 回答
5
 virtual bool runOnFunction(Function &F) {
  for (Function::iterator bb = F.begin(), bbe = F.end(); bb != bbe; ++bb) {
    BasicBlock &b = *bb;
    for (BasicBlock::iterator i = b.begin(), ie = b.end(); i != ie; ++i) {
      if (StoreInst *si = dyn_cast<StoreInst>(&*i)) {
        IRBuilder Builder(si);
        Value *StoreAddr = Builder.CreatePtrToInt(si->getPointerOperand(), Builder.getInt32Ty());
        Value *Masked = Builder.CreateAnd(StoreAddr, 0xffff);
        Value *AlignedAddr = Builder.CreateIntToPtr(Masked, si->getPointerOperand()->getType());
        // ...
      }
    }
  }
  return true;
}
于 2012-12-09T09:36:23.183 回答
1

您可以使用 anIRBuilder在另一条指令之前或基本块的末尾轻松插入新指令。

或者,如果您需要在另一条指令之后instruction list插入一条指令,则需要在包含基本块中使用:

BasicBlock *pb = ...; 
Instruction *pi = ...; 
Instruction *newInst = new Instruction(...); 

pb->getInstList().insertAfter(pi, newInst);

取自此处的代码和解决方案。

于 2017-02-15T17:34:25.233 回答