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

如何在LLVM Pass中遍历IR文件调试符号并解析DICompositeType元数据

LLVM Pass 遍历调试元数据(含DICompositeType)实现方案

实现思路

所有调试元数据都挂载在Module的llvm.dbg.cu命名元数据下,所有编译单元(DICompileUnit)都会在此处注册,你可以从编译单元出发遍历所有类型元数据,也可以全局遍历Module的所有元数据节点过滤得到目标DICompositeType。

必要头文件

#include "llvm/IR/Module.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/BinaryFormat/Dwarf.h"

具体实现步骤

  • 第一步:遍历编译单元获取结构体调试元数据
    从当前Module获取llvm.dbg.cu命名元数据,遍历每一个节点转为DICompileUnit后,过滤得到目标结构体类型的DICompositeType:
    bool runOnModule(Module &M) override {
      NamedMDNode *DbgCUNodes = M.getNamedMetadata("llvm.dbg.cu");
      if (!DbgCUNodes) {
        return false; // 无调试信息直接返回
      }
      for (MDNode *Node : DbgCUNodes->operands()) {
        DICompileUnit *CU = cast<DICompileUnit>(Node);
        // 遍历编译单元下所有保留类型
        for (DIType *Ty : CU->getRetainedTypes()) {
          // 尝试转为DICompositeType
          if (auto *CompositeTy = dyn_cast<DICompositeType>(Ty)) {
            // 过滤结构体类型
            if (CompositeTy->getTag() == dwarf::DW_TAG_structure_type) {
              // 这里就拿到了你要的结构体调试元数据
              errs() << "找到结构体类型: " << CompositeTy->getName().str() << "\n";
              errs() << "定义行号: " << CompositeTy->getLine() << "\n";
              errs() << "大小: " << CompositeTy->getSizeInBits() << "bit\n";
              // 遍历结构体成员
              for (DINode *Elem : CompositeTy->getElements()) {
                if (auto *MemberTy = dyn_cast<DIDerivedType>(Elem)) {
                  errs() << "  成员: " << MemberTy->getName().str() << "\n";
                }
              }
            }
          }
        }
      }
      return false;
    }
    
  • 第二步:DICompositeType与IR StructType关联
    如果你需要对应到getIdentifiedStructTypes()返回的IR结构体类型,可以调用getTypeForDIType接口做映射:
    StructType *IRStructTy = cast<StructType>(CompositeTy->getTypeForDIType(CompositeTy, M.getContext()));
    // 之后就可以和你从getIdentifiedStructTypes拿到的结构体指针做匹配
    
  • 全局遍历补充方案
    如果有部分复合类型没有在编译单元的保留类型中注册,可以直接遍历Module的所有元数据节点过滤,该方式覆盖所有场景但性能略低于从编译单元遍历。

DebugInfoFinder扩展说明

你之前使用的llvm::DebugInfoFinder没有直接返回DICompositeType的接口,但可以继承它扩展功能,它内部已经遍历了所有类型元数据,只需新增接口返回存储DICompositeType的容器即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:45:03