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

时间:2011-01-14 19:07:50

标签: c gcc linker binutils

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

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

3 个答案:

答案 0 :(得分: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指令包含在宏中。

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

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

答案 1 :(得分:0)

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

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

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


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

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

error ("message")
     

如果在函数声明中使用此属性,则调用此类函数   没有通过死代码消除或其他优化消除,一个错误   其中将包含消息将被诊断出来。这对编译时很有用   检查,特别是与__builtin_constant_p和内联函数一起检查   通过extern无法检查内联函数参数   char [(条件)? 1:-1];招数。虽然可以离开这个功能   undefined并因此在使用此属性时调用链接失败   即使在场的情况下,也会被提前诊断并确切地确定呼叫的位置   内联函数或不发出调试信息。

warning ("message")
     

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

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

答案 2 :(得分:0)

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

  • 可能创建具有函数名称的对象,因此配置阶段的链接器可能会抱怨符号不兼容
  • 创建具有永不解决的依赖关系“dont_use_symbol_XXX”的函数
  • 或伪造一个带有全局索引的.a文件,该索引具有您的功能,但归档中的.o成员格式错误