llvm - 在某些函数 llvm 中查找局部变量
问题描述
给定 LLVM 位代码中的某个函数,我如何识别它的局部变量?例如,来自 GNU coreutilsecho
实用程序的以下片段,我不知道如何do_v9
在主要 IR 代码的范围内找到变量。
int main (int argc, char **argv)
{
bool display_return = true;
bool posixly_correct = getenv ("POSIXLY_CORRECT");
....
bool do_v9 = false;
}
我注意到 LLVM 为局部变量创建了一个元数据,称为DILocalVariable
,其中该变量将替换为以字母开头的数字i
。
!686 = !DILocalVariable(name: "posixly_correct", scope: !678, file: !10, line: 114, type: !64)
!688 = !DILocalVariable(name: "do_v9", scope: !678, file: !10, line: 122, type: !64)
因此,主 IR 代码既不包含变量do_v9
,也不包含其对应的元数据!688
,除了主函数定义之外的值。我的分析循环了主函数中的指令,但我不知道如何在我的迭代中找到这个局部变量。我在哪里使用 LLVM 6.0。
; Function Attrs: nounwind uwtable
define i32 @main(i32, i8**) #9 !dbg !678 {
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i8**, align 8
%6 = alloca i8, align 1
%7 = alloca i8, align 1
%8 = alloca i8, align 1
%9 = alloca i8, align 1
%10 = alloca i32
%11 = alloca i8*, align 8
%12 = alloca i64, align 8
%13 = alloca i8*, align 8
%14 = alloca i8, align 1
%15 = alloca i8, align 1
解决方案
如果您想使用编译器发出的调试信息从 llvm IR 中的源代码中识别局部变量,您可以通过查看源代码中对@llvm.dbg.declare
or@llvm.dbg.addr
内部函数的调用来做到这一点。对于函数中的每个局部变量,您将有一个或另一个(但不是两者;llvm.dbg.addr 函数替换较新版本的 llvm 中的 llvm.dbg.declare)一次。例如,如果您有以下情况:
%1 = alloca i32, align 4
call void @llvm.dbg.addr(metadata i32* %1, metadata !2, metadata ...), !dbg ...
!2 = !DILocalVariable(name: "i", ...)
这告诉我们局部变量 i 对应于地址为 %1 的 alloca 分配的堆栈位置。
请注意,上面的 ... 仅代表我们在此上下文中不关心的内容。
推荐阅读
- python - Heroku docker 镜像需要一个开放的端口
- javascript - 如果具有相同的ID,如何将数组对象值合并到数组
- asp.net-mvc - 在 MVC 中保留页面刷新时的部分视图信息
- json - 如何在 grails 控制器中处理 JSONObject 中的 BigInteger 帖子?
- java - 如何从适配器回收视图传递/获取值复选框到另一个活动
- amazon-web-services - 当我取消注释我的一个导入时,AWS lambda“无法导入模块'lambda_function”
- vue.js - 计算属性中的副作用
- python-3.x - 使用多处理或线程或异步进行多任务处理,具体取决于场景
- java - 在 Maven 项目的 n 层架构中,我应该在哪里编写 Spring MVC 配置类?
- python - 访问 class.lambda 时语法无效