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

发布于 2024-10-12 09:30:00 字数 330 浏览 3 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

暗喜 2024-10-19 09:30:00

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

例如,

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

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

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

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,

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

Normally, there would also be a default version, like

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

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 in info gas, Ulrich Drepper's "How to write shared libraries", the commit that deprecated ttyslot() at http://gitorious.org/freebsd/freebsd/commit/3f59ed0d571ac62355fc2bde3edbfe9a4e722845

风情万种。 2024-10-19 09:30:00

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

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

One idea could be to generate a stub library that has these symbols but with unexpected properties.

  • perhaps create objects that have the name of the functions, so the linker in the configuration phase might complain that the symbols are not compatible
  • create functions that have a dependency "dont_use_symbol_XXX" that is never resolved
  • or fake a .a file with a global index that would have your functions but where the .o members in the archive have the wrong format
方圜几里 2024-10-19 09:30:00

为您不希望人们使用的已弃用函数生成链接时错误的最佳方法是确保已弃用函数不存在于库中 - 这使它们比“已弃用”更进一步。

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

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


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

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

错误(“消息”)

如果在函数声明中使用此属性并且对此类函数的调用是
未通过死代码消除或其他优化消除,错误
其中将包括将被诊断的消息。这对于编译时间很有用
检查,尤其是与 __builtin_constant_p 和内联函数一起使用
无法通过 extern 检查内联函数参数
字符 [(条件)? 1:-1];技巧。虽然可以离开该功能
未定义,因此调用链接失败,当使用此属性时会出现问题
即使在存在的情况下,也会更早地诊断出呼叫的确切位置
内联函数或不发出调试信息时。

警告(“消息”)

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

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

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 uses gets(). 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):

error ("message")

If this attribute is used on a function declaration and a call to such a function is
not eliminated through dead code elimination or other optimizations, an error
which will include message will be diagnosed. This is useful for compile time
checking, especially together with __builtin_constant_p and inline functions
where checking the inline function arguments is not possible through extern
char [(condition) ? 1 : -1]; tricks. While it is possible to leave the function
undefined and thus invoke a link failure, when using this attribute the problem
will be diagnosed earlier and with exact location of the call even in presence of
inline functions or when not emitting debugging information.

warning ("message")

If this attribute is used on a function declaration and a call to such a function is
not eliminated through dead code elimination or other optimizations, a warning
which will include message will be diagnosed. This is useful for compile time
checking, especially together with __builtin_constant_p and inline functions.
While it is possible to define the function with a message in .gnu.warning*
section, when using this attribute the problem will be diagnosed earlier and
with exact location of the call even in presence of inline functions or when not
emitting debugging information.

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文