2017-02-05 5 views
1

다음 코드는 BasicBlock 모두를 반복하는 FunctionPass을 생성하고 난독 화를 위해 a + b(a xor b) + 2 * (a and b)으로 변경하려는 시도입니다.이 'FunctionPass`를 수정하여 무한 루프에 빠지지 않도록하는 방법은 무엇입니까?

이제 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); 

답변

3

사실, 문제는 for 문에 있습니다

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

iebs->end()이 아닌 be->end()으로 초기화되어야합니다.

그러면 예제가 정상적으로 작동합니다.