当前位置:  开发笔记 > 编程语言 > 正文

LLVM:更改函数中的指令或基本块

如何解决《LLVM:更改函数中的指令或基本块》经验,为你挑选了1个好方法。

我想通过重新排序一些指令或插入一个新的基本块来操作一个函数.

我的方法可以在下面看到.

我从LLVM IR读取一个模块,然后迭代其内容.

我该如何更改其内容?

克隆是否必要,如果是,我将如何插入新指令?

#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace llvm;
int main()
{
  LLVMContext context;
  SMDiagnostic error;
  std::unique_ptr m = parseIRFile("test.ll", error, context);

  std::error_code EC;
  llvm::raw_fd_ostream OS("module", EC, llvm::sys::fs::F_None);
  WriteBitcodeToFile(m.get(), OS);
  OS.flush();

  std::cout << "Successfully read Module:" << std::endl;
  std::cout << " Name: " << m->getName().str() << std::endl;
  std::cout << " Target triple: " << m->getTargetTriple() << std::endl;

  Module* mod = new Module("obfus", getGlobalContext());

  for (auto iter1 = m->getFunctionList().begin();
       iter1 != m->getFunctionList().end(); iter1++) {
    Function &f = *iter1;
    std::cout << " Function: " << f.getName().str() << std::endl;

    Function* duplicateFunction = CloneFunction(f, nullptr, /*ModuleLevelChanges=*/false);
    f.getParent()->getFunctionList().push_back(duplicateFunction);

    for (auto iter2 = f.getBasicBlockList().begin();
         iter2 != f.getBasicBlockList().end(); iter2++) {
      BasicBlock &bb = *iter2;
      std::cout << "  BasicBlock: " << bb.getName().str() << std::endl;
      for (auto iter3 = bb.begin(); iter3 != bb.end(); iter3++) {
        Instruction &inst = *iter3;
        std::cout << "   Instruction " << &inst << " : " << inst.getOpcodeName();

    unsigned int  i = 0;
    unsigned int opnt_cnt = inst.getNumOperands();
        for(; i < opnt_cnt; ++i)
      {
        Value *opnd = inst.getOperand(i);
        std::string o;
        //          raw_string_ostream os(o);
        //         opnd->print(os);
        //opnd->printAsOperand(os, true, m);
        if (opnd->hasName()) {
          o = opnd->getName();
          std::cout << " " << o << "," ;
        } else {
          std::cout << " ptr" << opnd << ",";
        }
      }
        std:: cout << std::endl;
      }
    }
  }

  return 0;
}

AlexDenisov.. 5

通常,除非要保留​​原始版本,否则不需要克隆或复制任何内容.

基本块和指令都有用于插入,移动和替换的API.

要操作块,您可以使用以下方法(注意,将来可能会更改):

void insertInto(Function *Parent, BasicBlock *InsertBefore = nullptr);
void moveAfter(BasicBlock *MovePos);
void moveBefore(BasicBlock *MovePos);
SymbolTableList::iterator eraseFromParent();
void removeFromParent();

同样适用于指示:

void removeFromParent();
SymbolTableList::iterator eraseFromParent();
void insertBefore(Instruction *InsertPos);
void insertAfter(Instruction *InsertPos);
void moveBefore(Instruction *MovePos);
void moveBefore(BasicBlock &BB, SymbolTableList::iterator I);

我绝对可以推荐查看BasiBlock和Instruction接口,看看他们还有什么.



1> AlexDenisov..:

通常,除非要保留​​原始版本,否则不需要克隆或复制任何内容.

基本块和指令都有用于插入,移动和替换的API.

要操作块,您可以使用以下方法(注意,将来可能会更改):

void insertInto(Function *Parent, BasicBlock *InsertBefore = nullptr);
void moveAfter(BasicBlock *MovePos);
void moveBefore(BasicBlock *MovePos);
SymbolTableList::iterator eraseFromParent();
void removeFromParent();

同样适用于指示:

void removeFromParent();
SymbolTableList::iterator eraseFromParent();
void insertBefore(Instruction *InsertPos);
void insertAfter(Instruction *InsertPos);
void moveBefore(Instruction *MovePos);
void moveBefore(BasicBlock &BB, SymbolTableList::iterator I);

我绝对可以推荐查看BasiBlock和Instruction接口,看看他们还有什么.

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有