readelf 报告 so file as NEEDED,但没有使用它的函数(或其他符号)

readelf reports so file as NEEDED, but no functions (or other symbols) is used from it

Readelf 报告,ssh 实用程序需要 libutil.so.1:

$readelf -s /usr/bin/ssh | grep libutil
0x0000000000000001 (NEEDED)             Shared library: [libutil.so.1]

正如nm所说,libutil.so.1只有6个外部符号:

$nm -D /lib64/libutil.so.1 | grep "T "
000000331e0015a0 T forkpty
000000331e000fa0 T login
000000331e0010f0 T login_tty
000000331e001190 T logout
000000331e0012e0 T logwtmp
000000331e0013d0 T openpty

但是这些符号不是从 ssh 引用的:

$nm -D /usr/bin/ssh | grep forkpty
$nm -D /usr/bin/ssh | grep login
$nm -D /usr/bin/ssh | grep login_tty
$nm -D /usr/bin/ssh | grep logout
$nm -D /usr/bin/ssh | grep logwtmp
$nm -D /usr/bin/ssh | grep openpty

(grep not showing any matches)

这是怎么回事?为什么库被引用为 NEEDED,但没有使用它的符号?这不是唯一的例子。在分析另一个可执行文件的依赖关系时,我遇到了很多这样的 "empty" 引用。

DT_NEEDED 标记由 link 编辑器 (ld) 根据提供的 -l 标记生成。 GNU link 编辑器和大多数其他编辑器(除了一些例外)的默认设置是为提供的每个 -l 标志创建一个 DT_NEEDED 标记。

当使用 GNU ldgold 时,您可以在 -l 标志之前传递 --as-needed 以便只为库发出 DT_NEEDED 标签确实用过如果这些符号实际上是间接使用的,这可能仍然会发出不明显的标签。

实际上我已经写了很多关于 --as-needed 及其工作原理的文章,所以如果您更好奇,可以浏览 my blog posts