我有一个共享对象,其中 file 指示它是一个共享对象,并且它的使用和行为与共享对象相同。
% file libirc.so
libirc.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=9d54bda46b31ae048aae323dfd809f9ae6c8c55c, not stripped
%
但是ldd命令表明它是静态链接的。
% ldd libirc.so
statically linked
%
当我运行使用此 libirc.so 的可执行文件 ./Solver 时,它会按预期运行。但是,当我使用 LD_PRELOAD="io_functions.so" 运行相同的操作时,运行时链接器 /lib64/ld-linux-x86-64.so.2 在发出错误消息后立即出现段错误:
./Solver: Relink `./lib/libirc.so' with `/lib64/libc.so.6' for IFUNC symbol `memmove'
我可以通过在 LD_PRELOAD 上包含 libirc.so 来使用 LD_PRELOAD 进行运行。我没有 libirc.so 的源代码,所以我对此一无所知。我怀疑问题集中在 libirc.so 静态链接上。 io_functions.so 中的代码是什么并不重要,因为 ld.so 甚至没有达到调用 init 函数的程度,因为 ld.so 在绑定符号时出现段错误。
DSO 本质上没有任何扭曲之处,
ldd
报告为静态链接。在这种情况下,ldd
只是告诉
您认为 DSO 没有动态依赖性本身。
来了这样一个:
$ gcc --version
gcc (Ubuntu 13.2.0-4ubuntu3) 13.2.0
此编译器默认发出
PIC
代码。
$ cat hello.c
#include <stdio.h>
void hello(void)
{
puts("Hello World");
}
$ gcc -shared -o libhello-musl.so hello.c -L/usr/lib/x86_64-linux-musl/ -l:libc.a
为我的编译器构建并由我的编译器构建的库存 muscl static
libc
包含 PIC
目标文件,
所以it没有重定位错误。
$ file libhello-musl.so
libhello-musl.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=015152e75131cd274f08fa16447ff926b7c6d85d, not stripped
和:
$ ldd libhello-musl.so
statically linked
即使我没有尝试链接
-shared -static
(这会失败)。 ldd
这么说是因为:
$ readelf --dynamic libhello-musl.so | grep NEEDED; echo Done
Done
鉴于:
$ gcc -shared -o libhello-gnu.so hello.c
$ readelf --dynamic libhello-gnu.so | grep NEEDED; echo Done
0x0000000000000001 (NEEDED) Shared library [libc.so.6]
Done
$ ldd libhello-gnu.so
linux-vdso.so.1 (0x00007ffc4f5ce000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000079377ee00000)
/lib64/ld-linux-x86-64.so.2 (0x000079377f104000)
libhello-gnu.so
适合目的。
$ cat main.c
#include <stdio.h>
extern void hello(void);
int main(void)
{
hello();
return 0;
}
$ gcc -o hello main.c -L. -lhello-musl -Wl,-rpath=$(pwd)
$ ./hello
Hello World
$ ltrace -l libhello-musl.so ./hello
hello->hello(1, 0x7ffd219317d8, 0x7ffd219317e8, 0x5c2dd535bda0 <unfinished ...>
libhello-musl.so->puts("Hello World" <unfinished ...>
libhello-musl.so->fputs("Hello World", 0x78c0473fe060 <unfinished ...>
libhello-musl.so->strlen("Hello World") = 11
libhello-musl.so->fwrite("Hello World", 1, 11, 0x78c0473fe060 <unfinished ...>
libhello-musl.so->memcpy(0x78c0473fe188, "Hello World", 11) = 0x78c0473fe188
<... fwrite resumed> ) = 11
<... fputs resumed> ) = 0
Hello World
<... puts resumed> ) = 0
<... hello resumed> ) = 0
+++ exited (status 0) +++
从这个角度来看:
我怀疑问题集中在
静态链接上。libirc.so
似乎是一个错误的怀疑。
互联网上还提出了同类的其他例子
Relink `/path/to/libsome.so' with `/path/to/libc.so.6' for IFUNC symbol `symbol'
错误,其中没有出现
libsome.so
静态链接的观察结果。
其中包括:
其中
libsome.so
= /usr/lib/libgcc_s.so.1
发生了
链接到 libc.musl-x86_64.so.1
。
和:
这与您的误差模路径相同。
和:
这涉及 glibc 补丁:
于 2021 年 10 月 21 日承诺。
从这个角度来看,就像@n。米。我建议可能是人工智能 您的
[g]libc
的 libirc.so
版本已静态
链接的对象与您的 ./Solver
链接的对象未对齐。最可能的补救措施——像往常一样? - 是服从诊断:获取一个您知道已链接的新libirc.so
与 libc.so.6
(或相同的静态 PIC 版本)。如果这很难得到
无论您从何处获得最新版本的libirc.so
,它都可能是一个修复。