为什么 ld -L -l... 不匹配 ld /path/to/library.so 的行为?
Why doesn't `ld -L -l...` match the behavior of `ld /path/to/library.so`?
我有两个问题在下面突出显示。我正在使用 64 位 Linux.
我在另一个 post 上看到 MUSL
被提及为 libc
实现。
我尝试将其与以下 Hello world 汇编程序一起使用,该程序使用两个 libc
函数,write
和 _exit
。
.data
hello:
.ascii "Hello, world\n"
.text
.globl _start
_start:
movl , %edx
movl $hello, %esi
movl , %edi
call write
movl [=11=], %edi
call _exit
我用以下代码组装了代码:
# Command 1
$ as -o hello.o hello.s
然后我 运行 ld
生成静态 links 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
按预期工作。
接下来我尝试动态link MUSL
libc
.
# 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
表明 MUSL
的 libc
是 linked。
最后,我尝试了相对于先前静态 linked 版本的类似修改,使用 -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
生成了一个有效的可执行文件)。
运行 ldd
on a.out
也输出错误:
./a.out: error while loading shared libraries: /usr/lib/x86_64-linux-gnu/libc.so: invalid ELF header
问题 1:为什么在这种情况下使用 -L
和 -lc
调用 ld
与我之前指定的 [=45] 的行为不匹配=] 直接文件?
我注意到,如果我将指定的动态 linker 更改为 /lib/ld-musl-x86_64.so.1
,则生成的 a.out
运行s 如预期的那样。
# 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
会产生以下错误,之前我没有在 -lc
和 -L
中使用 -L
=50=]:
./a.out: error while loading shared libraries: /usr/lib/x86_64-linux-gnu/libc.so: invalid ELF header
问题 2:为什么 ld
在这个二进制文件上失败,但是当我将 .so
文件的路径传递给 ldd
并使用不同的动态 linker?
我遇到的问题是由于将 -L
与链接器一起使用,但没有可用于在运行时加载 libc.so
的路径。
我通过对 Command 4
和 Command 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
.
我有两个问题在下面突出显示。我正在使用 64 位 Linux.
我在另一个 post 上看到 MUSL
被提及为 libc
实现。
我尝试将其与以下 Hello world 汇编程序一起使用,该程序使用两个 libc
函数,write
和 _exit
。
.data
hello:
.ascii "Hello, world\n"
.text
.globl _start
_start:
movl , %edx
movl $hello, %esi
movl , %edi
call write
movl [=11=], %edi
call _exit
我用以下代码组装了代码:
# Command 1
$ as -o hello.o hello.s
然后我 运行 ld
生成静态 links 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
按预期工作。
接下来我尝试动态link MUSL
libc
.
# 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
表明 MUSL
的 libc
是 linked。
最后,我尝试了相对于先前静态 linked 版本的类似修改,使用 -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
生成了一个有效的可执行文件)。
运行 ldd
on a.out
也输出错误:
./a.out: error while loading shared libraries: /usr/lib/x86_64-linux-gnu/libc.so: invalid ELF header
问题 1:为什么在这种情况下使用 -L
和 -lc
调用 ld
与我之前指定的 [=45] 的行为不匹配=] 直接文件?
我注意到,如果我将指定的动态 linker 更改为 /lib/ld-musl-x86_64.so.1
,则生成的 a.out
运行s 如预期的那样。
# 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
会产生以下错误,之前我没有在 -lc
和 -L
中使用 -L
=50=]:
./a.out: error while loading shared libraries: /usr/lib/x86_64-linux-gnu/libc.so: invalid ELF header
问题 2:为什么 ld
在这个二进制文件上失败,但是当我将 .so
文件的路径传递给 ldd
并使用不同的动态 linker?
我遇到的问题是由于将 -L
与链接器一起使用,但没有可用于在运行时加载 libc.so
的路径。
我通过对 Command 4
和 Command 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
.