Linux内核的静态调用图生成

时间:2012-02-27 19:18:31

标签: linux-kernel function-pointers static-analysis call-graph

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

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

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

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

作为旁注,似乎有其他工具能够对源进行语义分析以推断潜在的指针值,但是AFAICT,它们都没有设计用于Linux内核等项目。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:5)

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

我们使用DMS Software Reengineering ToolkitC Front End及其associated flow analysis machinery来完成此操作。分数分析机制(和其他分析)是保守的;是的,你会得到一些虚假的点,因此会调用边缘。这些很难避免。 您可以通过提供关键功能的某些关键事实来帮助此类分析器,并利用诸如“嵌入式系统[和操作系统]之类的知识在调用图中不会有循环”,这意味着您可以消除其中的一些。当然,你必须允许例外;我的道德:“在大系统中,一切都在发生。”

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

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

这当然是分析Linux的合适尺度(我认为只有800万行左右:-)。但是我们还没有专门在Linux上试过它。

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