共享对象如何静态链接

问题描述 投票:0回答:1

我有一个共享对象,其中 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 在绑定符号时出现段错误。

linux gcc linker ld-preload
1个回答
0
投票

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
,它都可能是一个修复。

© www.soinside.com 2019 - 2024. All rights reserved.