【问题标题】:Relative-to-executable path to ld-linux dynamic linker/interpreterld-linux 动态链接器/解释器的相对可执行路径
【发布时间】:2019-07-17 08:04:37
【问题描述】:

我想发布和归档与尽可能多的 Linux 发行版向后和向前兼容且整个包可重定位的二进制文件(带有库的可执行文件)。 据我了解,像libc 这样的系统库也需要交付,因为在不同版本的libc 下,可执行文件会崩溃。同时libc 似乎与ld-linux 相结合 (例如,在 Debian 测试中编译的二进制文件已经不能在 Ubuntu 18.04 LTS 上运行),所以我也需要打包 ld-linux

我的解决方案是将所有可执行文件和库放在一个目录中,并将 rpath 设置为$ORIGIN(通过与-Wl,rpath=$ORIGIN 链接或使用chrpathpatchelf 设置)。这使得库可以与可执行文件一起重定位,并且适用于除链接器本身的ld-linux 之外的所有库。

可以通过-Wl,--dynamic-linker=/my/path/ld-linux.so 更改动态链接器路径或使用patchelf 设置它,但路径必须是绝对路径:

  1. $ORIGIN 技巧不起作用
  2. ./ 这样的相对路径有效,但仅当当前目录与加载程序本身相同时(从其他地方启动时可执行文件因错误而崩溃)
  3. 我可以编写一个 shell 脚本来检测所有路径并使用 /my/path/ld-linux.so /my/path/myexecutable $@ 启动可执行文件,但这意味着我想避免另一层间接和开销。

有没有办法将ld-linux相对于可执行文件的路径直接设置成可执行文件?

也许有办法静态链接 ld-linux 加载器?

【问题讨论】:

    标签: linux installation elf dynamic-linking relocation


    【解决方案1】:

    据我了解,像 libc 这样的系统库也需要交付,因为在不同版本的 libc 下,可执行文件会崩溃。

    这是不正确:GLIBC 保证向后兼容性(在旧系统上构建的可执行文件将继续在新版本的 GLIBC 上运行)。

    实现您想要的唯一明智的方法是针对您希望支持的最旧版本的 GLIBC 进行编译。

    同时 libc 似乎与 ld-linux 耦合

    正确:libc.so.6ld-linux 是 GLIBC 的一部分,必须来自同一个版本,任何不匹配都可能导致灾难性故障(SIGSEGVlibc.so.6 内,或在ld-linux)。

    我也需要打包 ld-linux。

    这很复杂:ld-linux绝对 路径被硬编码到a.out 中,并且无法更改。使一个 relocatable a.out 可以容忍对 ld-linux 的路径的更改是不可能的(缺少您已经尝试过的显式加载程序调用;这对于重新执行的可执行文件效果不佳自己)。

    更新:

    我可以尝试在旧的 Ubuntu LTS 上构建并获得大部分向后兼容性,但是我不会获得新的 C++17 编译器,这基本上破坏了现代软件工程的全部意义。

    可以在旧系统上安装更新的编译器,并使用旧的 GLIBC 获得 C++17。

    其中一个困难是您可能需要更新的libstdc++.so.6

    好消息是-Wl,-rpath=$ORIGIN 工作正常——只有 GLIBC 很难重新定位。您还可以使用--static-libstdc++ 将可执行文件与libstdc++.a 链接起来。

    但是,这样做可能会涉及许可问题(但是您的计划已经包括分发所有库,因此这个问题并不新鲜)。

    【讨论】:

    • 感谢您的关注。我同意 GLIBC 在向后兼容性方面付出了很多努力,但我在向前兼容性方面遇到了问题:Debian 编译的东西在最近的 Ubuntu 上不起作用。他们非常接近,我什至没有接触到 Fedora 和其他人。我可以尝试在旧的 Ubuntu LTS 上构建并获得大部分向后兼容性,但是我不会获得新的 C++17 编译器,这基本上破坏了现代软件工程的全部意义。
    • 我无法静态链接 libc 和 libstdc++,因为其他 (LGPL) 库需要链接回它们(也许 -rdynamic 可以解决),是的,静态链接一切都会破坏 LGPL。因此项目必须动态链接,然后我们回到 libc 链接器。
    • @mariusm “然后我们又回到了 libc 链接器”——我们不是。链接旧 GLIBC 和新 libstdc++(动态)——这是唯一可行的方法。好吧,您也可以要求您的客户设置 chroot 环境或容器,但这些都有自己的缺点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 2015-12-22
    • 2011-10-13
    • 2012-04-10
    • 1970-01-01
    • 2020-10-27
    相关资源
    最近更新 更多