我碰巧需要从导出的共享库符号的平面列表中找出哪个库导出了哪些符号。列表中有足够的符号(20 个左右),我不会手动交叉引用每个符号。
我发现这nm -A -D -f sysv <library-name>
似乎产生了有用的输出——我可以搜索包含FUNC
在第二列中也列出了地址的行。所以我对 中的所有内容都运行了这个命令/usr/lib
,并将其重定向到一个文件。
令我惊讶的是,我为解析文件而编写的脚本中的健全性检查报告说存在重复的符号!经调查发现库似乎在导出重复符号?!?
我使用一些 shell 脚本验证了这一点,并且我能够将我使用的命令变成这个(技术上)单行:
readlink -f /lib/* /usr/lib/* \
| grep -F .so. | sort | uniq \
| while read x; do nm -A -D -f sysv $x; done \
| grep FUNC | cut -d'|' -f1 | sort -g | uniq -c | sort -g \
| sed -n '/^ \+1/!{s/^ \+[0-9]\+ \+//p}' | sed 's/ //g' \
| tr '\n' '\v' \
| sed ':1;s/\([^ ]\+\):\([^\v$]\+\)\v\1:/\1:\2|/g;t1' \
| tr '\v' '\n' \
| while IFS=: read -a x; do \
nm -A -D -f sysv "${x[0]}" | grep ":\\(${x[1]//|/\\|}\\).*FUNC"; \
done
上面的命令将使您的磁盘搜索一小段时间。如果需要,您可以将其分解为重定向到临时文件的块。输出也会很宽(~150 cols)。
我最初在我正在使用的 Debian Squeeze chroot 上运行原始脚本,但出于好奇,我在我的主机系统上运行了上述脚本,以查明 chroot 是否不正常。
嗯...... chroot 报告了超过 90 个重复项,但我的主机(Arch)系统显然有大约 267 个。
该命令通过 greppingnm
的输出工作,因此结果有点嘈杂,但看起来像这样:
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access|00043700| T | FUNC|00000037| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access|000436c0| T | FUNC|0000003c| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access_mask|000458f0| T | FUNC|00000058| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size|000432a0| T | FUNC|00000037| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size|00043260| T | FUNC|0000003c| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_max|00044ff0| T | FUNC|0000003c| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_max|00045030| T | FUNC|00000037| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_min|000453c0| T | FUNC|00000037| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_min|00045380| T | FUNC|0000003c| |.text
注意每个符号有两个。地址是不同的,是的,但是......我认为动态链接是通过符号名称工作的,就是这样。(如果您在上面的列表中向右滚动)这些符号都是类型FUNC
并且来自该.text
部分,这使我更加困惑。
我发布这篇文章是为了了解这里的引擎盖下正在发生什么有趣的魔法。(因为我的系统正在工作......)
如果有人有任何好主意,我可以转储大约 600 行文本 - Pastebin 似乎不再流行,而且我不使用 GitHub - 我很乐意分享完整的输出。
符号出现重复是因为提供的信息
nm
不完整:有问题的符号是版本化的。你可以看到这个objdump -T
:or
nm
的--with-symbol-versions
选项:二进制文件与特定版本的符号链接,它们将在链接时获得正确的符号。这允许在保持向后兼容性的同时更改 API。