为已弃用的函数生成链接时错误

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

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

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

例如,

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

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

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

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

通常,asm指令包含在宏中。

诀窍取决于使用.symver汇编程序指令定义符号版本的GNU扩展,因此它可能只适用于Linux和FreeBSD。 Solaris兼容版本脚本每个符号只能表示一个定义。

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

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

  • 也许创建具有函数名称的对象,因此配置阶段的链接器可能会抱怨符号不兼容
  • 创建具有从未解析的依赖项“ dont_use_symbol_XXX ”的函数
  • 或假冒.a文件,其全局索引具有您的function,但归档中的.o成员格式错误

为不希望人们使用的已弃用函数生成链接时错误的最佳方法是确保库中不存在已弃用的函数 – 这使得它们超出“已弃用”阶段。

也许你可以提供一个辅助库,其中包含已弃用的function; 不注意的叛逆者可以与辅助图书馆联系,但主流人士不会使用辅助图书馆,因此不会使用这些function。 但是,它仍然超越了“弃用”阶段。

获取链接时警告很棘手。 很明显,GCC为某些function( mktemp()等)做了这一点,如果你运行一个使用gets()的程序,Apple会发出GCC警告。 我不知道他们做了什么来实现这一目标。


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

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

 error ("message") 

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

 warning ("message") 

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

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