ld-linux.so.2是linux的动态装载器(dynamic loader)。大多数的linux应用程序都是用这个装载器来装载的,除非在编译的过程中使用了-static参数。所以这个装载器在运行时的时候是必需的。它帮助去定位和装载该应用所需要的动态库。
我们创建出一个最简单的c程序,(假定$是当前的shell提示符)
$cat > helloworld.c << "EOF"
main(){}
EOF
这样我们在当前目录下建立了一个简单的helloworld.c程序,然后我们使用gcc命令去编译它。
$gcc helloworld.c
通常应该没有错误发生,之后我们用ldd命令去检视产生出来的执行文件。
$ldd a.out
这样能看到,a.out也是引用了ld-linux.so.2
linux-gate.so.1 => (0xb7f86000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e0f000)
/lib/ld-linux.so.2 (0xb7f87000)
我们可以使用readelf来观察a.out。gcc实现了ELF Specification所规定的动态链接,a.out中包含了ELF的程序头,名字叫INTERP。如下所示。
$ readelf -l a.out
Elf file type is EXEC (Executable file)
Entry point 0x80482e0
There are 8 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4
INTERP 0x000134 0x08048134 0x08048134 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x00474 0x00474 R E 0x1000
LOAD 0x000f0c 0x08049f0c 0x08049f0c 0x00104 0x0010c RW 0x1000
DYNAMIC 0x000f20 0x08049f20 0x08049f20 0x000d0 0x000d0 RW 0x4
NOTE 0x000148 0x08048148 0x08048148 0x00020 0x00020 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
GNU_RELRO 0x000f0c 0x08049f0c 0x08049f0c 0x000f4 0x000f4 R 0x1
那么ld-linux.so.2会以什么顺序来进行动态库的搜索呢?
man ld-linux告诉我们答案。
- 首先它会在LD_LIBRARY_PATH中进行搜索
- 之后他会在/etc/ld.so.cache中搜索被缓存的库
- 之后在/lib和/usr/lib中寻找这个库