svn commit: r251668 - head/lib/libc

Jeremie Le Hen jlh at FreeBSD.org
Wed Jun 12 21:12:06 UTC 2013


Author: jlh
Date: Wed Jun 12 21:12:05 2013
New Revision: 251668
URL: http://svnweb.freebsd.org/changeset/base/251668

Log:
  Turn libc.so into an ld script rather than a symlink pointing to the
  real shared object and libssp_nonshared.a.
  
  This was the last showstopper that prevented from enabling SSP for ports
  by default.  portmgr@ performed a buildworld which showed no significant
  breakage with this patch.
  
  Details:
  
  On i386 for PIC objects, gcc uses the __stack_chk_fail_local hidden
  symbol instead of calling __stack_chk_fail directly [1].  This happen
  not only with our gcc-4.2.1 but also with the latest gcc-4.8.  If you
  want the very nasty details, see [2].
  
  OTOH the problem doesn't exist on other architectures.  It also doesn't
  exist with Clang as the latter will somehow manage to create the
  function in the object file at compile time (contrary to only
  referencing it through a symbol that will be brought in at link time).
  
  In a perfect world, when an object file is compiled with
  -fstack-protector, it will be linked into a binary or a DSO with this
  same flag as well, so GCC will add libssp_nonshared.a to the linker
  command-line.  Unfortunately, we don't control softwares in ports and we
  may have such broken DSO.  This is the whole point of this patch.
  
  You can reproduce the problem on i386 by compiling a source file into an
  object file with "-fstack-protector-all -fPIE" and linking it
  into a binary without "-fstack-protector".
  
  This ld script automatically proposes libssp_nonshared.a along with the
  real libc DSO to the linker.  It is important to understand that the
  object file contained in this library will be pulled in the resulting
  binary _only if_ the linker notices one of its symbols is needed (i.e.
  one of the SSP symbol is missing).
  
  A theorical performance impact could be when compiling, but my testing
  showed less than 0.1% of difference.
  
  [1] For 32-bit code gcc saves the PIC register setup by using
      __stack_chk_fail_local hidden function instead of calling
      __stack_chk_fail directly.  See comment line 19460 in:
      src/contrib/gcc/config/i386/i386.c
  
  [2] When compiling a source file to an object file, if you use something
      which is external to the compilation unit, GCC doesn't know yet if
      this symbol will be inside or outside the DSO.  So it expects the
      worst case and routes the symbol through the GOT, which means
      additional space and extra relocation for rtld(1).
  
      Declaring a symbol has hidden tells GCC to use the optimal route (no
      GOT), but on the other hand this means the symbol has to be provided
      in the same DSO (namely libssp_nonshared.a).
  
      On i386, GCC actually uses an hidden symbol for SSP in PIC objects
      to save PIC register setup, as said in [1].
  
  PR:		ports/138228
  PR:		ports/168010
  Reviewed by:	kib, kan

Added:
  head/lib/libc/libc.ldscript   (contents, props changed)
Modified:
  head/lib/libc/Makefile

Modified: head/lib/libc/Makefile
==============================================================================
--- head/lib/libc/Makefile	Wed Jun 12 20:11:49 2013	(r251667)
+++ head/lib/libc/Makefile	Wed Jun 12 21:12:05 2013	(r251668)
@@ -23,6 +23,7 @@ LIBC_ARCH=${MACHINE_CPUARCH}
 # to CFLAGS below.  -DSYSLIBC_SCCS affects just the system call stubs.
 LIB=c
 SHLIB_MAJOR= 7
+SHLIB_LDSCRIPT=libc.ldscript
 WARNS?=	2
 CFLAGS+=-I${.CURDIR}/include -I${.CURDIR}/../../include
 CFLAGS+=-I${.CURDIR}/${LIBC_ARCH}

Added: head/lib/libc/libc.ldscript
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/libc.ldscript	Wed Jun 12 21:12:05 2013	(r251668)
@@ -0,0 +1,2 @@
+/* $FreeBSD$ */
+GROUP ( @@SHLIB@@ @@LIBDIR@@/libssp_nonshared.a )


More information about the svn-src-head mailing list