链接到 .so 文件中的旧符号版本 [英] Linking against older symbol version in a .so file

查看:21
本文介绍了链接到 .so 文件中的旧符号版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 x86_64 linux 上使用 gcc 和 ld 我需要链接到新版本的库 (glibc 2.14),但可执行文件需要在旧版本 (2.5) 的系统上运行.由于唯一不兼容的符号是 memcpy(需要 memcpy@GLIBC_2.2.5 但提供 memcpy@GLIBC_2.14 的库),我想告诉链接器,而不是采用 memcpy 的默认版本,它应该采用我指定的旧版本.

我发现了一种非常奇怪的方法:只需在链接器命令行中指定旧 .so 文件的副本.这工作正常,但我不喜欢将多个 .so 文件(我只能通过指定我链接到的所有旧库也有对 memcpy 的引用来使其工作)签入 svn 并被我的构建系统需要的想法.

所以我正在寻找一种方法来告诉链接器采用旧版本的符号.

对我不起作用(很好)的替代方案是:

  • 使用 asm .symver(见 Trevor Pounds 博客的网络档案),因为这需要我确保 symver 位于所有使用 memcpy 的代码之前,这将非常困难(带有 3rd 方代码的复杂代码库)
  • 使用旧库维护构建环境;仅仅是因为我想在我的桌面系统上进行开发,而在我们的网络中同步内容将是一件很麻烦的事情.

考虑到链接器所做的所有工作,实现起来似乎并不难,毕竟它也有一些代码来确定符号的默认版本.

任何其他与简单链接器命令行(例如创建简单的链接器脚本等)具有相同复杂性级别的想法也受到欢迎,只要它们不是像编辑生成的二进制文件这样的奇怪黑客....../p>

为了为未来的读者保留这一点,除了下面的想法,我发现链接器的选项 --wrap 有时也很有用.

解决方案

只需静态链接 memcpy - 将 memcpy.o 拉出 libc.a ar x/path/to/libc.a memcpy.o(无论版本如何 - memcpy 几乎是一个独立的功能)并将其包含在您的最终链接中.请注意,如果您的项目是向公众发布而不是开源的,则静态链接可能会使许可问题复杂化.

或者,您也可以简单地自己实现 memcpy,尽管 glibc 中手动调整的汇编版本可能更高效

请注意,memcpy@GLIBC_2.2.5 映射到 memmove(旧版本的 memcpy 始终复制到一个可预测的方向,这导致它在应该使用 memmove 时有时会被误用),这是版本颠簸的唯一原因 - 对于这种特定情况,您可以在代码中简单地将 memcpy 替换为 memmove.

或者您可以使用静态链接,或者您可以确保您网络上的所有系统都具有与您的构建机器相同或更好的版本.

Using gcc and ld on x86_64 linux I need to link against a newer version of a library (glibc 2.14) but the executable needs to run on a system with an older version (2.5). Since the only incompatible symbol is memcpy (needing memcpy@GLIBC_2.2.5 but the library providing memcpy@GLIBC_2.14), I would like to tell the linker that instead of taking the default version for memcpy, it should take an old version I specify.

I found a quite arkward way to do it: simply specify a copy of the old .so file at the linker command line. This works fine, but I don't like the idea of having multiple .so files (I could only make it work by specifying all old libraries I link to that also have references to memcpy) checked into the svn and needed by my build system.

So I am searching for a way to tell the linker to take the old versioned symbol.

Alternatives that don't work (well) for me are:

  • Using asm .symver (as seen on Web Archive of Trevor Pounds' Blog) since this would require me to make sure the symver is before all the code that is using memcpy, which would be very hard (complex codebase with 3rd party code)
  • Maintaining a build environment with the old libraries; simply because I want to develop on my desktop system and it would be a pita to sync stuff around in our network.

When thinking about all the jobs a linker does, it doesn't seem like a hard thing to imlpement, after all it has some code to figure out the default version of a symbol too.

Any other ideas that are on the same complexity level as a simple linker command line (like creating a simple linker script etc.) are welcome too, as long as they are not weird hacks like editing the resulting binary...

edit: To conserve this for the future readers, additionally to the below ideas I found the option --wrap to the linker, which might be useful sometimes too.

解决方案

Just link memcpy statically - pull memcpy.o out of libc.a ar x /path/to/libc.a memcpy.o (whatever version - memcpy is pretty much a standalone function) and include it in your final link. Note that static linking may complicate licensing issues if your project is distributed to the public and not open-source.

Alternatively, you could simply implement memcpy yourself, though the hand-tuned assembly version in glibc is likely to be more efficient

Note that memcpy@GLIBC_2.2.5 is mapped to memmove (old versions of memcpy consistently copied in a predictable direction, which led to it sometimes being misused when memmove should have been used), and this is the only reason for the version bump - you could simply replace memcpy with memmove in your code for this specific case.

Or you could go to static linking, or you could ensure that all systems on your network have the same or better version than your build machine.

这篇关于链接到 .so 文件中的旧符号版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆