Description of problem: gcc should compile crtbeginT.o w/ fPIC on Intel 64 to avoid following problem - seen when using icc -fast to create a shared library (that example below). This works: $ gcc -static -fpic scale.c -o libscale.so -shared -m32 This fails: $ gcc -static -fpic scale.c -o libscale.so -shared -m64 /usr/bin/ld: /opt/spdtools/compiler/ia32e/gcc-4.1.0/lib/gcc/x86_64-unknown- linux-gnu/4.1.0/crtbeginT.o: relocation R_X86_64_32 can not be used when making a shared object; recompile with -fPIC /opt/spdtools/compiler/ia32e/gcc-4.1.0/lib/gcc/x86_64-unknown-linux- gnu/4.1.0/crtbeginT.o: could not read symbols: Bad value collect2: ld returned 1 exit status Version-Release number of selected component (if applicable): $ gcc -v Using built-in specs. Target: x86_64-unknown-linux-gnu Configured with: ../gcc-4.1.0/configure -- prefix=/opt/spdtools/compiler/ia32e/gcc-4.1.0 Thread model: posix gcc version 4.1.0 How reproducible: I was able to reproduce this problem with gcc 3.2.3 and 4.0.0 on x86_64. I did not see the problem using gcc 4.1.0. Steps to Reproduce: 1. Copy test case (below) to an x86_64 machine 2. Compile the test case: gcc -static -fpic scale.c -o libscale.so -shared -m64 3. Look for error message Actual results: // Fails with -m64 % gcc40 -static -fpic scale.c -o libscale.so -shared -m64 /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/4.1.0/crtbeginT.o: relocation R_X86_64_32 against `__deregister_frame_info' can not be used when making a shared object; recompile with -fPIC /usr/lib/gcc/x86_64-redhat-linux/4.1.0/crtbeginT.o: could not read symbols: Bad value collect2: ld returned 1 exit status Expected results: // Works with -m32 % gcc40 -static -fpic scale.c -o libscale.so -shared -m32 % Additional info: Here's the test case: % cat scale.c #include <stdio.h> int scale(int val) { const int scalefactor = 999; int i= scalefactor * val; printf("scalefactor=%i. val=%i. i=%i \n", scalefactor, val, i); return i; }
This is a user error. Using -static together with -shared is nonsense. Either you want to create a shared library, or a statically linked binary, but never both.
*** Bug 214464 has been marked as a duplicate of this bug. ***
crtbeginT.o is not, and should not be PIC. `gcc -shared` should link to crtbeginS.o. This problem still existed as of gcc 4.3.3. (In reply to comment #1) > This is a user error. Using -static together with -shared is nonsense. > Either you want to create a shared library, or a statically linked binary, > but never both. Calling it "error" or "nonsense" is dismissive. `gcc -shared -static` works on some installations. Sometimes it is a good compromise. cf. the well-known option --static-libgcc and the new option --static-libstdc++ in gcc 4.5. Explanation from GNU gcc manual: 3.13 Options for Linking http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html "it is sometimes useful to freeze the version of libstdc++ used by the program".
I don't see how this is nonsense. -static does not necessarily mean "create a static executable" it simply means "do not link against shared libraries" which makes perfect sense in the context of creating a shared library. Additionally, I think we would agree on the fact that -static and -shared are linking options. Coincidentally the linker interprets them exactly as Jeff intended when opening the bug. From ld(1): -static [..] This option can be used with -shared. Doing so means that a shared library is being created but that all of the library's external references must be resolved by pulling in entries from static libraries. Which is exactly Jeff meant when passing -static and -shared to gcc.
If you want to link some libraries statically, the option to use is -shared -Wl,-Bstatic -lfoo -lbar -Wl,-Bdynamic for libraries you want to link statically into the shared libraries listed in between -Bstatic and -Bdynamic. The shared libraries usually have to be built in a special way for that to work (-fpic), otherwise they either fail to link properly, or even if they get linked with text relocations, they might be refused to dynamically link for security reasons (e.g. SELinux). System libraries like libgcc or libc usually can't be linked that way, so you want either always end the command line in -Wl,-Bdynamic state (after the end of command line the gcc driver adds system libraries), or link with -nostdlib and add whatever system libraries you want to link explicitly.
I disagree with this not being a bug. In part also because this does not only affect dynamic libraries but also executables when you use "-static -pie". I consider it quite a significant annoyance that it is not possible to compile static linking (to allow the binary to run on basically any system) with PIE (to get additional security). The -Bstatic/-Bdynamic workaround is a bad hack, since it depends on the position there is no way to add it e.g. via CFLAGS so every single project that wants to support PIE with static linking will have to add special support to their build system. That certainly isn't a way to help making more secure compilation options the default!