首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Fedora 28 / GLIBC 2.27 libm.so.6 logf()和powf() c++

Fedora 28 / GLIBC 2.27 libm.so.6 logf()和powf() c++
EN

Stack Overflow用户
提问于 2018-08-06 22:08:33
回答 1查看 2K关注 0票数 7

我相信其他Fedora 28用户会知道,操作系统的glibc最近更新为glibc 2.27。在许多其他事情中,2.27添加了logf()和powf()的新实现。这导致我的应用程序无法在使用旧的glibc (例如Debian)的发行版上运行。在Debian上调用应用程序时,会产生以下错误:

  • ..。未找到libm.so.6版本的GLIBC-2.27 (./app_name要求)

我使用以下过程跟踪这些符号到logf和powf:

代码语言:javascript
复制
objdump -T ./app_name | grep GLIBC_2.27

它提供了以下输出:

代码语言:javascript
复制
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.27  powf
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.27  logf

然后..。

代码语言:javascript
复制
objdump -T /lib/libm.so.6 | grep -w logf
objdump -T /lib/libm.so.6 | grep -w powf

它提供了以下输出:

代码语言:javascript
复制
000397a0 g    DF .text  00000135  GLIBC_2.27  logf
00010430 g    DF .text  0000009e (GLIBC_2.0)  logf

还有..。

代码语言:javascript
复制
000397a0 g    DF .text  00000135  GLIBC_2.27  powf
00010430 g    DF .text  0000009e (GLIBC_2.0)  powf

因此,我在GLIBC-2.0中也实现了powf()和logf()的信息,在我的项目中添加了以下内容(上面是main())并重新编译。

代码语言:javascript
复制
__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.so6做不同的事情吗?

很明显,我在这里遗漏了一些东西,所以我很感谢你的帮助。

非常感谢

阿曼达

EN

Stack Overflow用户

回答已采纳

发布于 2018-08-07 11:57:03

我认为问题在于您使用objdump来查找32位libm的符号版本,并且我假设您实际上正在构建一个64位的应用程序。在Fedora 28容器中,如果我查看64位库,则会看到以下版本:

代码语言:javascript
复制
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

这项工作如预期的那样:

代码语言:javascript
复制
#include <math.h>

__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位库中的版本:

代码语言:javascript
复制
$ 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位上工作,您可以:

代码语言:javascript
复制
#include <math.h>

#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);
}

它对wordsize使用正确的版本:

代码语言:javascript
复制
$ 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
票数 6
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51716288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档