问题 如何使用LLVM生成调用图?


我正在研究为linux内核生成一个包含函数指针的调用图(参见我之前的问题 Linux内核的静态调用图生成 了解更多信息)。我被告知LLVM应该适合这个目的,但我无法在llvm.org上找到相关信息

任何帮助,包括相关文档的指示,将不胜感激。


11366
2018-03-30 08:53


起源



答案:


首先,您必须将内核编译为LLVM IR(而不是本机对象文件)。然后,使用 llvm-ld,将所有IR对象文件合并为一个大型模块。这可能是一件非常棘手的事情,你必须大量修改makefile,但我相信它是可行的。

现在您可以进行分析了。可以使用。生成一个简单的调用图 opt 工具 -dot-callgraph 通过。它不太可能处理函数指针,因此您可能想要修改它。

跟踪将携带函数指针的所有可能的数据流路径是一个相当大的挑战,并且通常情况下是不可能的(如果有任何指向整数强制转换的指针,如果指针存储在复杂的数据结构中,等等)。对于大多数特定情况,您可以尝试实现全局抽象解释,以近似指针的所有可能数据流路径。当然,这不准确,但是你会得到至少一个保守的近似值。


12
2018-03-30 09:29



你真的不想为800万行代码生成一个点调用图。它会覆盖一个网球,如果点可以画它,它不能。除此之外,这是OP对其他问题的答案的一个很好的回应: - }特别强调有趣的函数指针是什么。 - Ira Baxter
@IraBaxter,当然你不想 显示 对于任何大于“你好,世界!”的东西的点调图。但您可能希望使用该.dot文件进行进一步分析。我通常解析.dot文件并将它们存储到数据库中。 - SK-logic
谢谢你指出了 opt 工具。是的,艾拉,我不打算生成调用图的图形表示。以任何可解析的格式使用它是正确的,点格式符合条件。关于函数指针,我被告知LLVM应该能够做一些这些点 - 分析函数指针。我自己并没有考虑清楚地实现这一点。 - addalbx
llvm-ld 已弃用,请使用 llvm-link 或者是黄金插件。 - user


答案:


首先,您必须将内核编译为LLVM IR(而不是本机对象文件)。然后,使用 llvm-ld,将所有IR对象文件合并为一个大型模块。这可能是一件非常棘手的事情,你必须大量修改makefile,但我相信它是可行的。

现在您可以进行分析了。可以使用。生成一个简单的调用图 opt 工具 -dot-callgraph 通过。它不太可能处理函数指针,因此您可能想要修改它。

跟踪将携带函数指针的所有可能的数据流路径是一个相当大的挑战,并且通常情况下是不可能的(如果有任何指向整数强制转换的指针,如果指针存储在复杂的数据结构中,等等)。对于大多数特定情况,您可以尝试实现全局抽象解释,以近似指针的所有可能数据流路径。当然,这不准确,但是你会得到至少一个保守的近似值。


12
2018-03-30 09:29



你真的不想为800万行代码生成一个点调用图。它会覆盖一个网球,如果点可以画它,它不能。除此之外,这是OP对其他问题的答案的一个很好的回应: - }特别强调有趣的函数指针是什么。 - Ira Baxter
@IraBaxter,当然你不想 显示 对于任何大于“你好,世界!”的东西的点调图。但您可能希望使用该.dot文件进行进一步分析。我通常解析.dot文件并将它们存储到数据库中。 - SK-logic
谢谢你指出了 opt 工具。是的,艾拉,我不打算生成调用图的图形表示。以任何可解析的格式使用它是正确的,点格式符合条件。关于函数指针,我被告知LLVM应该能够做一些这些点 - 分析函数指针。我自己并没有考虑清楚地实现这一点。 - addalbx
llvm-ld 已弃用,请使用 llvm-link 或者是黄金插件。 - user