查看可执行文件中依赖的动态库:
$ readelf -d /bin/sh
Dynamic section at offset 0x1ca88 contains 27 entries:
标记 类型 名称/值
0x0000000000000001 (NEEDED) 共享库:[libc.so.6]
0x000000000000000c (INIT) 0x45e8
0x000000000000000d (FINI) 0x15ad4
0x0000000000000019 (INIT_ARRAY) 0x21bda8
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x21bdb0
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x298
0x0000000000000005 (STRTAB) 0x1788
0x0000000000000006 (SYMTAB) 0x558
0x000000000000000a (STRSZ) 1815 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x21cc78
0x0000000000000002 (PLTRELSZ) 2328 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x3cd0
0x0000000000000007 (RELA) 0x2098
0x0000000000000008 (RELASZ) 7224 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x0000000000000018 (BIND_NOW)
0x000000006ffffffb (FLAGS_1) 标志: NOW
0x000000006ffffffe (VERNEED) 0x2028
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0x1ea0
0x000000006ffffff9 (RELACOUNT) 271
0x0000000000000000 (NULL) 0x0
这里能看到sh这个程序依赖的共享库是libc.so.6,那么在运行时如何找到该共享库呢?
实际上更加详细的信息可以使用ldd命令查看:
$ ldd /bin/sh
linux-vdso.so.1 => (0x00007fff5a5fe000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1407c31000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1408235000)
这里发现除了上面指定的之外,还有对应的ld-linux-x86-64.so.2,这个库文件就是为了查找动态库的,那么它又是如何被找到的呢?
实际上ld-linux动态库是在可执行文件的固定位置,路径也是由gcc在编译时就已经确定好了的。那么后续其他动态库查找都是由此动态库完成的。
ld-linux查找动态库的顺序:
1.可执行文件编译时由-L指定的动态库路径查找
2.从LD_LIBRARY_PATH环境变量指定的路径查找
3.从ldconfig的配置文件指定的路径查找:/etc/ld.so.conf(或/usr/local/etc/ld.so.conf)
4.从默认路径查找:/usr/lib和/lib
为arm64平台上适配ldd命令
1.修改ldd脚本第一行#!/bin/bash改为busybox对应的路径如#!/bin/sh
2.修改RTLDLIST="/lib64/ld-linux-x86-64.so.2"为对应的目录RTLDLIST="/lib/ld-linux-aarch64.so.1"
3.把脚本放到目标板的/bin目录