You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检查LLVM变量中存储的数据?——针对汇编转LLVM IR提升器的技术问询

如何验证LLVM IR中加载变量的值?

问题描述

我正在构建一个将汇编代码转换为LLVM IR的提升器,现在需要找到可行的方法来检查LLVM变量中存储的数据。举个例子,我写了一段代码创建了一个dummy函数,里面只包含一个基本块:先为变量SRC分配内存,把立即数31存进去,再从内存加载到名为loaded的变量。我想确认%loaded变量的值确实是31,请问有什么办法可以做到?

示例C++代码

int main() {
 llvm::LLVMContext context;
 llvm::Type* type = llvm::Type::getVoidTy(context);
 Module* modu = new Module("test", context);
 modu->getOrInsertFunction("dummy",type);
 Function* dummy = modu->getFunction("dummy");
 BasicBlock* block = BasicBlock::Create(context, "entry", dummy);
 IRBuilder<> builder(block);
 llvm::Value* SRC = builder.CreateAlloca(Type::getInt32Ty(context), nullptr);
 llvm::Value* s = builder.CreateStore(llvm::ConstantInt::get(context, llvm::APInt(/*nbits*/32, 31, true)), SRC, /*isVolatile=*/false);
 llvm::Value* loaded = builder.CreateLoad(SRC, "loaded");
 builder.CreateRetVoid();
 PassManager <llvm::Module>PM;
 llvm::AnalysisManager <llvm::Module>AM;
 verifyFunction(*(modu->getFunction("dummy")), &llvm::errs());
 verifyModule(*modu, &llvm::errs());
 PassBuilder PB;
 PB.registerModuleAnalyses(AM);
 PM.addPass(PrintModulePass());
 PM.run(*modu, AM);
}

生成的LLVM IR输出

; ModuleID = 'test'
source_filename = "test"
define void @dummy() {
entry:
 %0 = alloca i32, align 4
 store i32 31, i32* %0, align 4
 %loaded = load i32, i32* %0, align 4
 ret void
}

解决方案

很高兴帮你解决这个问题!针对你想验证%loaded变量值的需求,有几种实用的方法,根据你的场景选择即可:

方法一:编写LLVM静态分析Pass(编译期验证)

如果不需要运行程序,只想在编译期通过分析IR来验证值,编写一个自定义的分析Pass是最适合的。这个Pass可以遍历IR指令,追踪Load操作的来源,确认存储的值是否符合预期。

下面是一个简单的Pass示例,它会找到Load指令并检查对应的Store值:

#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassManager.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/CGSCCPassManager.h"

using namespace llvm;

struct ValueCheckerPass : public PassInfoMixin<ValueCheckerPass> {
  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
    for (BasicBlock &BB : F) {
      for (Instruction &I : BB) {
        // 找到所有Load指令
        if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
          Value *ptrOperand = LI->getPointerOperand();
          // 遍历这个指针的所有使用者,查找对应的Store指令
          for (User *user : ptrOperand->users()) {
            if (StoreInst *SI = dyn_cast<StoreInst>(user)) {
              if (SI->getPointerOperand() == ptrOperand) {
                Value *storedVal = SI->getValueOperand();
                // 如果存储的是常量整数,直接读取值
                if (ConstantInt *constVal = dyn_cast<ConstantInt>(storedVal)) {
                  errs() << "找到Load指令: " << *LI << "\n";
                  errs() << "对应的存储值为: " << constVal->getSExtValue() << "\n";
                  // 这里添加验证逻辑,判断是否等于31
                  if (constVal->getSExtValue() == 31) {
                    errs() << "✅ 验证通过:%loaded的值确实是31\n";
                  }
                }
              }
            }
          }
        }
      }
    }
    return PreservedAnalyses::all();
  }

  static bool isRequired() { return true; }
};

// 注册Pass,方便opt工具调用
extern "C" LLVM_ATTRIBUTE_WEAK PassPluginLibraryInfo llvmGetPassPluginInfo() {
  return {
    LLVM_PLUGIN_API_VERSION, "ValueCheckerPass", "v0.1",
    [](PassBuilder &PB) {
      PB.registerPipelineParsingCallback(
        [](StringRef Name, FunctionPassManager &FPM, ArrayRef<PassBuilder::PipelineElement>) {
          if (Name == "value-checker") {
            FPM.addPass(ValueCheckerPass());
            return true;
          }
          return false;
        }
      );
    }
  };
}

使用方式:

  1. 把这个Pass编译成动态库(比如libValueCheckerPass.so)。
  2. 用你的代码生成LLVM IR的.bc文件。
  3. 用opt工具运行Pass:opt -load-plugin libValueCheckerPass.so -passes="value-checker" test.bc -disable-output,就能看到验证结果。

方法二:通过LLVM解释器(lli)运行并打印值

如果可以运行生成的IR,这是最直接的验证方式。你只需要修改代码,添加打印loaded变量的指令,然后用lli运行IR即可。

修改你的代码,在builder.CreateRetVoid();之前添加:

// 添加打印指令
builder.CreatePrint(loaded);

重新生成IR后,用lli test.ll运行,终端会输出31,直观确认值的正确性。

方法三:使用LLDB调试(适合复杂场景)

如果你的场景更复杂,需要调试整个流程,可以给变量添加调试信息,然后用LLDB加载生成的可执行文件,设置断点查看变量值。不过这种方法需要生成可执行文件,步骤稍多,但适合深入调试。


内容的提问来源于stack exchange,提问作者hany erfan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:17:43