gcc 6.2.0 试图在不应该的时候创建共享对象?

gcc 6.2.0 is attempting to create shared object when it shouldn't?

在 gcc 6.2.0 之前,使用不可重定位的汇编程序代码链接从来都不是问题。我不知道盯着这个的确切版本,但是对于 gcc 5.4.0(及更低版本)这有效:

$ gcc -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto

但是,对于 gcc 6.2.0:

$ gcc -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto
/usr/bin/ld: ../../../lib/libribs2_ssl.a(context_asm.o): relocation R_X86_64_32S against symbol `current_ctx' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status

尝试强制静态链接会产生另一个问题:

$ gcc -static -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto -ldl
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
(.text+0x11): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
../obj/httpget.o: In function `main':
/home/nir/ribs2/examples/httpget/src/httpget.c:194: warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

并且程序在使用 gethostbyname() 时出现段错误(但在其他情况下有效)

同样尝试混合静态和动态也不起作用。

$ gcc -o httpget -Wl,-Bstatic ../obj/httpget.o ../../../lib/libribs2_ssl.a -Wl,-Bdynamic -lssl -lcrypto
/usr/bin/ld: ../../../lib/libribs2_ssl.a(context_asm.o): relocation R_X86_64_32S against symbol `current_ctx' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status

有什么想法吗? Link 到项目:https://github.com/niryeffet/ribs2

感谢@Jester 的提示:向 LDFLAGS 添加 -no-pie(不是 -fno-PIE)解决了问题。

gcc -no-pie -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto

此更改也适用于 gcc 5.4。似乎默认值已更改。

更新:

这就解释了。来自 https://wiki.ubuntu.com/SecurityTeam/PIE

In Ubuntu 16.10, as an additional compiler hardening measure, we've enabled PIE and immediate binding by default on amd64 and ppc64le. This greatly increases the effectiveness of ASLR on those platforms.