如何从 LLVM 的中间表示中获取在程序的每个函数中执行的函数调用列表?
How can I get the list of function calls that are performed in each function of a program, from the intermediate representation of LLVM?
我正在尝试使用 LLVM 构建一个简单版本的代码分析工具。
我有几个 .ll 文件,其中包含某些程序的中间 LLVM 表示。
如何从 LLVM 的中间表示中获取程序的每个函数中执行的函数调用列表?
我的输入参数是 LLVM 的一个实例:代表程序的模块 class。然后,我使用函数 getFunctionList () 获取程序中存在的函数列表。
void getFunctionCalls(const Module *M)
{
// Iterate functions in program
for (auto curFref = M->getFunctionList().begin(), endFref = M->getFunctionList().end();
curFref != endFref; ++curFref) {
// For each function
// Get list of function calls
}
}
这是我们工作代码的片段here:
for (auto &module : Ctx.getModules()) {
auto &functionList = module->getModule()->getFunctionList();
for (auto &function : functionList) {
for (auto &bb : function) {
for (auto &instruction : bb) {
if (CallInst *callInst = dyn_cast<CallInst>(&instruction)) {
if (Function *calledFunction = callInst->getCalledFunction()) {
if (calledFunction->getName().startswith("llvm.dbg.declare")) {
还要记住,还有调用指令InvokeInst
,可以通过类似的方式获得。
Google CallInst vs InvokeInst
并了解有或没有被调用函数的函数。如果函数没有被调用函数,则这是间接调用。当源代码不是直接调用函数而是调用函数指针时,间接调用出现在 LLVM IR 中。在 C++ 中,当某些 class 通过抽象接口(多态性)进行操作时,通常会发生这种情况。因此请记住,即使您有调用指令,也并非总是可以 100% 跟踪被调用函数。
我正在尝试使用 LLVM 构建一个简单版本的代码分析工具。
我有几个 .ll 文件,其中包含某些程序的中间 LLVM 表示。
如何从 LLVM 的中间表示中获取程序的每个函数中执行的函数调用列表?
我的输入参数是 LLVM 的一个实例:代表程序的模块 class。然后,我使用函数 getFunctionList () 获取程序中存在的函数列表。
void getFunctionCalls(const Module *M)
{
// Iterate functions in program
for (auto curFref = M->getFunctionList().begin(), endFref = M->getFunctionList().end();
curFref != endFref; ++curFref) {
// For each function
// Get list of function calls
}
}
这是我们工作代码的片段here:
for (auto &module : Ctx.getModules()) {
auto &functionList = module->getModule()->getFunctionList();
for (auto &function : functionList) {
for (auto &bb : function) {
for (auto &instruction : bb) {
if (CallInst *callInst = dyn_cast<CallInst>(&instruction)) {
if (Function *calledFunction = callInst->getCalledFunction()) {
if (calledFunction->getName().startswith("llvm.dbg.declare")) {
还要记住,还有调用指令InvokeInst
,可以通过类似的方式获得。
Google CallInst vs InvokeInst
并了解有或没有被调用函数的函数。如果函数没有被调用函数,则这是间接调用。当源代码不是直接调用函数而是调用函数指针时,间接调用出现在 LLVM IR 中。在 C++ 中,当某些 class 通过抽象接口(多态性)进行操作时,通常会发生这种情况。因此请记住,即使您有调用指令,也并非总是可以 100% 跟踪被调用函数。