Llvm Clang如何为函数参数生成代码?
在函数中,我想知道参数是如何传递到函数体的,以便跟踪参数流。我尝试了一个简单的代码,发现每个参数似乎都有一个Llvm Clang如何为函数参数生成代码?,llvm,static-analysis,callstack,llvm-ir,Llvm,Static Analysis,Callstack,Llvm Ir,在函数中,我想知道参数是如何传递到函数体的,以便跟踪参数流。我尝试了一个简单的代码,发现每个参数似乎都有一个alloc-store模式,我想知道它是否正确 演示代码是 int add(int x, int y){ return x+y; } 它生成的llvm ir是: ; Function Attrs: nounwind uwtable define i32 @add(i32 %x, i32 %y) #0 { %1 = alloca i32, align 4 %2 = allo
alloc
-store
模式,我想知道它是否正确
演示代码是
int add(int x, int y){
return x+y;
}
它生成的llvm ir是:
; Function Attrs: nounwind uwtable
define i32 @add(i32 %x, i32 %y) #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 %x, i32* %1, align 4
store i32 %y, i32* %2, align 4
%3 = load i32, i32* %1, align 4
%4 = load i32, i32* %2, align 4
%5 = add nsw i32 %3, %4
ret i32 %5
}
在这个例子中我们可以看到
alloc
指令来定义
局部变量alloc
指令之后,使用store
指令
赋值alloc
和store
模式中生成的?或者LLVM究竟如何处理这些参数李>
参数的顺序取决于它所使用的约定
我认为这种模式适用于没有编译时优化的代码;但是,如果改为使用-O3(或任何应用mem2reg优化的工具)编译代码,则此模式将被优化: (clang-emit llvm-S-O0 add.c) (opt-mem2reg add.ll-o add_m.ll) 因此,如果您正在控制正在分析的所有代码,那么您可以依赖此模式。相反,我建议您使用LLVMAPI来获取函数参数。下面的代码遍历函数F的参数,并在转换为值后打印它们
for (auto AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI)
{
Value* v = &*AI;
errs() << *v << "\n";
}
for(自动AI=F->arg_开始(),AE=F->arg_结束();AI!=AE;++AI)
{
值*v=&*AI;
errs()谢谢你,Brian。我试过了你说的,但它打印出来的像i32%x
。我想知道如何测试两个值是否相等,例如,在二进制文件中,每个指针都存储它指向的地址。这是一个不同的问题。检索了每个函数参数的值*后,你就可以使用它进行进一步的分析了是。这可能是静态的,就像最初标记的那样,在这种情况下,您可能需要构造一个控制流图,并通过每个函数使用变量。动态地,您可以通过添加额外的IR来检查是否相等,该IR检查条目上的值,或者通过就地构造比较或将值传递给单独的支持路由ines。我的示例旨在展示一种简单的方法来最初访问这些值并对其进行处理。感谢您的指导。次要注释:您似乎在问clang如何生成LLVM IR,而不是LLVM如何生成代码。@IsmailBadawi感谢您的注释,我已经编辑了这个问题。
define i32 @add(i32 %x, i32 %y) #0 {
%1 = add nsw i32 %y, %x
ret i32 %1
}
for (auto AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI)
{
Value* v = &*AI;
errs() << *v << "\n";
}