在Linux中使用LD_PRELOAD混合64位/ 32位环境

Rob*_*Lay 3 linux 32bit-64bit ld-preload

我想设置LD_PRELOAD指向一个共享库,我可以运行64位或32位应用程序.很明显,共享库和可执行文件必须匹配bit-ness.

$ LD_PRELOAD=/lib64/lib_init.so ./hello32
ERROR: ld.so: object '/lib64/lib_init.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS64): ignored
Run Code Online (Sandbox Code Playgroud)

其中hello32是32位应用程序.世界上有一些页面说我应该能够:

$ LD_PRELOAD='/$LIB/lib_init.so' ./hello32
ERROR: ld.so: object '/$LIB/lib_init.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored
Run Code Online (Sandbox Code Playgroud)

其中$ LIB将自动在lib和lib64之间切换,具体取决于应用程序是32位还是64位.但显然这不起作用.

是否有一些技巧可以使这项工作?LD_PRELOAD_32,LD_PRELOAD_64?谢谢!

kof*_*ann 5

通过指定库的完整路径,您不允许动态链接器根据二进制体系结构调整其搜索路径.仅定义库名称,并让链接器为您选择正确的库.例如:

$ LD_PRELOAD=lib_init.so ./hello32
Run Code Online (Sandbox Code Playgroud)

将在/ lib中搜索lib_init.so

$ LD_PRELOAD=lib_init.so ./hello64
Run Code Online (Sandbox Code Playgroud)

将在/ lib64中搜索


use*_*881 5

事实证明,您可以在设置LD_PRELOAD(或设置文件/etc/ld.so.preload)时设置使用$LIB。问题是 $LIB 设置的值取决于您的 Linux 发行版。啊!

在我有限的测试中,我发现基于 Redhat 的系统将 $LIB 扩展为“lib64”(对于 64 位应用程序)和“lib”(对于 32 位应用程序)。

然而,在基于 debian 的发行版上,我发现 $LIB 对于 64 位应用程序扩展为“lib/x86_64-linux-gnu”,对于 32 位应用程序扩展为“lib/i386-linux-gnu”。我无法找到任何有关此的文档,但我已经对此进行了测试。

这意味着如果我有:

 $ LD_PRELOAD='/$LIB/lib_init.so'  ./hello64
Run Code Online (Sandbox Code Playgroud)

在像 ubuntu 这样的基于 Debian 的系统上,我有:

/lib/x86_64-linux-gnu/lib_init.so  (for 64bit apps)
Run Code Online (Sandbox Code Playgroud)

/lib/i386-linux-gnu/lib_init.so  (for 32bit apps)
Run Code Online (Sandbox Code Playgroud)

这会工作得很好(在基于 ubuntu 的 Linux 计算机上)

否则,在基于 Redhat 的发行版上,您需要

  /lib64/lib_init.so and /lib/lib_init.so
Run Code Online (Sandbox Code Playgroud)

适用于 64 位和 32 位应用程序。

使用 LD_PRELOAD='/$LIB/lib_init.so' 的优点是您不依赖于 $LD_LIBRARY_PATH 的值。

只是在 LD_PRELOAD 中设置 $LIB 时不要忘记单引号