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

Nik*_*391 5 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";
                       }
                    }
                }

}
Run Code Online (Sandbox Code Playgroud)

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

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

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

%4 = call i8* @__cxa_allocate_exception(i64 4) #2
i8* bitcast (i8** @_ZTIi to i8*)
i8* null
Run Code Online (Sandbox Code Playgroud)

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

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

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

com*_*por 1

异常改变了程序的控制流,以便在程序执行期间提供它们的便利。作为操作程序堆栈、执行清理等的运行时构造,它依赖运行时系统支持来履行其职责。因此,存在一个ABI 标准,该标准对跨实现的具体实施方式进行了标准化。

话虽如此,如果您深入研究该规范,您会发现参数就是__cxa_throw 它所抛出的内容。看看这里。上面的片段包含指向已分配异常位置的指针以及类型信息。事实上,如果你申请c++filt_ZTIi你就会得到typeinfo for int

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