【问题标题】:Can I modify the dynamic linker and use without recompiling the glibc?我可以修改动态链接器并在不重新编译 glibc 的情况下使用吗?
【发布时间】:2013-11-18 15:24:08
【问题描述】:

我正在尝试在 64 位 Ubuntu 机器上修改 libc6(2.15-0ubuntu20.2) 中提供的动态链接器。

所以目前我的代码使用的是相同版本的 glibc 库。 (我已经下载了相同的源代码并正在研究它)。我的问题是,是否可以修改和构建 only 存在于glibc\elf\ 目录中的链接器源代码,而无需构建整个 glibc 库。

如果可能的话,我怎样才能让我的测试程序使用我自己构建的新版本的动态链接器来切换,而不是使用默认的未修改的链接器。

非常感谢任何指针或建议。 (如果需要更多信息,请告诉我)

编辑:: @constantius

我按照您链接的帖子中的步骤构建 ld.so。 但是我在制作时遇到了以下错误,我检查了 ld.so 在精灵中不存在。 错误是::

/var/services/homes/abhi/test/ld/eglibc-build/elf/librtld.os: In function `generic_getcwd':
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:356: undefined reference to `__closedir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:368: undefined reference to `__fdopendir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:384: undefined reference to `__readdir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:397: undefined reference to `rewinddir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:528: undefined reference to `__closedir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:490: undefined reference to `__closedir'
collect2: error: ld returned 1 exit status
make[2]: *** [/var/services/homes/abhi/test/ld/eglibc-build/elf/ld.so] Error 1
make[2]: Leaving directory `/var/services/homes/abhi/test/ld/eglibc-2.15/elf'
make[1]: *** [elf/subdir_lib] Error 2
make[1]: Leaving directory `/var/services/homes/abhi/test/ld/eglibc-2.15'
make: *** [all] Error 2

注意 使用相同的基础架构,我可以构建和安装完整的 GLIBC,因此我认为基础架构没有错误。 - 我猜这个错误与将 Makeconfig 编辑为 all-subdirs = csu elf gmon io misc posix setjmp signal stdlib string time 有关。 --对此有什么建议..

已解决 除了我们之前编辑的内容外,还需要在所有子目录列表中添加dirent

谢谢

【问题讨论】:

    标签: c linux compiler-construction linker glibc


    【解决方案1】:

    引用this page。如果你没有得到什么,请发表评论——我会尽力解释。

    建筑

    要编译Glibc(ld.so不能独立编译)下载并解压Glibc源码包。

    1确保您下载的 Glibc 版本与系统当前版本相同。

    2确保未设置环境变量 LD_RUN_PATH。

    3阅读安装并确保所有必要的工具链(Make、Binutils 等)都是最新的。

    4确保您正在编译的文件系统区分大小写,否则您会看到类似

    的奇怪错误
    /scratch/elf/librtld.os: In function `process_envvars':
    /tmp/glibc-2.x.y/elf/rtld.c:2718: undefined reference to `__open'
    ...
    

    5 ld.so 应该使用优化标志进行编译(-O2 是默认值)。如果不这样做,最终会出现奇怪的错误(请参阅常见问题解答中的问题 1.23)

    6假设Glibc在

    解压
    /tmp/glibc-2.x.y/
    

    然后编辑/tmp/glibc-2.x.y/Makefile.in:取消注释该行

    # PARALLELMFLAGS = -j 4
    

    并将 4 更改为适当的数字。

    7 由于我们只对ld.so 感兴趣,而不是整个Glibc,我们只想构建ld.so 所需的基本源文件。为此,请编辑/tmp/glibc-2.x.y/Makeconfig:找到以

    开头的行
    all-subdirs = csu assert ctype locale intl catgets math setjmp signal \
      ...
    

    并将其更改为

    all-subdirs = csu elf gmon io misc posix setjmp signal stdlib string time
    

    8 找一个临时目录,比如/scratch。那么

    $ cd /scratch
    $ /tmp/glibc-2.x.y/configure --prefix=/scratch --disable-profile
    $ gmake
    

    由于我们没有构建整个 Glibc,所以当 gmake 停止时(可能有一些错误),检查 /scratch/elf/ld.so 是否存在。

    ld.so 是一个静态二进制文件,这意味着它有自己的标准 C 例程实现(例如 memcpystrcmp 等)它有自己的类似 printf 的例程,称为 _dl_debug_printf

    测试

    您可以直接运行ld-linux.so。它会抱怨这可能不是您想要的(但您确实想要这个)并为您提供可以运行它的选项列表。有关调试标志,另请参见 man ld-linux.so,即您可以定义 LD_DEBUG 环境变量以查看 ld-linux.so 调试输出。

    【讨论】:

    • 如果按照帖子中的步骤操作并在执行 make 时出现此错误。我无法在 cmets 中添加错误 .. 将其添加到主帖中。
    【解决方案2】:

    虽然我不清楚glibc 的构建系统 是否让这件事变得简单,但没有根本原因就不能构建和使用glibc 动态链接器而不构建libc.so。我会仔细阅读顶级 Makefile 以了解如何完成这项工作。

    至于测试,有两种方法:

    1. 显式调用动态链接器来运行程序,如:

      ./ld-linux.so.2 a.out args ...
      
    2. 链接您的程序时,通过将此选项传递给编译器驱动程序,指定备用动态链接器路径名(将存储在其PT_INTERP 程序头中):

      -Wl,-dynamic-linker,/path/to/alternate/ld-linux.so.2
      

    【讨论】:

    • 您也可以在程序编译后使用patchelf --set-interpreter /foo/bar等工具编辑程序的ELF解释器。
    猜你喜欢
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    • 2010-09-07
    • 2010-11-30
    • 1970-01-01
    • 2016-09-30
    • 2021-03-28
    • 2020-03-13
    相关资源
    最近更新 更多