当前位置: 首页 > 面试题库 >

在.so文件中链接到较旧的符号版本

詹高畅
2023-03-14
问题内容

在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的Web存档上的Web存档所示),因为这将需要我确保symver位于所有使用memcpy的代码之前,这将非常困难(带有第三方代码的复杂代码库)
  • 使用旧库维护构建环境;仅仅因为我想在我的桌面系统上进行开发,而在我们的网络中同步内容将是皮塔饼。

考虑链接器的所有工作时,似乎并不难实现,毕竟它也有一些代码可以找出符号的默认版本。

只要不是像编辑最终二进制文件这样的怪异技巧,任何其他与简单链接程序命令行具有相同复杂性级别的想法(例如创建简单的链接脚本等)也将受到欢迎。

编辑: 为了保护以后的读者,除了以下想法外,我还找到--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即可。

或者,您可以进行静态链接,或者可以确保网络上的所有系统都具有与构建计算机相同或更好的版本。



 类似资料:
  • 问题内容: 安装新的构建机器后,我发现它带有标准C ++库的6.0.10 但是,我们的许多目标计算机仍使用旧版本的libstdc ++,例如: 显然,在最后两个0.0.1中,ABI发生了变化,因为尝试运行程序会导致 我尝试明确安装旧版本的gcc,但没有帮助。升级目标计算机是我无法控制的,因此不是一种选择。使我的构建在具有较旧libstdc ++的计算机上工作的最佳方法是什么? 我在apt-cach

  • 问题内容: 大家好,我需要在linux中执行此操作: 给出:文件名“ foo.txt” 查找:所有符号链接到“ foo.txt”的文件 怎么做?谢谢! 问题答案: 这取决于是否要查找指向特定文件的链接,那么这是唯一的好方法: 另一方面,如果您只是想查找指向恰好名为的 任何 文件的链接,则类似 要么

  • 问题内容: 我想在Linux中建立一个符号链接。我已经编写了此Bash命令,其中第一个路径是我要链接到的文件夹,第二个路径是已编译的源代码。 它是否正确? 问题答案: 要创建新的符号链接(如果符号链接已存在,将失败): 要创建或更新符号链接:

  • 问题内容: 我正在尝试让一个库在我的c 项目中工作,并且对于不习惯c 的人没有明确的说明 以下链接是我最近来的 它指出以下 还有以下线程指出以下内容 现在从我可以看到的命令是+ ,例如我的文件名是,这是正确的,有人可以澄清一下吗 我目前正在使用以下命令来编译我的文件,但是想包含一个名为.so的文件,例如 问题答案: 现在从我所看到的命令,例如我的文件名是这将是 不,那是不正确的。应该是,即您用来将

  • 我希望使用SetupTools将一个包部署到PyPi。但是,包的核心部分实际上是用Fortran编写的,我正在使用f2py用Python包装。基本上,项目的结构如下所示: null myfunc.py模块导入hello.so(),然后myfunc.py中的函数可以使用该模块。这在我的机器上很好用。 然后我在我的Ubuntu上尝试了标准的setuptools安装:,结果安装得很好。但不幸的是,在导入