ASAN Pass源码分析(六)——全局变量插桩

插桩功能由ModuleAddressSanitizer::instrumentModule实现。这是个模块插桩,主要以全局变量插桩为主,也包括ASAN其它功能中所需的模块插桩功能。这里主要关注全局变量的处理。

在此之前,编译器前端(parseSanitizerKinds())会识别-fsanitize=address标识,在Sanitizer类型集合中记录当前是AddressSanitzer。CodeGen会开启一个将全局变量元数据传给ASan的功能(SanitizerMD->reportGlobalToASan()),这些元数据记录了源码位置、是否动态初始化等信息。

主要步骤包括:

  1. 将原来的全局变量转变成一个结构体,内部包含了原来的全局变量和一个右Redzone,将原来被使用的全局变量替换(replaceAllUsesWith)成新的结构体内的全局变量,之后将所有的新全局变量结构体通过调用__asan_register_globals进行poison
  2. 构建asan.module_ctorctor函数),优先级为1。IR代码如下。里面除了有__asan_register_globals,还有必要的ASAN初始化函数__asan_init
define internal void @asan.module_ctor() {
  call void @__asan_init()
  call void @__asan_version_mismatch_check_v8()
  call void @__asan_register_globals(i64 ptrtoint ([4 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 4)
  ret void
}
  1. 构建asan.module_dtor
define internal void @asan.module_dtor() {
  call void @__asan_unregister_globals(i64 ptrtoint ([4 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 4)
  ret void
}
  1. 将所有原来的ctor函数内的首尾插入__asan_before/after_dynamic_init
define internal void @_GLOBAL__sub_I_a.cpp() #0 section ".text.startup" {
entry:
  call void @__asan_before_dynamic_init(i64 ptrtoint ([6 x i8]* @___asan_gen_.14 to i64))
  call void @__cxx_global_var_init()
  call void @__asan_after_dynamic_init()
  ret void
}

关于运行时具体注册全局变量,请看《ASAN Runtime源码分析(二)——注册全局变量》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值