我想用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 然后追问也不回答,希望来个真正懂的帮我解决这个问题
写一个这样的教程也能帮助到更多人。如能解决此问题,我必采纳!在此谢过了
llvm pass 插桩后,文件执行时输出实际执行线路上插入的随机数
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
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,并将修改后的模块写入到一个文件中。
希望这能帮助你解决问题!
解决 无用评论 打赏 举报
悬赏问题
- ¥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驱动开发环境