18

我正在寻找一种工具来静态生成 Linux 内核的调用图(对于给定的内核配置)。生成的调用图应该是“完整的”,因为所有调用都包括在内,包括我们可以假设的潜在间接调用,在 Linux 内核的情况下,这些调用只能通过使用函数指针来完成。

例如,这可以通过分析函数指针类型来完成:这种方法会导致图中出现多余的边,但这对我来说没关系。

ncc似乎实现了这个想法,但是我没有成功地使它在 3.0 内核上工作。还有其他建议吗?

我猜这种方法也可能导致在使用函数指针强制转换的情况下丢失边缘,所以我也想知道这是否可能在 Linux 内核中。

附带说明一下,似乎还有其他工具能够对源代码进行语义分析以推断潜在的指针值,但是 AFAICT,它们都不是设计用于 Linux 内核等项目的。

任何帮助将非常感激。

4

1 回答 1

5

我们已经完成了全局指向分析(使用间接函数指针)和 2600 万行(18000 个编译单元)的单体 C 系统的完整调用图构建。

我们使用我们的DMS 软件再造工具包、它的C 前端相关的流分析机器来做到这一点。指向分析机制(和其他分析)是保守的;是的,你得到了一些虚假的指向,因此调用边缘。这些是很难避免的。您可以通过提供有关关键功能的某些关键事实以及利用诸如“嵌入式系统 [和操作系统] 在调用图中往往没有循环”之类的知识来帮助此类分析器,这意味着您可以消除其中的一些。当然,你必须允许例外;我的寓意:“在大系统中,一切都会发生。”

特定问题包括使用特定于该特定软件的特殊加载方案动态加载(!)C 模块,但这只是增加了问题。

对函数指针的强制转换不应该丢失边缘;保守的分析应该简单地假设强制转换指针匹配系统中具有对应于强制转换结果的签名的任何函数。更成问题的是产生某种兼容签名的强制转换。如果在被调用的实际函数接受 int 时将函数指针转换为 void* foo(uint),则分析点必然会保守地选择错误的函数。你不能为此责怪分析仪。演员就在这种情况下。是的,我们在2600万行系统中看到了这种垃圾。

这无疑是分析 Linux 的正确规模(我认为只有 800 万行左右 :-)。但是我们还没有专门在 Linux 上尝试过。

设置此工具很复杂,因为您必须捕获有关编译本身的所有详细信息,尤其是要生成的 Linux 内核的配置。因此,您几乎必须拦截编译器调用以获取命令行开关等。

于 2012-02-27T22:20:55.613 回答