readelf 是否将 RPATH 返回为 RUNPATH?

readelf 是否将 RPATH 返回为 RUNPATH?

我使用 cmake 编写了一个简单的程序/库组合,名为“PrintFive”。

从 CLI 运行:

readelf -d PrintFive 

Dynamic section at offset 0x2d60 contains 30 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libUsesSharedLib.so]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000001d (RUNPATH)            Library runpath: [/home/xxx/Projects/PrintFive/UsesSharedLib/sharedLib/lib:/home/xxx/Projects/PrintFive/build/UsesSharedLib]
 ...

奇怪。我的理解是 CMake 会写入 RPATH。它没有出现,但“RUNPATH”出现了。

如果我从 CLI 运行该应用程序,则可以轻松找到该库。

如果我删除 RUNPATH 属性:

chrpath -d PrintFive

然后应用程序不再运行。没有意外。如果我设置LD_LIBRARY_PATH为指向图书馆的位置,那么一切都会恢复正常。

(此时我重建了我的程序)

如果这个“RUNPATH”是真的,RUNPATH那么我应该能够使用覆盖它LD_LIBRARY_PATH。或者本文索偿。

所以我从应用程序的构建目录运行:

export LD_LIBRARY_PATH=`pwd`

(请注意,使用 cmake 构建时,库不会与应用程序放在同一目录中)

按照理论,应用程序现在不应该运行,因为 LD_LIBRARY_PATH 应该覆盖二进制文件中嵌入的任何真正的 RUNPATH。

但它运行了。对我来说,这表明二进制文件确实有 RPATH。

我有两种理论。

  1. readelf 返回 RPATH 作为 RUNPATH
  2. 尽管二进制文件中已经嵌入了 RPATH,但 readelf 不会打印 RPATH。

附加信息:

readelf -v
GNU readelf (GNU Binutils for Ubuntu) 2.34
Copyright (C) 2020 Free Software Foundation, Inc.

不过,我已经看到很多互联网文章显示 readelf 打印 RPATH。有人能告诉我吗?

答案1

我怀疑你的推理LD_LIBRARY_PATH是错误的。在寻找库时,动态链接器会按照一定的顺序搜索各个位置:

  1. 路径
  2. LD_LIBRARY_PATH
  3. 运行路径
  4. 缓存文件
  5. 在默认路径 /lib 和 /usr/lib (或 lib64,取决于 glibc 的一些编译设置)中

这并不意味着如果设置了,搜索将在步骤 2 之后无条件停止LD_LIBRARY_PATH。它只是意味着如果在步骤 2 中找到合适的库,则跳过步骤 3 及后续步骤。

相关内容