【问题标题】: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 的中间表示中获取在程序的每个函数中执行的函数调用列表?
【发布时间】:2017-04-01 18:33:44
【问题描述】:

我正在尝试使用 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

  }

}

【问题讨论】:

    标签: c++ llvm


    【解决方案1】:

    这是我们工作代码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++ 中,当某些类通过抽象接口(多态性)进行操作时,通常会发生这种情况。所以请记住,即使您有一个调用指令,也不是 100% 总是可以跟踪调用的函数。

    【讨论】:

    • 非常感谢@Stanislav Pankevich!。它对我非常有用。现在我有一个问题。编译该工具时,我收到一条错误消息,指出 CallInst 类的构造函数是私有的。我会在另一个帖子上发表评论。
    • 抱歉混淆了 - 我手动制作了我的示例,并没有更改 CallInst *callInst = dyn_cast&lt;CallInst&gt;(&amp;instruction) 以获得正确的变量名称。我看到你已经在你的后续问题中澄清了。无论如何,我已经编辑了我的答案。
    猜你喜欢
    • 2020-10-04
    • 2017-09-15
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    相关资源
    最近更新 更多