如何确定glibc(glibcxx)二进制文件所依赖的版本?

14

众所周知,glibc(以及据我所知,glibstd ++也是如此)使用符号版本机制。(有关详细信息,请参考:如何链接到特定的glibc版本。)

问题是如何确定链接器将选择GLIBC和GLIBCXX的确切版本来处理libc和libstdc++中的名称?例如,如何获得类似于以下内容:

time -> time@GLIBC_2_5
...
gethostbyname -> gethostbyname@GLIBC_2_3

为什么我们需要这个?在我看来,如果您想要最小化所需的glibc/libstdc++版本,它可能会非常有用。


如果我没记错的话,dso-howto(http://www.akkadia.org/drepper/dsohowto.pdf)中有一节关于使用链接脚本的内容。 - ninjalj
2个回答

27

你可以尝试在二进制文件上运行objdump -T。例如,以下是如何查看我的系统上的/usr/sbin/nordvpnd二进制文件依赖于至少2.18版本的GLIBC:

$ objdump -T /usr/sbin/nordvpnd | grep GLIBC | sed 's/.*GLIBC_\([.0-9]*\).*/\1/g' | sort -Vu      
2.2.5
2.3
2.3.2
2.3.3
2.3.4
2.4
2.7
2.8
2.9
2.10
2.14
2.15
2.16
2.17
2.18

如果您考虑链接到旧版本的符号,请注意这些旧版本可能依赖于旧的、不同的结构或其他定义。为避免这种情况,请使用相应的旧版头文件和库进行编译和链接。


谢谢,jilles。它有效。还有一个问题,如何从代码中获取调用动态符号的位置?我的意思是,例如,如果“objdump -T”返回某个条目,比如GLIBCXX_3.4.9 ***Insert_***,如何理解哪些函数在源代码中使用了这个符号? - Shcheklein
嗯,我真的不知道比运行objdump -t在所有.o文件上并检查哪些文件包含对该函数的引用更好的解决方案。似乎这可以更好地完成,因为链接器知道未解析符号被使用的位置。 - jilles
1
我只想补充一点,对于共享库,“objdump -T”不起作用,我使用的解决方案是“ldd -v somelibrary.so”(-v很重要),该解决方案在https://askubuntu.com/questions/163138/how-do-i-find-what-version-of-libc-my-application-links-to中有描述。 - Alexander Samoylov

2
objdump -T  bin-file | grep -Eo 'GLIBC_\S+' | sort -u

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接