为已弃用的函数生成链接时错误
gcc 和 GNU binutils 有没有办法标记某些函数,以便它们在使用时会在链接时生成错误?我的情况是,我有一些库函数,为了与现有二进制文件兼容,我没有删除这些函数,但我想确保没有新编译的二进制文件尝试使用这些函数。我不能只使用编译时 gcc 属性,因为有问题的代码会忽略我的标头并使用 configure
脚本检测函数的存在并对其本身进行原型设计。我的目标是为错误的配置脚本生成链接时错误,以便它们停止检测函数的存在。
编辑:一个想法..使用程序集为入口点指定错误的.type
是否与动态链接器兼容,但在尝试链接新程序时会生成链接错误?
Is there a way with gcc and GNU binutils to mark some functions such that they will generate an error at link-time if used? My situation is that I have some library functions which I am not removing for the sake of compatibility with existing binaries, but I want to ensure that no newly-compiled binary tries to make use of the functions. I can't just use compile-time gcc attributes because the offending code is ignoring my headers and detecting the presence of the functions with a configure
script and prototyping them itself. My goal is to generate a link-time error for the bad configure
scripts so that they stop detecting the existence of the functions.
Edit: An idea.. would using assembly to specify the wrong .type
for the entry points be compatible with the dynamic linker but generate link errors when trying to link new programs?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
FreeBSD 9.x 的 ttyslot() 函数所做的事情与您想要的非常接近。这个函数对于utmpx来说是没有意义的。诀窍在于该符号只有非默认版本。因此,
ld
不会找到它,但 rtld 会在运行旧的二进制文件时找到版本化定义。我不知道如果旧的二进制文件具有未版本控制的引用会发生什么,但如果只有一个定义,这可能是明智的。例如,
通常情况下,还会有一个默认版本,例如
Solaris 兼容版本脚本或通过 Solaris 兼容版本脚本,但诀窍是不要添加一个。
通常,asm 指令被包装到宏中。
这个技巧依赖于 GNU 扩展来使用
.symver
汇编器指令定义符号版本,因此它可能只适用于 Linux 和 FreeBSD。 Solaris 兼容版本脚本只能为每个符号表达一个定义。更多信息:
info Gas
中的.symver
指令、Ulrich Drepper 的“如何编写共享库”、在FreeBSD 9.x does something very close to what you want with the
ttyslot()
function. This function is meaningless with utmpx. The trick is that there are only non-default versions of this symbol. Therefore,ld
will not find it, but rtld will find the versioned definition when an old binary is run. I don't know what happens if an old binary has an unversioned reference, but it is probably sensible if there is only one definition.For example,
Normally, there would also be a default version, like
or via a Solaris-compatible version script, but the trick is not to add one.
Typically, the asm directive is wrapped into a macro.
The trick depends on the GNU extensions to define symbol versions with the
.symver
assembler directive, so it will probably only work on Linux and FreeBSD. The Solaris-compatible version scripts can only express one definition per symbol.More information:
.symver
directive ininfo gas
, Ulrich Drepper's "How to write shared libraries", the commit that deprecated ttyslot() at http://gitorious.org/freebsd/freebsd/commit/3f59ed0d571ac62355fc2bde3edbfe9a4e722845一种想法可能是生成一个具有这些符号但具有意外属性的存根库。
dont_use_symbol_XXX
”的函数One idea could be to generate a stub library that has these symbols but with unexpected properties.
dont_use_symbol_XXX
" that is never resolved为您不希望人们使用的已弃用函数生成链接时错误的最佳方法是确保已弃用函数不存在于库中 - 这使它们比“已弃用”更进一步。
也许你可以提供一个辅助库,其中包含已弃用的函数;不注意的人可以链接辅助库,但是主流人不会使用辅助库,因此不会使用这些功能。然而,它仍然超出了“弃用”阶段。
获得链接时警告是很棘手的。显然,GCC 对某些函数(
mktemp()
等)执行此操作,并且如果您运行使用gets()
的程序,Apple 会发出 GCC 警告。我不知道他们做了什么来实现这一点。根据评论,我认为您需要在编译时解决问题,而不是等到链接时或运行时。
GCC 属性包括(来自 GCC 4.4.1 手册):
如果配置程序忽略这些错误,它们就被破坏了。这意味着无法使用这些函数编译新代码,但现有代码可以继续使用库中已弃用的函数(直到需要重新编译为止)。
The best way to generate a link-time error for deprecated functions that you do not want people to use is to make sure the deprecated functions are not present in the libraries - which makes them one stage beyond 'deprecated'.
Maybe you can provide an auxilliary library with the deprecated function in it; the reprobates who won't pay attention can link with the auxilliary library, but people in the mainstream won't use the auxilliary library and therefore won't use the functions. However, it is still taking it beyond the 'deprecated' stage.
Getting a link-time warning is tricky. Clearly, GCC does that for some function (
mktemp()
et al), and Apple has GCC warn if you run a program that usesgets()
. I don't know what they do to make that happen.In the light of the comments, I think you need to head the problem off at compile time, rather than waiting until link time or run time.
The GCC attributes include (from the GCC 4.4.1 manual):
If the configuration programs ignore the errors, they're simply broken. This means that new code could not be compiled using the functions, but the existing code can continue to use the deprecated functions in the libraries (up until it needs to be recompiled).