【问题标题】:Why doesn't `ld -L -l...` match the behavior of `ld /path/to/library.so`?为什么 `ld -L -l...` 不匹配 `ld /path/to/library.so` 的行为?
【发布时间】:2020-07-29 04:48:48
【问题描述】:

我有两个问题在下面突出显示。我使用的是 64 位 Linux。

我在另一个post 上看到MUSL 被提及为libc 实现。

我尝试将它与以下 Hello world 汇编程序一起使用,该汇编程序使用两个 libc 函数,write_exit

  .data
hello:
  .ascii "Hello, world\n"

  .text
  .globl _start
_start:
  movl $13, %edx
  movl $hello, %esi
  movl $1, %edi
  call write

  movl $0, %edi
  call _exit

我用以下代码组装了代码:

# Command 1
$ as -o hello.o hello.s

然后我运行 ld 以生成静态链接 MUSL libc 的可执行文件。

# Command 2
$ ld hello.o /usr/lib/x86_64-linux-musl/libc.a 

这会生成一个 a.out 文件,该文件按预期工作,执行时输出“Hello, world”。

我还尝试了对前面ld命令的不同调用,使用-static -lc而不是直接指定路径,并且还使用-L提供MUSL的路径,这样glibc就不会被使用,因为后者已经在 ld 的搜索路径上。

# Command 3
$ ld hello.o -L/usr/lib/x86_64-linux-musl/ -static -lc

按预期工作。

接下来我尝试动态链接MUSLlibc

# Command 4
$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 hello.o \
     /usr/lib/x86_64-linux-musl/libc.so

这似乎按预期工作。我可以运行a.out,在a.out 上调用ldd 表明MUSLlibc 已链接。

最后,我尝试了相对于之前静态链接版本的类似修改,使用-lc-L 而不是直接指定.so 文件的路径。

# Command 5
$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 hello.o \
     -L/usr/lib/x86_64-linux-musl -lc

程序运行不正常,输出错误:

bash: ./a.out: No such file or directory

当我使用--verbose 标志运行相同的ld 命令时,输出与将--verbose 传递给之前的ld 命令(生成工作可执行文件的Command 4)时的输出相同。

a.out 上运行ldd 也会输出错误:

./a.out: error while loading shared libraries: /usr/lib/x86_64-linux-gnu/libc.so: invalid ELF header

问题 1:为什么在这种情况下使用 -L-lc 调用 ld 与之前直接指定 .so 文件的行为不匹配?

我注意到如果我将指定的动态链接器更改为/lib/ld-musl-x86_64.so.1,生成的a.out 会按预期运行。

# Command 6
$ ld -dynamic-linker /lib/ld-musl-x86_64.so.1 hello.o \
     -L/usr/lib/x86_64-linux-musl -lc

但是,在生成的a.out 上调用ldd 会产生以下错误,之前我在Command 4 中没有使用-lc-L 时并非如此:

./a.out: error while loading shared libraries: /usr/lib/x86_64-linux-gnu/libc.so: invalid ELF header

问题 2:为什么 ld 在此二进制文件上失败,但在我将 .so 文件的路径传递给 ldd 并使用不同的动态链接器时更早地工作? p>

【问题讨论】:

  • 至少用--verbose 重新运行上述命令,看看实际发生了什么。
  • @n.'pronouns'm.,我尝试使用--verbose 运行命令,它会输出使用的内部链接器脚本,然后是ld: mode elf_x86_64attempt to open hello.o succeededhello.oattempt to open /usr/lib/x86_64-linux-musl/libc.so succeeded/usr/lib/x86_64-linux-musl/libc.so--verbose 的输出对于上面的命令 4 和 5 是相同的,我已经更新了帖子以表明这一点。

标签: linux assembly x86-64 ld musl


【解决方案1】:

我遇到的问题是由于将-L 与链接器一起使用,但没有该路径可用于在运行时加载libc.so

我在Command 4Command 5 生成的程序上调用readelf --dynamic --program-headers 注意到了这一点。

 # Command 4
 0x0000000000000001 (NEEDED) Shared library: [/usr/lib/x86_64-linux-musl/libc.so]
 # Command 5
 0x0000000000000001 (NEEDED) Shared library: [libc.so]

我能够解决Command 5 生成的程序的问题,方法是在运行程序时使用环境变量LD_LIBRARY_PATH=/usr/lib/x86_64-linux-musl,或者通过向ld-rpath /usr/lib/x86_64-linux-musl 传递一个额外的参数。

【讨论】:

    猜你喜欢
    • 2017-02-11
    • 2012-08-19
    • 1970-01-01
    • 2013-05-18
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    相关资源
    最近更新 更多