5

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

所以目前我的代码正在使用相同版本的 glibc 库。(我已经下载了相同的源代码并正在研究它)。我的问题是,是否可以只修改和构建目录中存在的链接器源代码,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

谢谢

4

2 回答 2

2

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

建造

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

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.soGlibc 而不是整个 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调试输出。

于 2013-11-11T15:29:26.977 回答
2

虽然我不清楚 glibc 的构建系统是否让这件事变得容易,但没有根本的原因为什么你不能在不构建 libc.so 的情况下构建和使用 glibc 动态链接器。我会仔细阅读顶级 Makefile 以了解使其工作的方法。

至于测试它,有两种方法:

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

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

    -Wl,-dynamic-linker,/path/to/alternate/ld-linux.so.2
    
于 2013-11-07T04:58:44.760 回答