【发布时间】:2014-12-04 07:35:51
【问题描述】:
以下问题是相关的,但不回答我的问题:
Linking partially static and partially dynamic in GCC
Linking a dynamic library to a static library that links to other static libraries
GCC: static linking only some libraries
Static link of shared library function in gcc
我之前问了一个非常相似的问题,但是由于我提出的上一个问题在评论部分有些混乱并且没有完全回答(但我将其标记为已回答,因为这是一个很好的努力并且至少部分回答了它) 我会问一个新问题。问题具体是如何将 libc 链接为静态,同时动态链接其他一些库(例如 libm)。有人建议在第一个问题中无法做到这一点,这是真的吗?如果是这样,知道为什么不这样做会很有趣。
甚至有可能做到这一点吗?有人发表了评论(由于某种原因被删除,也许是不正确的?)这是可能的,但是必须也存在动态链接版本的 libc,因为它将被动态库(例如动态库需要动态库(?))。
这对我来说很好,但对我来说如何告诉 GCC 这样做并不明显,即在 libc 中链接为静态和动态。我该怎么做(我做了几次尝试,一些在问题后面显示)?还是有其他方法可以做我想做的事?
我们首先看到,通过简单的运行 gcc test.c -lm,一切都是动态链接的,如下:
$ gcc test.c -lm
$ ldd a.out
linux-vdso.so.1 (0x00007fffb37d1000)
libm.so.6 => /lib64/libm.so.6 (0x00007f3b0eeb6000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3b0eb10000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3b0f1b0000)
要仅将 libm 链接为静态,同时允许 libc 保持动态,我们可以这样做(正如 Z boson 在上述问题之一中指出的那样):
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libm.a
$ ldd a.out
linux-vdso.so.1 (0x00007fff747ff000)
libc.so.6 => /lib64/libc.so.6 (0x00007f09aaa0c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f09aadb2000)
但是,尝试相同的过程来链接 libc 静态和 libm 动态,似乎不起作用:
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a -lm
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
这个错误信息是什么意思?
其他一些尝试(大部分也包含在我的第一个问题中):
$ gcc test.c /usr/lib64/libc.a
linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
urned 1 exit status
$ gcc test.c -Wl,-Bdynamic -lm -Wl,-Bstatic -lc
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
$ gcc -Wl,-Bdynamic -lm -Wl,-Bstatic -lc test.c
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
$ gcc -Wl,-Bstatic -lc -Wl,-Bdynamic -lm test.c
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.so -lm
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.so /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a -lm
注意最后一个编译/链接成功。但是 libc 并没有静态链接,只是动态链接,所以又是一次失败的尝试。
测试程序简单如下:
$ cat test.c
#include <stdio.h>
#include <math.h>
int main(int argc, char **argv)
{
int i;
int result;
for(i = 0; i < 65535; i++) {
result = sin(i);
}
return 0;
}
编辑:
我也尝试过 statifier 和 ermine,正如这个问题所建议的那样:
Static link of shared library function in gcc
都不行。
【问题讨论】:
-
您要解决的问题是什么?我的意思是在更高的层次上,而不是“我想静态链接”。也许我们可以解决这个问题。
-
libm链接到libc- 这可能是问题的一部分(请参阅ldd /usr/lib64/libm.so)。 -
@John Zwinck,这不是微不足道的,我试图证明在某些特殊情况下可以针对英特尔 MPX 进行基于 ROP 的漏洞利用,但它需要 libmpx(它只存在于动态链接形式,据我所知,没有可用的源代码)是动态链接的,而 libc 是静态链接的。但是,如果这是不可能的,那么知道为什么不这样做会很有趣,我会寻找一种不同的方法。
-
@el.pescado,是的,这很可能至少是问题的一部分,在其他问题中的评论消失之前,评论部分已简要指出。
-
您需要静态链接的整个 libc,还是只需要几个特定函数?