ASAN Pass(一)——简单分析

本文主要依据网上现有资料分析以下ASAN的相关源码。源码的调试分析放在续文中。

克隆一份源码(根目录llvm-project,版本CommitID 0156f91f3b0a,此时Clang版本为14)。

git clone --depth=1 https://github.com/llvm/llvm-project

资料—Sanitizer注册

Sanitizer ID信息

Sanitizers.def包含了ASAN的注册信息,Sanitizers.def会在Sanitizers.hstruct SanitizerKind中导入(include),也就是说Sanitizers.h维护了注册信息的数据结构,Sanitizers.def包含了注册信息的具体内容。

// clang\include\clang\Basic\Sanitizers.def
SANITIZER("address", Address)

Sanitizers.defclang\include\clang\Basic\Sanitizers.h导入并解释。

Santizer参数信息

// clang\include\clang\Driver\SanitizerArgs.h
...
class SanitizerArgs {
  ...
  bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); }
  ...
};
...

添加支持的Santizer ID(如果Santizer无需运行时支持,不含ASAN)

// clang\lib\Driver\ToolChain.cpp
SanitizerMask ToolChain::getSupportedSanitizers() const {...}

静态看ASAN源码结构

相关资料如AddressSanitizer算法及源码解析LLVM每日谈之六 LLVM的源码结构过于简短。

ASAN主体内容位于llvm\lib\Transforms\Instrumentation\AddressSanitizer.{cpp, h}

AddressSanitizer.h

首先观察AddressSanitizer.h,里面包含了ASanGlobalsMetadataAnalysis(模块Pass)、AddressSanitizerPass(函数Pass)和ModuleAddressSanitizerPass(模块Pass),这三者继承自PassInfoMixin,使用New PassManager,用到了称为静态多态的CRTP。(还包含了用于初始化构建LegacyPassSanitizer的函数createAddressSanitizerFunctionPasscreateModuleAddressSanitizerLegacyPassPass

  1. ASanGlobalsMetadataAnalysis负责处理全局元数据GlobalsMetadata
  2. AddressSanitizerPass通过struct AddressSanitizer实现插桩任务
  3. ModuleAddressSanitizerPass通过class ModuleAddressSanitizer实现插桩任务。
  4. (后两者会通过ASanGlobalsMetadataAnalysis获取全局元数据。)

AddressSanitizer.cpp

包含ASanGlobalsMetadataWrapperPass模块Pass、AddressSanitizerLegacyPass函数Pass、ModuleAddressSanitizerLegacyPass模块Pass,使用Legacy PassManager。

  1. ASanGlobalsMetadataWrapperPass会处理全局元数据GlobalsMetadata
  2. AddressSanitizerLegacyPass通过AddressSanitizer完成具体功能
  3. ModuleAddressSanitizerLegacyPass通过ModuleAddressSanitizer完成具体功能。
  4. (后两者会通过ASanGlobalsMetadataWrapperPass获取全局元数据。)

Legacy Pass通过INITIALIZE_PASS宏展开(如展开定义initializeAddressSanitizerLegacyPassPass(),并间接被createAddressSanitizerFunctionPass调用),用于注册对应Pass。

// llvm\lib\Transforms\Instrumentation\AddressSanitizer.cpp
INITIALIZE_PASS(ASanGlobalsMetadataWrapperPass, "asan-globals-md",
                "Read metadata to mark which globals should be instrumented "
                "when running ASan.",
                false, true)

INITIALIZE_PASS_BEGIN(
    AddressSanitizerLegacyPass, "asan",
    "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false,
    false)
INITIALIZE_PASS_DEPENDENCY(ASanGlobalsMetadataWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(
    AddressSanitizerLegacyPass, "asan",
    "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false,
    false)

INITIALIZE_PASS(
    ModuleAddressSanitizerLegacyPass, "asan-module",
    "AddressSanitizer: detects use-after-free and out-of-bounds bugs."
    "ModulePass",
    false, false)

后续

LLVM ASAN【源码分析】(二)》描述了调试环境的搭建。

LLVM ASAN【源码分析】(三)》中描述了gdb调试分析ASAN源码的内容。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值