LLVM在运行时获取声明函数的参数值

时间:2017-04-25 16:22:08

标签: c++ c llvm

我正在编写一个LLVM传递,需要将值传递给声明的函数,然后将其打印出来。请注意,已在LLVM IR中调用声明的函数。

我编写了一个模块传递来迭代程序中的所有指令。获取指令中被调用函数的参数的片段如下:

for (auto &B: F){
                for (auto &I: B){
                    if (auto *InvokeI = dyn_cast <InvokeInst>(&I)) { 
                       if (InvokeI->getCalledFunction()->getName().str() == "function_name") {
                            errs() << "===\n";
                            errs() << *(InvokeI->getOperand(0)) <<"\n";
                            errs() << *(InvokeI->getOperand(1)) <<"\n";
                            errs() << *(InvokeI->getOperand(2)) <<"\n";
                       }
                    }
                }

}

但是,如果调用函数的LLVM IR看起来像这样:

invoke void @function_name(i8* %4, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #5
          to label %36 unwind label %6

然后我上面的代码片段输出:

%4 = call i8* @__cxa_allocate_exception(i64 4) #2
i8* bitcast (i8** @_ZTIi to i8*)
i8* null

而不是输出函数调用期间传递的实际值。

我的问题是如何获取运行时期间传递的值。有没有办法可以将函数体添加到没有返回任何内容的声明函数中?

对此有任何帮助表示赞赏, 谢谢

1 个答案:

答案 0 :(得分:1)

异常会更改程序的控制流程,以便在程序执行期间提供其功能。作为操作程序堆栈,执行清理等的运行时构造,它依赖于runtime system支持来执行其职责。出于这个原因,有一个ABI standard标准化了如何在各个实现中采取行动的方面。

话虽如此,如果你深入研究那个规范,你会发现__cxa_throw 的论据是它被抛出的内容。看看here。上面的片段包含指向已分配异常的位置的指针以及类型信息。实际上,如果您在c++filt上应用_ZTIi,则会获得typeinfo for int

换句话说,语句1抛出的整数throw 1被包装到运行时期间要访问的异常对象(即内存位置)中。关于这些值存储在何处以及如何存储的进一步具体细节在上述规范中。我没有看到静态访问特定值的简单方法,因为可能有哪些异常处于活动状态,并且具有哪些确切内容依赖于执行期间程序的状态(例如调用堆栈等)。