Message ID | 201201101514.40392.tijl@coosemans.org |
---|---|
State | New |
Headers | show |
On Tue, Jan 10, 2012 at 3:14 PM, Tijl Coosemans <tijl@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). Richard. > 2011-01-10 Tijl Coosemans <tijl@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
On Tue, Jan 10, 2012 at 3:38 PM, Richard Guenther <richard.guenther@gmail.com> wrote: > On Tue, Jan 10, 2012 at 3:14 PM, Tijl Coosemans <tijl@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). 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? Richard. > Richard. > >> 2011-01-10 Tijl Coosemans <tijl@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
On Tuesday 10 January 2012 15:40:15 Richard Guenther wrote: > On Tue, Jan 10, 2012 at 3:38 PM, Richard Guenther > <richard.guenther@gmail.com> wrote: >> On Tue, Jan 10, 2012 at 3:14 PM, Tijl Coosemans <tijl@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? > 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 >>> 2011-01-10 Tijl Coosemans <tijl@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
On Tue, Jan 10, 2012 at 8:50 PM, Tijl Coosemans <tijl@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.guenther@gmail.com> wrote: >>> On Tue, Jan 10, 2012 at 3:14 PM, Tijl Coosemans <tijl@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. Richard.
--- 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