weixin_46374192 2023-07-31 15:40 采纳率: 0%
浏览 27
已结题

llvm pass 插桩后,文件执行时输出实际执行线路上插入的随机数

我想用llvm的pass做一个插桩的需求。但是网上只有hello pass的写法,pass官网的介绍也看的云里雾里。但是我们这周就必须做出来这个需求,这个需求对熟练使用pass的人来说可能就是个很小的需求。就是我想写个pass,它的功能是,用它处理一个C代码之后生成一个文件,在这个文件的每一个基本块上插入随机数,和输出这个随机数的指令给这个随机数输出到一个外部文件。当我每次执行这个文件的时候,实际执行到的路径上的随机数会被输出到外部文件。希望各位能帮我写出这个pass,以及在终端执行的每一步的指令,最后达到这样一个功能。之前有人给的pass,要么有CallInst *printCall = CallInst::Create(printFunc, argsRef, "", terminator);语句,要么有 Builder.CreateCall(putsFunc, RandomNumValue);语句,总是在编译make时会报错,error: ‘printlnFunc’ was not declared in this scope 或者error: ‘putsFunc’ was not declared in this scope 然后追问也不回答,希望来个真正懂的帮我解决这个问题
写一个这样的教程也能帮助到更多人。如能解决此问题,我必采纳!在此谢过了

  • 写回答

11条回答 默认 最新

  • anbosol 2023-07-31 16:16
    关注

    首先,要编写一个LLVM的pass来实现你的需求,你需要先包含一些必要的头文件和定义一些必要的类。以下是一个简单的示例,展示了如何编写一个pass来在每个基本块上插入随机数并输出到外部文件:

    #include "llvm/IR/PassManager.h"
    #include "llvm/IR/Module.h"
    #include "llvm/IR/Function.h"
    #include "llvm/IR/BasicBlock.h"
    #include "llvm/IR/IRBuilder.h"
    #include "llvm/IR/LLVMContext.h"
    #include "llvm/IR/Value.h"
    #include "llvm/Support/RandomNumberGenerator.h"
    
    using namespace llvm;
    
    namespace {
      struct RandomNumberInsertion : public ModulePass {
        static char ID;
        RandomNumberInsertion() : ModulePass(ID) {}
    
        void getAnalysisUsage(AnalysisUsage &AU) const override {
          AU.setPreservesAll();
        }
    
        bool runOnModule(Module &M) override {
          LLVMContext &Context = M.getContext();
          RandomNumberGenerator RNG;
    
          for (Function &F : M) {
            for (BasicBlock &BB : F) {
              // Generate a random number
              uint32_t RandomNum = RNG.next();
    
              // Create a new basic block for the random number insertion
              BasicBlock *RandomBB = BasicBlock::Create(Context, "random", &F, &BB);
    
              // Insert the random number into the new basic block
              IRBuilder<> builder(Context);
              builder.SetInsertPoint(RandomBB);
              Value *RandomNumValue = builder.getInt32(RandomNum);
              builder.CreateCall(&F.getFunction("printlnFunc"), RandomNumValue);
    
              // Add a branch instruction from the original basic block to the new one
              BB.getTerminator()->addSuccessor(RandomBB, BranchProbability(1, 1));
              BB.getTerminator()->setSuccessor(1, RandomBB);
            }
          }
    
          return true;
        }
      };
    }
    
    char RandomNumberInsertion::ID = 0;
    static RegisterPass<RandomNumberInsertion> X("random-number-insertion", "Random Number Insertion Pass");
    
    

    在这个示例中,我们创建了一个名为RandomNumberInsertion的pass类,它继承自ModulePass。在runOnModule方法中,我们遍历了模块中的每个函数和基本块,并在每个基本块中插入了一个新的基本块,用于输出随机数。我们还添加了一个分支指令,将控制流从原始基本块转移到新的基本块。这样,每次执行通过这个pass处理后的代码时,都会在每个基本块上生成一个随机数,并将其输出到外部文件。

    要使用这个pass,你需要将其添加到pass管理器中,并在执行优化时包含它。以下是一个示例:

    c++

    int main() {
      LLVMContext Context;
      std::unique_ptr<Module> M = std::make_unique<Module>("test", Context);
      // ... (Create your module here) ...
    
      // Create a pass manager and add our pass to it
      PassManager PM;
      PM.add(new RandomNumberInsertion);
    
      // Run the pass manager on the module
      PM.run(*M);
    
      // Write the modified module to然后,我们创建了一个pass管理器,并将我们的pass添加到其中。最后,我们使用pass管理器运行pass,并将修改后的模块写入到一个文件中。
    
    

    希望这能帮助你解决问题!

    评论

报告相同问题?

问题事件

  • 系统已结题 8月8日
  • 创建了问题 7月31日

悬赏问题

  • ¥30 STM32 INMP441无法读取数据
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境