【问题标题】:How to fix this `FunctionPass` such that it doesn't go into an infinite loop?如何修复此“FunctionPass”使其不会进入无限循环?
【发布时间】:2017-02-05 19:02:02
【问题描述】:

以下代码尝试创建一个FunctionPass,它遍历所有BasicBlock,并将a + b更改为(a xor b) + 2 * (a and b)以进行混淆。

现在,当我使用ReplaceInstWithValue 时,迭代器失效,程序进入无限循环。

我已经尝试了几种方法来解决这个问题,但都没有被证明是有用的。

我将如何更改程序,以便它迭代程序中的所有指令,而不会在第一条 add 指令上进入无限循环?

#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <map>
#include <string>

using namespace llvm;

namespace {
struct CountOp : public FunctionPass {
    std::map<std::string, int> bbNameToId;

    static char ID;

    CountOp() : FunctionPass(ID) {}

    virtual bool runOnFunction(Function &F) {

        for (Function::iterator bs = F.begin(), be = F.end(); bs != be; ++bs) {
            for (BasicBlock::iterator is = bs->begin(), ie = be->end(); is != ie; ++is) {
                Instruction& inst  = *is;
                BinaryOperator* binop = dyn_cast<BinaryOperator>(&inst);

                if (!binop) {
                    continue;
                }

                unsigned opcode = binop->getOpcode();
                errs() << binop->getOpcodeName() << "\n";

                if (opcode != Instruction::Add) {
                    continue;
                }

                IRBuilder<> builder(binop);
                Value* v = builder.CreateAdd(builder.CreateXor(binop->getOperand(0), binop->getOperand(1)), 
                                             builder.CreateMul(ConstantInt::get(binop->getType(), 2), 
                                                               builder.CreateAnd(binop->getOperand(0), binop->getOperand(1))));

                ReplaceInstWithValue(bs->getInstList(), is, v);
            } 
        }   


        return true;
    }
};
}

char CountOp::ID = 0;
static RegisterPass<CountOp> X("opChanger", "Change add operations", false, false);

【问题讨论】:

    标签: c++ llvm llvm-clang llvm-ir


    【解决方案1】:

    其实问题出在for语句中:

    for (BasicBlock::iterator is = bs-&gt;begin(), ie = be-&gt;end(); is != ie; ++is).

    ie 应初始化为 bs-&gt;end() 而不是 be-&gt;end()

    那么这个例子就可以正常工作了。

    【讨论】:

      猜你喜欢
      • 2019-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多