如何从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 中间 表示      更新时间:2023-10-16

我正在尝试使用LLVM构建代码分析工具的简单版本。

我有几个.ll文件,其中包含某些程序的中间LLVM表示。

如何从 LLVM 的中间表示中获取在程序的每个函数中执行的函数调用列表?

我拥有的输入参数是 LLVM:模块类的实例,它表示程序。然后,我使用函数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
  }
}

这是我们工作代码的一个片段:

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可以通过类似的方式获得。

谷歌CallInst vs InvokeInst并了解带有或不带有调用函数的函数。如果函数没有被调用的函数,则这是间接调用。当源代码而不是直接调用函数而是调用函数指针时,间接调用会出现在 LLVM IR 中。在C++当某个类通过抽象接口(多态性(运行时,通常会发生这种情况。因此请记住,即使您有调用指令,也并非 100% 总是可以跟踪被调用的函数。