我正在使用 gcc 在 linux 上编译 C 程序。该程序本身在构建时链接 libc(而不是其他),因此 ldd 给出以下输出:
$ ldd myprogram
linux-vdso.so.1 => (0x00007fffd31fe000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7a991c0000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7a99bba000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f7a98fbb000)
在运行时,这个程序 dlopen() 的库 B,它依赖于库 A,当然 dlopen 在返回之前也会加载。A 导出一个名为 re_exec 的函数,B 调用该函数(B 与 A 链接)。libc 还导出了一个名为 re_exec 的函数。自述输出:
$ readelf -as A.so | grep re_exec
104: 00000000000044ff 803 FUNC GLOBAL PROTECTED 11 re_exec
469: 00000000000044ff 803 FUNC GLOBAL PROTECTED 11 re_exec
$ readelf -as /lib/x86_64-linux-gnu/libc.so.6 | grep re_exec
2165: 00000000000e4ae0 39 FUNC WEAK DEFAULT 12 re_exec@@GLIBC_2.2.5
问题是当 B 调用 re_exec 时,调用的是 libc 中的 re_exec,而不是 A 中的 re_exc。
如果,当我调用程序时,我包含 LD_LIBRARY_PRELOAD=/path/to/A.so,那么一切都按预期工作:Bs 调用 re_exec 正确调用 A,而不是 libc。
dlopen 调用通过 RTLD_NOW | RTLD_GLOBAL。我尝试过使用和不使用 DEEPBIND,并且在任何一种情况下都得到相同的行为。
我还尝试在 B 之前直接 dlopen()ing A,无论是否使用 DEEPBIND,这都不会影响行为。
问题:是否可以比链接时包含的库(在本例中为 libc)具有更高优先级的 dlopen A/B?
(请不要建议我将调用重命名为 re_exec 以外的名称;没用)