我在 /bin/cat 上做了一个 ldd,我看到动态加载程序库 /lib64/ld-linux-x86-64.so.2 是其中的一部分。
ldd /bin/cat
linux-vdso.so.1 (0x00007ffe743f4000)
libc.so.6 => /lib64/libc.so.6 (0x00007fde4f0a1000)
/lib64/ld-linux-x86-64.so.2 (0x000056057639c000)
但是,当我对这个二进制文件 ( strace -o cat.trace /usr/bin/ls /etc/motd )执行 strace并且找不到它正在加载时,我的问题就开始了。我假设它应该是内核加载的第一个。
execve("/usr/bin/ls", ["/usr/bin/ls", "/etc/motd"], 0x7ffe9e6a8d38 /* 56 vars */) = 0
brk(NULL) = 0x5650331a2000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f39527b9000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=95294, ...}) = 0
mmap(NULL, 95294, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f39527a1000
close(3) = 0
open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000c\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=153176, ...}) = 0
mmap(NULL, 2253688, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f3952370000
mprotect(0x7f3952393000, 2097152, PROT_NONE) = 0
mmap(0x7f3952593000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x23000) = 0x7f3952593000
mmap(0x7f3952595000, 4984, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f3952595000
close(3) = 0
open("/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\25\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=18608, ...}) = 0
mmap(NULL, 2113840, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f395216b000
mprotect(0x7f395216f000, 2093056, PROT_NONE) = 0
mmap(0x7f395236e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f395236e000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\10\2\0\0\0\0\0"..., 832) = 832
从 ldd 输出可以看出,这里的一个补充问题是 - ldd 如何在加载库之前预测动态链接/加载的库的加载地址?在我研究的理论上,内存是共享资源,然后多个库应该能够加载到相同的内存位置(尽管不是同时)。