On targets where libc implements stack protector functions (GNU libc, FreeBSD libc), and where gcc (as an optimisation) generates calls to a locally defined __stack_chk_fail_local instead of directly calling the global function __stack_chk_fail (e.g. -fpic code on i386), one must explicitly specify -lssp_nonshared or "-lc -lc_nonshared" on the command line to statically link in __stack_chk_fail_local.
It would be more convenient if the compiler kept the details of this target specific optimisation hidden by passing -lssp_nonshared to the linker internally. Here's a simple test case that shows the problem on i386-freebsd, but works just fine on e.g. x86_64 targets: % cat test.c int main( void ) { return( 0 ); } % gcc46 -o test test.c -fstack-protector-all -fPIE /var/tmp//ccjYQxKu.o: In function `main': test.c:(.text+0x37): undefined reference to `__stack_chk_fail_local' /usr/local/bin/ld: test: hidden symbol `__stack_chk_fail_local' isn't defined /usr/local/bin/ld: final link failed: Bad value collect2: ld returned 1 exit status I don't have commit access, so please commit when approved. 2011-01-10 Tijl Coosemans <t...@coosemans.org> * gcc.c [TARGET_LIBC_PROVIDES_SSP] (LINK_SSP_SPEC): Add -lssp_nonshared. --- gcc/gcc.c.orig +++ gcc/gcc.c @@ -602,7 +602,7 @@ proper position among the other output f #ifndef LINK_SSP_SPEC #ifdef TARGET_LIBC_PROVIDES_SSP -#define LINK_SSP_SPEC "%{fstack-protector:}" +#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared}" #else #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared -lssp}" #endif