-static and -pie are incompatible, yet gcc neither warns nor errors on the combination. What's more, gcc's behaviour depends on whether gcc was built with --enable-default-pie. If gcc was built with --enable-default-pie then -static silently overrides an explicit -pie, at least on x86 and I suspect most targets. -static is passed on to ld, gcc specifies the static startup files, and no -dynamic-linker is passed to ld. This is reasonable, but a warning that the explicit -pie was overridden would be nicer. If gcc was built with --disable-default-pie then -static does not fully override -pie. On x86, you get the static startup files, no -dynamic-linker, and both -static and -pie are passed on to the linker. ld.gold errors on that combination. ld.bfd tries to generate a PIE using the static startup files and static (typically non-pic) libraries, and typically the wrong ld.so. The wrong ld.so leads to a somewhat cryptic "file not found" message on trying to run an executable. Non-pic startup and libraries result in a linker error on x86_64, and text relocations on powerpc64le. TEXTREL and ifunc as found in modern glibc are fundamentally incompatible: When applying the text relocations, ld.so makes the text segment temporarily writeable (and non-exec), but the text needs to be exec to run ifunc resolvers. A segfault before main is the result.
Revising my original comments.. According to the gcc docs -static is supposed to just prevent linking with dynamic libraries. I agree that this is traditional linker behaviour. That means, for example, that -shared -static ought to create a shared library but any libraries linked should be static libraries. Presumably those libraries would have been compiled PIC. Similarly, -pie -static ought to create a PIE but any libraries linked should be static libraries, presumably also compiled as PIC. Of course on most Linux systems static libraries are not PIC so aren't suitable for use in a PIE. However, there isn't really a fundamental reason the option combination should not be allowed. It is true that -pie -static chooses wrong startup files, and doesn't pass a -dynamic-linker option to ld. That is a bug. Also, an explicit -pie -static when gcc is configured for --enable-default-pie ought to behave the same as -pie -static when PIEs are not default. ie. gcc should produce a PIE, not a static executable in that case.
I think I'm wasting everybody's time with this issue.
see PR 7516