gpt4 book ai didi

linux - ld-linux 动态链接器/解释器的相对可执行路径

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:14:37 26 4
gpt4 key购买 nike

我想发送和归档二进制文件(带库的可执行文件),它们与尽可能多的 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 加载程序的方法?

最佳答案

As I understand system libraries like libc also need to be shipped because the executable will crash given a different version of libc.

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

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

Meanwhile libc seems to be coupled with ld-linux

正确:libc.so.6ld-linux 是 GLIBC 的一部分,必须 来自相同的构建,任何不匹配可能导致灾难性故障(SIGSEGV inside libc.so.6,或 inside ld-linux)。

I need to package ld-linux too.

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

更新:

I could try building on an old Ubuntu LTS and get most of backward compatibility, but then I would not get the new C++17 compilers, which basically defeats the whole point of modern software engineering.

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

这样做的一个困难是您可能需要更新的 libstdc++.so.6

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

但是,执行任何一种操作都可能涉及许可问题(但话又说回来,您的计划已经包括分发所有库,因此这个问题并不新鲜)。

关于linux - ld-linux 动态链接器/解释器的相对可执行路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54840445/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com