【问题标题】:Is libc.so.2 required to be located in /usr/lib?libc.so.2 是否需要位于 /usr/lib 中?
【发布时间】:2014-10-05 17:36:00
【问题描述】:

我有一个目录,内容如下:

bin/busybox
lib/ld-linux.so.2
lib/libc.so.6

当我调用时:

chroot . bin/busybox sh

它失败了:

/bin/busybox: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory

当我将 lib/libc.so.6 移动到 usr/lib 时,它工作正常。

为什么 libc 必须在 /usr/lib 中?当我调用时:

objcdump -p bin/busybox | grep NEEDED

我明白了:

NEEDED        libc.so.6

所以我想,因为只有库的 soname 没有使用斜杠等。加载的将能够在标准文件夹中找到它,即 /lib 和 /usr/lib。显然,情况并非如此。

更令人困惑的是,ld-linux.so.2 似乎必须在 /lib 中,因为当它移动到 /usr/lib 时,chroot 失败并显示:

chroot: failed to run command '/bin/busybox': No such file or directory

我了解到的实际上是找不到加载程序的错误,而不是busybox二进制文件。

libc.so.2 发行版的问题是特定的吗?如果这很重要,我正在使用 Arch Linux。

【问题讨论】:

  • 编译时设置LD_RUN_PATH,或者运行前导出LD_LIBRARY_PATH设置库搜索路径
  • 或者做 ln -s /lib/libc.so.6 /usr/lib/libc.so.6
  • 谢谢。这些是解决问题的方法(除了将文件保留在目录中以便一切正常),但不解释原始行为。

标签: linux archlinux libc chroot


【解决方案1】:

加载程序的位置(通常类似于/lib/ld-linux.so)在二进制文件中是硬编码的。这个组件没有搜索过程——如果找不到,二进制文件根本不会运行。

(具体路径取决于您使用的 libc 和架构。例如,对于 x86_64 上的 glibc,它位于 /lib64/ld-linux-x86-64.so.2。)

搜索动态库的位置可在/etc/ld.so.conf 中配置。但是,如果您在 chroot 中没有该文件,则可能未配置某些标准路径!

【讨论】:

  • 硬编码加载器是否存储在 .interp 标头部分?我虽然 .interp 部分实际上有加载器代码。是的,我没有 ld.so.conf。我认为 /lib 和 /usr/lib 是默认的默认值;也就是说,即使没有定义其他内容,也可以使用。
  • 加载器的路径存储在.interp部分,而不是加载器的代码。 (在我的系统上,加载程序在磁盘上大约有 150K,这对于包含在每个二进制文件中来说是相当大的!)
  • 我对 man 8 ld.so 的措辞感到困惑:(...)存储在 .interp 部分中的动态链接器(...)我读到的链接器可能被替换通过任意代码,这就是为什么在未经处理的二进制文件上调用 ldd 可能是危险的。这种更换是否只是更换装载机的位置?它是否接受相对路径?
猜你喜欢
  • 1970-01-01
  • 2012-11-27
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 2012-06-07
  • 1970-01-01
  • 2023-02-23
  • 2011-07-31
相关资源
最近更新 更多