问题
With non relocatable assembler code linking was never a problem up until gcc 6.2.0. I don't know the exact version that stared this, but with gcc 5.4.0 (and below) this worked:
$ gcc -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto
However, with 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
Trying to force static linking creates another problem:
$ 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
And the program segfaults when using gethostbyname() (but works otherwise)
Also trying to mix static and dynamic doesn't work.
$ 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
Any ideas? Link to the project: https://github.com/niryeffet/ribs2
回答1:
Thanks to the hint from @Jester: adding -no-pie (not -fno-PIE) to LDFLAGS solved the problem.
gcc -no-pie -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto
The change also works on gcc 5.4. It seems as the default has changed.
UPDATE:
This explains it. From 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.
来源:https://stackoverflow.com/questions/40246054/gcc-6-2-0-is-attempting-to-create-shared-object-when-it-shouldnt