【问题标题】:how do call graphs resolve function pointers?调用图如何解析函数指针?
【发布时间】:2010-12-04 17:20:37
【问题描述】:

我正在使用 perl 脚本为 C 实现一个调用图程序。我想知道如何使用“objdump”的输出来解析函数指针的调用图? 不同的调用图应用程序如何解析函数指针? 函数指针是在运行时解析还是可以静态完成?

编辑 调用图如何解决程序静态评估中的循环问题?

【问题讨论】:

标签: c function-pointers call-graph objdump


【解决方案1】:

当调用语句明确提到 B 时,很容易构建 A-calls-B 的调用图。正如您所注意到的,处理间接调用要困难得多。

静态分析工具通过在程序数据流(程序间和程序内[“全局”])之间传播指针分配/副本/算术来形成指针变量内容的估计,使用各种计划,通常是保守的(“你得到了太多”)。

如果没有这样的估计,您将无法知道指针包含什么,因此根本无法做出有用的预测(好吧,您可以使用最终的保守估计它会去任何地方,但我认为您已经拒绝了解决方案)。

我们的DMS Software Reengineering Toolkitstatic control/dataflow/points-to/call graph analysis,它已应用于庞大的C 代码系统(~2500 万行),并产生了这样的调用图。执行此操作的机器 相当复杂,但您可以在编译器文献的高级主题中找到它。我怀疑你想在 Perl 中实现它。

如果您有源代码,这会更容易,因为您至少可以可靠地知道什么是代码,什么不是。您正在尝试对目标代码执行此操作,这意味着您甚至无法消除数据。

【讨论】:

  • 如果我使用源代码查找调用图,C程序如何解析不同文件中的方法。例如:-fileA中定义的方法A和fileB中的方法B调用图如何遍历不同的文件?
  • 该工具读取所有源文件并计算所有文件内和跨所有文件的数据流。从概念上讲,这并不难。这就像将所有源代码放在一个文件中一样:-} 在实现上,您可能会面临读取 18,000 个编译单元(及其头文件)的问题,这意味着您将面临一场大规模的斗争。
  • 函数指针是否总是在运行时解析?是否有可能我以某种方式静态链接并获取其反汇编输出并对其进行解析,然后也获取这些函数的调用图?
  • 这里有些混乱。函数指针仅在运行时的特定时刻获取特定值 0x17234983,就像整数变量在特定时刻获取特定值一样。对“指针值”的静态分析实际上产生了一个集合可能的抽象值{&foo, &bar, &baz}指针可能采用在运行时。您称图为“静态分析”,其中 main { ... foo(x); ... (*p)() ...}说明main可以直接调用foo,main可以通过p调用foo/bar/baz。没有任何保证调用图中的 any 函数被实际调用。
  • ...所以不,你不能做一个静态链接和解析函数指针。如果您不清楚这一点,您可能不应该构建调用图。
【解决方案2】:

使用函数指针是选择在运行时调用的实际函数的一种方式,因此一般来说,不可能知道静态实际会发生什么。

但是,您可以查看所有可能调用的函数,并可能以某种方式显示它们。回调通常具有足够独特的签名(并非总是如此)。

如果你想做得更好,你必须分析源代码,看看哪些函数分配给了开始的指针。

【讨论】:

  • C 语言没有太多的元数据,这使得这种静态分析几乎不可能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-05
  • 2014-07-26
  • 2013-01-18
  • 2018-05-26
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
相关资源
最近更新 更多