作者:malohual | 来源:互联网 | 2022-12-08 15:01
我相信其他Fedora 28用户会知道,操作系统的glibc最近更新为glibc 2.27.在许多其他事情中,2.27增加了logf()和powf()的新实现.这导致我的应用程序无法在具有旧glibc(例如Debian)的发行版上运行.在Debian上调用应用程序时,会产生以下错误:
...找不到libm.so.6版本GLIBC-2.27
(./app_name要求)
我使用以下过程跟踪符号到logf和powf:
objdump -T ./app_name | grep GLIBC_2.27
其中给出了以下输出:
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.27 powf
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.27 logf
然后...
objdump -T /lib/libm.so.6 | grep -w logf
objdump -T /lib/libm.so.6 | grep -w powf
其中给出了以下输出:
000397a0 g DF .text 00000135 GLIBC_2.27 logf
00010430 g DF .text 0000009e (GLIBC_2.0) logf
和...
000397a0 g DF .text 00000135 GLIBC_2.27 powf
00010430 g DF .text 0000009e (GLIBC_2.0) powf
因此,有了powf()和logf()也在GLIBC-2.0中实现的信息,我将以下内容添加到我的项目中(在main()之上)并重新编译.
__asm__(".symver logf,logf@GLIBC_2.0");
__asm__(".symver powf,powf@GLIBC_2.0");
不幸的是,我的项目仍在使用GLIBC-2.27的powf和logf.实际上,我为Debian分发二进制文件非常重要,如果可以避免,我宁愿不必编译该分发版.
从历史上看,我已成功将此过程用于libc.so.6中的符号,但不是libm.so.6.我应该为libm.so.6做些不同的事吗?
显然,我在这里遗漏了一些东西,所以我将不胜感激任何提供的帮助.
非常感谢
阿曼达
1> Jonathan Wak..:
我认为问题是你曾经objdump
找到32位libm的符号版本,我假设你实际上正在构建一个64位应用程序.在Fedora 28容器中,如果我查看64位库,那么我会看到这些版本:
objdump -T /lib64/libm.so.6 | egrep -w 'logf|powf'
0000000000011ea0 g DF .text 0000000000000138 (GLIBC_2.2.5) powf
000000000004cad0 g iD .text 000000000000002a GLIBC_2.27 powf
000000000004c610 g iD .text 000000000000002a GLIBC_2.27 logf
0000000000011e40 g DF .text 0000000000000051 (GLIBC_2.2.5) logf
这符合预期:
#include
__asm__(".symver logf,logf@GLIBC_2.2.5");
__asm__(".symver powf,powf@GLIBC_2.2.5");
int main(int argc, char**)
{
return powf(argc, 2.0f) * logf(argc);
}
它使用64位库中的版本:
$ g++ m.cc
$ nm --undefined-only a.out
w __gmon_start__
U __libc_start_main@@GLIBC_2.2.5
U logf@GLIBC_2.2.5
U powf@GLIBC_2.2.5
所以我认为问题是你试图链接到那些不在64位库中的符号(因为glibc在版本2.2.5之前没有这些符号的64位版本,所以它们不会与GLIBC_2.0
版本一起存在).
要使其适用于32位或64位,您可以:
#include
#if __LP64__
# define SYMVER "GLIBC_2.2.5"
#else
# define SYMVER "GLIBC_2.0"
#endif
#define USE_OLD_SYM(F,V) __asm__(".symver " #F "," #F "@" V)
USE_OLD_SYM(logf,SYMVER);
USE_OLD_SYM(powf,SYMVER);
int main(int argc, char**)
{
return powf(argc, 2.0f) * logf(argc);
}
这使用了正确的版本:
$ g++ m.cc
$ nm --undefined-only a.out
w __gmon_start__
U __libc_start_main@@GLIBC_2.2.5
U logf@GLIBC_2.2.5
U powf@GLIBC_2.2.5
$ g++ m.cc -m32
$ nm --undefined-only a.out
w __gmon_start__
U __libc_start_main@@GLIBC_2.0
U logf@GLIBC_2.0
U powf@GLIBC_2.0