我正在编写一个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
而不是输出在函数调用期间传递的实际值.
我的问题是我们如何获取运行时期间传递的值.有没有办法我们可以将函数体添加到声明的函数,什么都不返回?
对此有任何帮助表示赞赏,
谢谢
最佳答案 例外更改程序的控制流程,以便在程序执行期间提供其功能.作为操作程序堆栈,执行清理等的运行时构造,它依赖于
runtime system支持来执行其职责.出于这个原因,有一个
ABI standard标准化了如何在各个实现中采取行动的方面.
话虽如此,如果你深入研究那个规范,你会发现__cxa_throw的参数是它被抛出的.看看here.上面的片段包含指向已分配异常的位置的指针以及类型信息.实际上,如果在_ZTIi上应用c filt,则会获得int的typeinfo.
换句话说,由语句throw 1抛出的整数1被包装到要在运行时期间访问的异常对象(即,存储器位置)中.关于这些值存储在何处以及如何存储的进一步具体细节在上述规范中.我没有看到静态访问特定值的简单方法,因为可能有什么异常是活动的,并且具有什么确切内容依赖于执行期间程序的状态(例如调用堆栈等).