On Wednesday 11 January 2012 10:06:42 Richard Guenther wrote: > On Tue, Jan 10, 2012 at 8:50 PM, Tijl Coosemans <t...@freebsd.org> wrote: >> On Tuesday 10 January 2012 15:40:15 Richard Guenther wrote: >>> On Tue, Jan 10, 2012 at 3:38 PM, Richard Guenther >>> <richard.guent...@gmail.com> wrote: >>>> On Tue, Jan 10, 2012 at 3:14 PM, Tijl Coosemans <t...@coosemans.org> wrote: >>>>> 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. >>>> >>>> Works fine for me on i?86-linux without -lssp_nonshared (which I do not >>>> have, so linking would fail). >> >> So my patch would actually break Linux? > > Yes. > >>> Probably because libc.so is a linker script: >>> >>> /* GNU ld script >>> Use the shared library, but some functions are only in >>> the static library, so try that secondarily. */ >>> OUTPUT_FORMAT(elf64-x86-64) >>> GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( >>> /lib64/ld-linux-x86-64.so.2 ) ) >>> >>> and /usr/lib64/libc_nonshared.a provides the symbol. Why not fix it that >>> way on *BSD? >> >> I'll discuss it with some FreeBSD developers. Currently FreeBSD doesn't >> use linker scripts anywhere. Would a FreeBSD specific version of the >> patch be acceptable? For instance, the version of GCC shipped with >> FreeBSD has been patched like this: >> http://svnweb.freebsd.org/base/head/contrib/gcc/config/freebsd-spec.h?r1=195697&r2=195696 > > That looks better to me.
I've been using this patch now. It's similar to the above url, but conditional on TARGET_LIBC_PROVIDES_SSP to support older FreeBSD versions. Gerald volunteered to commit. Gerald, just trunk for now or older branches too? 2011-01-20 Tijl Coosemans <t...@coosemans.org> * gcc/config/freebsd-spec.h [TARGET_LIBC_PROVIDES_SSP] (LINK_SSP_SPEC): Define. --- gcc/config/freebsd-spec.h +++ gcc/config/freebsd-spec.h @@ -138,6 +138,10 @@ is built with the --enable-threads confi #define LINK_EH_SPEC "%{!static:--eh-frame-hdr} " #endif +#ifdef TARGET_LIBC_PROVIDES_SSP +#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared}" +#endif + /* Use --as-needed -lgcc_s for eh support. */ #ifdef HAVE_LD_AS_NEEDED #define USE_LD_AS_NEEDED 1