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

LLVM FunctionPass开发:实现目标函数存在性检查

刚好做过类似的LLVM Pass开发,给你整理个简洁清晰的实现方案,完全贴合你已经准备好的信息提取逻辑:

实现LLVM FunctionPass检查目标函数的具体方案

1. 核心逻辑梳理

你已经拿到了待检查函数和目标函数的名称、返回类型、参数数量+类型,核心就是在FunctionPass遍历每个函数的过程中,对这几项信息逐一比对——全匹配就判定找到了目标函数,逻辑非常直接。

2. 具体代码实现步骤

第一步:定义你的FunctionPass类

继承llvm::FunctionPass,重写runOnFunction方法(这是遍历每个函数的核心入口)。你可以把目标函数的信息作为类的成员变量,要么硬编码(适合固定目标的场景),要么通过构造函数传入(动态目标更灵活)。

第二步:实现精准的信息比对逻辑

在runOnFunction里,对当前遍历到的函数,按以下顺序比对(从快到慢,提前过滤不匹配的函数,提升效率):

  • 先比函数名称:用func.getName().str()拿到函数名的字符串,和目标名称快速对比,不匹配直接跳过。
  • 再比返回类型:LLVM的Type对象是全局单例,直接用func.getReturnType()和目标返回类型用==判断就行,不用自己解析类型字符串。
  • 最后比参数:先看参数数量是否一致(func.arg_size()),然后逐个遍历参数的类型,和目标参数类型逐一比对,顺序也要对应上(毕竟foo(int, float)和foo(float, int)是完全不同的函数)。

第三步:完整代码模板

给你一个可直接复用的简洁模板,你可以根据自己的需求调整:

#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

namespace {
struct TargetFuncChecker : public FunctionPass {
  static char ID;
  // 目标函数信息,这里示例用硬编码,你可以改成构造函数传入
  std::string TargetName = "my_target_func";
  Type* TargetRetTy;
  std::vector<Type*> TargetParamTys;

  TargetFuncChecker() : FunctionPass(ID) {}

  // 用于动态设置目标函数类型信息的方法
  void setTargetInfo(Type* RetTy, std::vector<Type*> ParamTys) {
    TargetRetTy = RetTy;
    TargetParamTys = ParamTys;
  }

  bool runOnFunction(Function &F) override {
    // 1. 快速过滤名称不匹配的函数
    if (F.getName().str() != TargetName) {
      return false; // 返回false表示没修改IR,继续遍历
    }

    // 2. 比对返回类型
    if (F.getReturnType() != TargetRetTy) {
      errs() << "Name matches but return type mismatch: " << F.getName() << "\n";
      return false;
    }

    // 3. 比对参数数量和类型
    if (F.arg_size() != TargetParamTys.size()) {
      errs() << "Name matches but param count mismatch: " << F.getName() << "\n";
      return false;
    }

    unsigned idx = 0;
    for (Argument &Arg : F.args()) {
      if (Arg.getType() != TargetParamTys[idx]) {
        errs() << "Name matches but param " << idx << " type mismatch: " << F.getName() << "\n";
        return false;
      }
      idx++;
    }

    // 所有信息匹配,输出结果
    errs() << "✅ Found target function: " << F.getName() << "\n";
    return false;
  }
};
} // namespace

char TargetFuncChecker::ID = 0;
static RegisterPass<TargetFuncChecker> X("check-target", "Check for existence of target function",
                                         false /* Doesn't modify CFG */,
                                         false /* Not an analysis pass */);

3. 关键细节提示

  • Type对象的可靠性:LLVM的Type是全局唯一实例,直接用==对比完全准确,比解析类型字符串靠谱得多,还能避免字符串解析的各种坑。
  • 参数顺序不能忽略:函数签名的参数顺序是匹配的核心,一定要按顺序比对每个参数的类型。
  • Pass注册:最后通过RegisterPass把你的Pass注册到LLVM系统,这样才能用opt工具加载运行。
  • 动态传参优化:如果你的目标函数信息是从外部获取的(比如配置文件或者命令行参数),可以给Pass添加带参数的构造函数,或者在初始化阶段读取配置,不用硬编码目标信息。

4. 运行方式

把代码编译成LLVM Pass的动态库后,用opt工具运行:

opt -load ./libTargetFuncChecker.so -check-target < input.bc > /dev/null

运行后就能在控制台看到是否找到目标函数的提示了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:12:35