6

gcc 和 GNU binutils 有没有办法标记一些函数,如果使用它们会在链接时产生错误?我的情况是我有一些库函数,为了与现有二进制文件兼容,我没有删除它们,但我想确保没有新编译的二进制文件尝试使用这些函数。我不能只使用编译时 gcc 属性,因为有问题的代码会忽略我的标头并使用configure脚本检测函数的存在并自行对其进行原型设计。我的目标是为不良configure脚本生成链接时错误,以便它们停止检测函数的存在。

编辑:一个想法..使用程序集.type为入口点指定错误是否与动态链接器兼容,但在尝试链接新程序时会产生链接错误?

4

3 回答 3

2

FreeBSD 9.x 的功能非常接近您想要的ttyslot()功能。这个函数对 utmpx 没有意义。诀窍是这个符号只有非默认版本。因此,ld不会找到它,但 rtld 会在运行旧二进制文件时找到版本化定义。我不知道如果旧二进制文件具有未版本化的引用会发生什么,但如果只有一个定义可能是明智的。

例如,

__asm__(".symver hidden_badfunc, badfunc@MYLIB_1.0");

通常,还会有一个默认版本,例如

__asm__(".symver new_badfunc, badfunc@@MYLIB_1.1");

或通过与 Solaris 兼容的版本脚本,但诀窍是不要添加一个。

通常,asm 指令被包装到一个宏中。

这个技巧依赖于 GNU 扩展来使用.symver汇编指令定义符号版本,因此它可能只适用于 Linux 和 FreeBSD。与 Solaris 兼容的版本脚本每个符号只能表达一个定义。

更多信息:Ulrich Drepper 的“如何编写共享库”中的.symver指令,在http://gitorious.org/freebsd/freebsd/commit/3f59ed0d571ac62355fc2bde3edbfe9a4e722845弃用 ttyslot() 的提交info gas

于 2011-01-15T00:43:30.173 回答
0

一个想法可能是生成一个包含这些符号但具有意外属性的存根库。

  • 也许创建具有函数名称的对象,因此配置阶段的链接器可能会抱怨符号不兼容
  • 创建具有dont_use_symbol_XXX永远不会解决的依赖“”的函数
  • 或伪造具有全局索引的 .a 文件,该文件将具有您的功能,但存档中的 .o 成员格式错误
于 2011-01-14T20:17:20.777 回答
0

为您不希望人们使用的已弃用函数生成链接时错误的最佳方法是确保库中不存在已弃用的函数 - 这使它们成为“已弃用”之外的一个阶段。

也许您可以提供一个辅助库,其中包含不推荐使用的功能;不注意的人可以链接辅助库,但主流的人不会使用辅助库,因此不会使用这些功能。但是,它仍然超出了“弃用”阶段。

获取链接时警告很棘手。显然,GCC 对某些功能(mktemp()等)执行此操作,如果您运行使用gets(). 我不知道他们做了什么来实现这一点。


根据评论,我认为您需要在编译时解决问题,而不是等到链接时或运行时。

GCC 属性包括(来自 GCC 4.4.1 手册):

error ("message")

如果在函数声明中使用此属性,并且未通过死代码消除或其他优化消除对此类函数的调用,则会诊断出包含消息的错误。这对于编译时检查很有用,尤其是与 __builtin_constant_p 和内联函数一起使用时,无法通过 extern char [(condition) 来检查内联函数参数?1:-1];技巧。虽然可以保留函数未定义并因此调用链接故障,但使用此属性时,即使存在内联函数或未发出调试信息,也会更早地诊断出问题并提供调用的确切位置。

warning ("message")

如果在函数声明中使用此属性,并且没有通过死代码消除或其他优化消除对此类函数的调用,则会诊断出包含消息的警告。这对于编译时检查很有用,尤其是与 __builtin_constant_p 和内联函数一起使用。虽然可以在 .gnu.warning* 部分中使用消息定义函数,但使用此属性时,即使存在内联函数或不发出调试信息,也会更早地诊断出问题并提供调用的确切位置。

如果配置程序忽略这些错误,它们就会被破坏。这意味着无法使用这些函数编译新代码,但现有代码可以继续使用库中已弃用的函数(直到需要重新编译)。

于 2011-01-14T19:37:08.927 回答