Linux二进制文件通常动态链接到核心系统库(libc)。这样可以使二进制文件的内存占用空间很小,但是依赖于最新库的二进制文件将无法在较旧的系统上运行。相反,链接到较早的库的二进制文件将在最新的系统上愉快地运行。
因此,为了确保我们的应用程序在分发期间具有良好的覆盖范围,我们需要找出我们可以支持的最旧的libc并将其链接到该二进制文件。
我们应该如何确定可以链接到的最旧版本的libc?
找出可执行文件中的哪些符号正在创建对不需要版本的glibc的依赖。
$ objdump -p myprog ... Version References: required from libc.so.6: 0x09691972 0x00 05 GLIBC_2.3 0x09691a75 0x00 03 GLIBC_2.2.5 $ objdump -T myprog | fgrep GLIBC_2.3 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.3 realpath
查看附属库中的内容,以查看是否可以链接较旧版本的任何符号:
$ objdump -T /lib/libc.so.6 | grep -w realpath 0000000000105d90 g DF .text 0000000000000021 (GLIBC_2.2.5) realpath 000000000003e7b0 g DF .text 00000000000004bf GLIBC_2.3 realpath
我们很幸运!
从GLIBC_2.2.5您的代码中请求版本:
GLIBC_2.2.5
#include <limits.h> #include <stdlib.h> __asm__(".symver realpath,realpath@GLIBC_2.2.5"); int main () { realpath ("foo", "bar"); }
观察到不再需要GLIBC_2.3:
$ objdump -p myprog ... Version References: required from libc.so.6: 0x09691a75 0x00 02 GLIBC_2.2.5 $ objdump -T myprog | grep realpath 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 realpath
有关更多信息,请参见http://web.archive.org/web/20160107032111/http://www.trevorpounds.com/blog/?p=103。