This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch hjl/pie/static created. glibc-2.26.9000-996-gf788289


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, hjl/pie/static has been created
        at  f7882894427b3d720892667418b5d97dc179c1e9 (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f7882894427b3d720892667418b5d97dc179c1e9

commit f7882894427b3d720892667418b5d97dc179c1e9
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Sep 27 16:47:29 2017 -0700

    Add --enable-static-pie to build-many-glibcs.py

diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py
index 5453000..bac9916 100755
--- a/scripts/build-many-glibcs.py
+++ b/scripts/build-many-glibcs.py
@@ -1338,6 +1338,7 @@ class Glibc(object):
         cmdlist.create_copy_dir(srcdir, srcdir_copy)
         cfg_cmd = [os.path.join(srcdir_copy, 'configure'),
                    '--prefix=/usr',
+                   '--enable-static-pie',
                    '--enable-profile',
                    '--build=%s' % self.ctx.build_triplet,
                    '--host=%s' % self.triplet,

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=882a61c686b85cd1016c0909ca17cf508e307efc

commit 882a61c686b85cd1016c0909ca17cf508e307efc
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Sep 28 16:13:54 2017 -0700

    sparc: Check PIC instead of SHARED in start.S
    
    Since start.o may be compiled as PIC, we should check PIC instead of
    SHARED.
    
    	* sysdeps/sparc/sparc32/start.S (_start): Check PIC instead of
    	SHARED.
    	* sysdeps/sparc/sparc64/start.S (_start): Likewise.

diff --git a/sysdeps/sparc/sparc32/start.S b/sysdeps/sparc/sparc32/start.S
index a06568d..b882d1e 100644
--- a/sysdeps/sparc/sparc32/start.S
+++ b/sysdeps/sparc/sparc32/start.S
@@ -42,7 +42,7 @@
 	.global _start
 	.type _start,#function
 _start:
-#ifdef SHARED
+#ifdef PIC
 	SETUP_PIC_REG(l7)
 #endif
 
@@ -57,7 +57,7 @@ _start:
 	add	%sp, 23*4, %o2
 
   /* Load the addresses of the user entry points.  */
-#ifndef SHARED
+#ifndef PIC
 	sethi	%hi(main), %o0
 	sethi	%hi(__libc_csu_init), %o3
 	sethi	%hi(__libc_csu_fini), %o4
diff --git a/sysdeps/sparc/sparc64/start.S b/sysdeps/sparc/sparc64/start.S
index fcd4721..21d16de 100644
--- a/sysdeps/sparc/sparc64/start.S
+++ b/sysdeps/sparc/sparc64/start.S
@@ -42,7 +42,7 @@
 	.global _start
 	.type _start,#function
 _start:
-#ifdef SHARED
+#ifdef PIC
 	SETUP_PIC_REG(l7)
 #endif
 
@@ -58,7 +58,7 @@ _start:
 	add	%sp, STACK_BIAS+23*8, %o2
 
   /* Load the addresses of the user entry points.  */
-#ifndef SHARED
+#ifndef PIC
 	sethi	%hi(main), %o0
 	sethi	%hi(__libc_csu_init), %o3
 	sethi	%hi(__libc_csu_fini), %o4

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=cbf62acd2955290b3bce6174e68b5a40afed5ed2

commit cbf62acd2955290b3bce6174e68b5a40afed5ed2
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Sep 28 16:13:22 2017 -0700

    microblaze: Check PIC instead of SHARED in start.S
    
    Since start.o may be compiled as PIC, we should check PIC instead of
    SHARED.
    
    	* sysdeps/microblaze/start.S (_start): Check PIC instead of SHARED.

diff --git a/sysdeps/microblaze/start.S b/sysdeps/microblaze/start.S
index f94e816..d9b13d0 100644
--- a/sysdeps/microblaze/start.S
+++ b/sysdeps/microblaze/start.S
@@ -58,7 +58,7 @@ _start:
     sw      r6,r1,r0
     addik   r7,r1,4
     addik   r1,r1,-24
-#ifdef SHARED
+#ifdef PIC
     /* Setup PIC.  */
     mfs     r20,rpc
     addik   r20,r20,_GLOBAL_OFFSET_TABLE_+8

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c4e62403a180cc19785aab8b4a641fd5507dd156

commit c4e62403a180cc19785aab8b4a641fd5507dd156
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Sep 28 14:55:18 2017 -0700

    sh: Update elf_machine_load_address for static PIE
    
    When --enable-static-pie is used to configure glibc, we need to use
    _dl_relocate_static_pie to compute load address in static PIE.
    
    	* sysdeps/sh/dl-machine.h (elf_machine_load_address): Use
    	_dl_relocate_static_pie instead of _dl_start to compute load
    	address in static PIE.

diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
index 7106afb..cfcc4d9 100644
--- a/sysdeps/sh/dl-machine.h
+++ b/sysdeps/sh/dl-machine.h
@@ -50,6 +50,7 @@ static inline Elf32_Addr __attribute__ ((unused))
 elf_machine_load_address (void)
 {
   Elf32_Addr addr;
+#ifdef SHARED
   asm ("mov.l 1f,r0\n\
 	mov.l 3f,r2\n\
 	add r12,r2\n\
@@ -61,6 +62,19 @@ elf_machine_load_address (void)
 	3: .long _dl_start@GOTOFF\n\
 	2: mov r2,%0"
        : "=r" (addr) : : "r0", "r1", "r2");
+#else
+  asm ("mov.l 1f,r0\n\
+	mov.l 3f,r2\n\
+	add r12,r2\n\
+	mov.l @(r0,r12),r0\n\
+	bra 2f\n\
+	 sub r0,r2\n\
+	.align 2\n\
+	1: .long _dl_relocate_static_pie@GOT\n\
+	3: .long _dl_relocate_static_pie@GOTOFF\n\
+	2: mov r2,%0"
+       : "=r" (addr) : : "r0", "r1", "r2");
+#endif
   return addr;
 }
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=4d7a746c98f130e78c33a8beb2d293d0312b53ad

commit 4d7a746c98f130e78c33a8beb2d293d0312b53ad
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Sep 28 14:53:06 2017 -0700

    s390: Update elf_machine_load_address for static PIE
    
    When --enable-static-pie is used to configure glibc, we need to use
    _dl_relocate_static_pie to compute load address in static PIE.
    
    	* sysdeps/s390/s390-32/dl-machine.h (elf_machine_dynamic): Use
    	_dl_relocate_static_pie instead of _dl_start to compute load
    	address in static PIE.
    	* sysdeps/s390/s390-64/dl-machine.h (elf_machine_dynamic):
    	Likewise.

diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index c302c9d..da6817e 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -70,6 +70,7 @@ elf_machine_load_address (void)
 {
   Elf32_Addr addr;
 
+#ifdef SHARED
   __asm__( "   bras  1,2f\n"
 	   "1: .long _GLOBAL_OFFSET_TABLE_ - 1b\n"
 	   "   .long (_dl_start - 1b - 0x80000000) & 0x00000000ffffffff\n"
@@ -78,6 +79,16 @@ elf_machine_load_address (void)
 	   "   al    1,0(1)\n"
 	   "   sl    %0,_dl_start@GOT(1)"
 	   : "=&d" (addr) : : "1" );
+#else
+  __asm__( "   bras  1,2f\n"
+	   "1: .long _GLOBAL_OFFSET_TABLE_ - 1b\n"
+	   "   .long (_dl_relocate_static_pie - 1b - 0x80000000) & 0x00000000ffffffff\n"
+	   "2: l     %0,4(1)\n"
+	   "   ar    %0,1\n"
+	   "   al    1,0(1)\n"
+	   "   sl    %0,_dl_relocate_static_pie@GOT(1)"
+	   : "=&d" (addr) : : "1" );
+#endif
   return addr;
 }
 
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
index 7513520..5ef1c60 100644
--- a/sysdeps/s390/s390-64/dl-machine.h
+++ b/sysdeps/s390/s390-64/dl-machine.h
@@ -63,11 +63,19 @@ elf_machine_load_address (void)
 {
   Elf64_Addr addr;
 
+#ifdef SHARED
   __asm__( "   larl	 %0,_dl_start\n"
 	   "   larl	 1,_GLOBAL_OFFSET_TABLE_\n"
 	   "   lghi	 2,_dl_start@GOT\n"
 	   "   slg	 %0,0(2,1)"
 	   : "=&d" (addr) : : "1", "2" );
+#else
+  __asm__( "   larl	 %0,_dl_relocate_static_pie\n"
+	   "   larl	 1,_GLOBAL_OFFSET_TABLE_\n"
+	   "   lghi	 2,_dl_relocate_static_pie@GOT\n"
+	   "   slg	 %0,0(2,1)"
+	   : "=&d" (addr) : : "1", "2" );
+#endif
   return addr;
 }
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=44e46587845edfbfc58133037e1d90efca829cd6

commit 44e46587845edfbfc58133037e1d90efca829cd6
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Jul 17 08:17:32 2017 -0700

    Add --enable-static-pie configure option to build static PIE [BZ #19574]
    
    Static PIE extends address space layout randomization to static
    executables.  It provides additional security hardening benefits at
    the cost of some memory and performance.
    
    Dynamic linker, ld.so, is a standalone program which can be loaded at
    any address.  This patch adds a configure option, --enable-static-pie,
    to embed the part of ld.so in static executable to create static position
    independent executable (static PIE).  A static PIE is similar to static
    executable, but can be loaded at any address without help from a dynamic
    linker.  When --enable-static-pie is used to configure glibc, libc.a is
    built as PIE and all static executables, including tests, are built as
    static PIE.  The resulting libc.a can be used together with GCC 8 or
    above to build static PIE with the compiler option, -static-pie.  But
    GCC 8 isn't required to build glibc with --enable-static-pie.  Only GCC
    with PIE support is needed.  When an older GCC is used to build glibc
    with --enable-static-pie, proper input files are passed to linker to
    create static executables as static PIE, together with "-z text" to
    prevent dynamic relocations in read-only segments, which are not allowed
    in static PIE.
    
    The following changes are made for static PIE:
    
    1. Add a new function, _dl_relocate_static_pie, to:
       a. Get the run-time load address.
       b. Read the dynamic section.
       c. Perform dynamic relocations.
    Dynamic linker also performs these steps.  But static PIE doesn't load
    any shared objects.
    2. Call _dl_relocate_static_pie at entrance of LIBC_START_MAIN in
    libc.a.  crt1.o, which is used to create dynamic and non-PIE static
    executables, is updated to include a dummy _dl_relocate_static_pie.
    rcrt1.o is added to create static PIE, which will link in the real
    _dl_relocate_static_pie.  grcrt1.o is also added to create static PIE
    with -pg.  GCC 8 has been updated to support rcrt1.o and grcrt1.o for
    static PIE.
    
    Static PIE can work on all architectures which support PIE, provided:
    
    1. Target must support accessing of local functions without dynamic
    relocations, which is needed in start.S to call __libc_start_main with
    function addresses of __libc_csu_init, __libc_csu_fini and main.  All
    functions in static PIE are local functions.  If PIE start.S can't reach
    main () defined in a shared object, the code sequence:
    
    	pass address of local_main to __libc_start_main
    	...
    
    local_main:
    	tail call to main via PLT
    
    can be used.
    2. start.S is updated to check PIC instead SHARED for PIC code path and
    avoid dynamic relocation, when PIC is defined and SHARED isn't defined,
    to support static PIE.  Patches are submitted for aarch64, hppa, m68k,
    microblaze and sparc.
    3. All assembly codes are updated check PIC instead SHARED for PIC code
    path to avoid dynamic relocations in read-only sections.
    4. All assembly codes are updated check SHARED instead PIC for static
    symbol name.  A patch is submitted for tile.
    5. elf_machine_load_address in dl-machine.h are updated to support static
    PIE.  Patches are submitted for aarch64, s390 and sh.
    6. __brk works without TLS nor dynamic relocations in read-only section
    so that it can be used by __libc_setup_tls to initializes TLS in static
    PIE.
    
    NB: When glibc is built with GCC defaulted to PIE, libc.a is compiled
    with -fPIE, regardless if --enable-static-pie is used to configure glibc.
    When glibc is configured with --enable-static-pie, libc.a is compiled
    with -fPIE, regardless whether GCC defaults to PIE or not.  The same
    libc.a can be used to build both static executable and static PIE.
    There is no need for separate PIE copy of libc.a.
    
    On x86-64, the normal static sln:
    
       text	   data	    bss	    dec	    hex	filename
     625425	   8284	   5456	 639165	  9c0bd	elf/sln
    
    the static PIE sln:
    
       text	   data	    bss	    dec	    hex	filename
     657626	  20636	   5392	 683654	  a6e86	elf/sln
    
    The code size is increased by 5% and the binary size is increased by 7%.
    
    Linker requirements to build glibc with --enable-static-pie:
    
    1. Linker supports --no-dynamic-linker to remove PT_INTERP segment from
    static PIE.
    2. Linker can create working static PIE.  The x86-64 linker needs the
    fix for
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=21782
    
    The i386 linker needs to be able to convert "movl main@GOT(%ebx), %eax"
    to "leal main@GOTOFF(%ebx), %eax" if main is defined locally.
    
    Binutils 2.29 or above are OK for i686 and x86-64.  But linker status for
    other targets need to be verified.
    
    3. Linker should resolve undefined weak symbols to 0 in static PIE:
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=22269
    
    4. Many ELF backend linkers incorrectly check bfd_link_pic for TLS
    relocations, which should check bfd_link_executable instead:
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=22263
    
    Tested on aarch64, i686 and x86-64.
    
    Using GCC 7 and binutils master branch, build-many-glibcs.py with
    --enable-static-pie with all patches for static PIE applied have the
    following build successes:
    
    PASS: glibcs-aarch64_be-linux-gnu build
    PASS: glibcs-aarch64-linux-gnu build
    PASS: glibcs-armeb-linux-gnueabi-be8 build
    PASS: glibcs-armeb-linux-gnueabi build
    PASS: glibcs-armeb-linux-gnueabihf-be8 build
    PASS: glibcs-armeb-linux-gnueabihf build
    PASS: glibcs-arm-linux-gnueabi build
    PASS: glibcs-arm-linux-gnueabihf build
    PASS: glibcs-arm-linux-gnueabihf-v7a build
    PASS: glibcs-arm-linux-gnueabihf-v7a-disable-multi-arch build
    PASS: glibcs-m68k-linux-gnu build
    PASS: glibcs-microblazeel-linux-gnu build
    PASS: glibcs-microblaze-linux-gnu build
    PASS: glibcs-mips64el-linux-gnu-n32 build
    PASS: glibcs-mips64el-linux-gnu-n32-nan2008 build
    PASS: glibcs-mips64el-linux-gnu-n32-nan2008-soft build
    PASS: glibcs-mips64el-linux-gnu-n32-soft build
    PASS: glibcs-mips64el-linux-gnu-n64 build
    PASS: glibcs-mips64el-linux-gnu-n64-nan2008 build
    PASS: glibcs-mips64el-linux-gnu-n64-nan2008-soft build
    PASS: glibcs-mips64el-linux-gnu-n64-soft build
    PASS: glibcs-mips64-linux-gnu-n32 build
    PASS: glibcs-mips64-linux-gnu-n32-nan2008 build
    PASS: glibcs-mips64-linux-gnu-n32-nan2008-soft build
    PASS: glibcs-mips64-linux-gnu-n32-soft build
    PASS: glibcs-mips64-linux-gnu-n64 build
    PASS: glibcs-mips64-linux-gnu-n64-nan2008 build
    PASS: glibcs-mips64-linux-gnu-n64-nan2008-soft build
    PASS: glibcs-mips64-linux-gnu-n64-soft build
    PASS: glibcs-mipsel-linux-gnu build
    PASS: glibcs-mipsel-linux-gnu-nan2008 build
    PASS: glibcs-mipsel-linux-gnu-nan2008-soft build
    PASS: glibcs-mipsel-linux-gnu-soft build
    PASS: glibcs-mips-linux-gnu build
    PASS: glibcs-mips-linux-gnu-nan2008 build
    PASS: glibcs-mips-linux-gnu-nan2008-soft build
    PASS: glibcs-mips-linux-gnu-soft build
    PASS: glibcs-nios2-linux-gnu build
    PASS: glibcs-powerpc64le-linux-gnu build
    PASS: glibcs-powerpc64-linux-gnu build
    PASS: glibcs-tilegxbe-linux-gnu-32 build
    PASS: glibcs-tilegxbe-linux-gnu build
    PASS: glibcs-tilegx-linux-gnu-32 build
    PASS: glibcs-tilegx-linux-gnu build
    PASS: glibcs-tilepro-linux-gnu build
    
    and the following build failures:
    
    FAIL: glibcs-alpha-linux-gnu build
    
    elf/sln is failed to link due to:
    
    assertion fail bfd/elf64-alpha.c:4125
    
    This is caused by linker bug and/or non-PIC code in PIE libc.a.
    
    FAIL: glibcs-hppa-linux-gnu build
    
    elf/sln is failed to link due to:
    
    collect2: fatal error: ld terminated with signal 11 [Segmentation fault]
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=22537
    
    FAIL: glibcs-ia64-linux-gnu build
    
    elf/sln is failed to link due to:
    
    collect2: fatal error: ld terminated with signal 11 [Segmentation fault]
    
    FAIL: glibcs-powerpc-linux-gnu build
    FAIL: glibcs-powerpc-linux-gnu-soft build
    FAIL: glibcs-powerpc-linux-gnuspe build
    FAIL: glibcs-powerpc-linux-gnuspe-e500v1 build
    
    elf/sln is failed to link due to:
    
    ld: read-only segment has dynamic relocations.
    
    This is caused by linker bug and/or non-PIC code in PIE libc.a.  See:
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=22264
    
    FAIL: glibcs-powerpc-linux-gnu-power4 build
    
    elf/sln is failed to link due to:
    
    findlocale.c:96:(.text+0x22c): @local call to ifunc memchr
    
    This is caused by linker bug and/or non-PIC code in PIE libc.a.
    
    FAIL: glibcs-s390-linux-gnu build
    
    elf/sln is failed to link due to:
    
    collect2: fatal error: ld terminated with signal 11 [Segmentation fault], core dumped
    
    assertion fail bfd/elflink.c:14299
    
    This is caused by linker bug and/or non-PIC code in PIE libc.a.
    
    FAIL: glibcs-sh3eb-linux-gnu build
    FAIL: glibcs-sh3-linux-gnu build
    FAIL: glibcs-sh4eb-linux-gnu build
    FAIL: glibcs-sh4eb-linux-gnu-soft build
    FAIL: glibcs-sh4-linux-gnu build
    FAIL: glibcs-sh4-linux-gnu-soft build
    
    elf/sln is failed to link due to:
    
    ld: read-only segment has dynamic relocations.
    
    This is caused by linker bug and/or non-PIC code in PIE libc.a.  See:
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=22263
    
    Also TLS code sequence in SH assembly syscalls in glibc doesn't match TLS
    code sequence expected by ld:
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=22270
    
    FAIL: glibcs-sparc64-linux-gnu build
    FAIL: glibcs-sparcv9-linux-gnu build
    FAIL: glibcs-tilegxbe-linux-gnu build
    FAIL: glibcs-tilegxbe-linux-gnu-32 build
    FAIL: glibcs-tilegx-linux-gnu build
    FAIL: glibcs-tilegx-linux-gnu-32 build
    FAIL: glibcs-tilepro-linux-gnu build
    
    elf/sln is failed to link due to:
    
    ld: read-only segment has dynamic relocations.
    
    This is caused by linker bug and/or non-PIC code in PIE libc.a.  See:
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=22263
    
    	[BZ #19574]
    	* INSTALL: Regenerated.
    	* Makeconfig (real-static-start-installed-name): New.
    	(pic-default): Updated for --enable-static-pie.
    	(pie-default): New for --enable-static-pie.
    	(default-pie-ldflag): Likewise.
    	(+link-static-before-libc): Replace $(DEFAULT-LDFLAGS-$(@F))
    	with $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)).
    	Replace $(static-start-installed-name) with
    	$(real-static-start-installed-name).
    	(+prectorT): Updated for --enable-static-pie.
    	(+postctorT): Likewise.
    	(CFLAGS-.o): Add $(pie-default).
    	(CFLAGS-.op): Likewise.
    	* NEWS: Mention --enable-static-pie.
    	* config.h.in (ENABLE_STATIC_PIE): New.
    	* configure.ac (--enable-static-pie): New configure option.
    	(have-no-dynamic-linker): New LIBC_CONFIG_VAR.
    	(have-static-pie): Likewise.
    	Enable static PIE if linker supports --no-dynamic-linker.
    	(ENABLE_STATIC_PIE): New AC_DEFINE.
    	(enable-static-pie): New LIBC_CONFIG_VAR.
    	* configure: Regenerated.
    	* csu/Makefile (omit-deps): Add r$(start-installed-name) and
    	gr$(start-installed-name) for --enable-static-pie.
    	(extra-objs): Likewise.
    	(install-lib): Likewise.
    	(extra-objs): Add static-reloc.o and static-reloc.os
    	($(objpfx)$(start-installed-name)): Also depend on
    	$(objpfx)static-reloc.o.
    	($(objpfx)r$(start-installed-name)): New.
    	($(objpfx)g$(start-installed-name)): Also depend on
    	$(objpfx)static-reloc.os.
    	($(objpfx)gr$(start-installed-name)): New.
    	* csu/libc-start.c (LIBC_START_MAIN): Call _dl_relocate_static_pie
    	in libc.a.
    	* csu/libc-tls.c (__libc_setup_tls): Add main_map->l_addr to
    	initimage.
    	* csu/static-reloc.c: New file.
    	* elf/Makefile (routines): Add dl-reloc-static-pie.
    	(elide-routines.os): Likewise.
    	(DEFAULT-LDFLAGS-tst-tls1-static-non-pie): Removed.
    	(tst-tls1-static-non-pie-no-pie): New.
    	* elf/dl-reloc-static-pie.c: New file.
    	* elf/dl-support.c (_dl_get_dl_main_map): New function.
    	* elf/dynamic-link.h (ELF_DURING_STARTUP): Also check
    	STATIC_PIE_BOOTSTRAP.
    	* elf/get-dynamic-info.h (elf_get_dynamic_info): Likewise.
    	* gmon/Makefile (tests): Add tst-gmon-static-pie.
    	(tests-static): Likewise.
    	(DEFAULT-LDFLAGS-tst-gmon-static): Removed.
    	(tst-gmon-static-no-pie): New.
    	(CFLAGS-tst-gmon-static-pie.c): Likewise.
    	(CRT-tst-gmon-static-pie): Likewise.
    	(tst-gmon-static-pie-ENV): Likewise.
    	(tests-special): Likewise.
    	($(objpfx)tst-gmon-static-pie.out): Likewise.
    	(clean-tst-gmon-static-pie-data): Likewise.
    	($(objpfx)tst-gmon-static-pie-gprof.out): Likewise.
    	* gmon/tst-gmon-static-pie.c: New file.
    	* manual/install.texi: Document --enable-static-pie.
    	* sysdeps/generic/ldsodefs.h (_dl_relocate_static_pie): New.
    	(_dl_get_dl_main_map): Likewise.
    	* sysdeps/i386/configure.ac: Check if linker supports static PIE.
    	* sysdeps/x86_64/configure.ac: Likewise.
    	* sysdeps/i386/configure: Regenerated.
    	* sysdeps/x86_64/configure: Likewise.
    	* sysdeps/mips/Makefile (ASFLAGS-.o): Add $(pie-default).
    	(ASFLAGS-.op): Likewise.

diff --git a/INSTALL b/INSTALL
index 80306de..9a1404b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -86,6 +86,15 @@ will be used, and CFLAGS sets optimization options for the compiler.
      systems support shared libraries; you need ELF support and
      (currently) the GNU linker.
 
+'--enable-static-pie'
+     Enable static position independent executable (static PIE) support.
+     Static PIE is similar to static executable, but can be loaded at
+     any address without help from a dynamic linker.  All static
+     programs as well as static tests are built as static PIE, except
+     for those marked with no-pie.  The resulting glibc can be used with
+     the GCC option, -static-pie, which is available with GCC 8 or
+     above, to create static PIE.
+
 '--disable-profile'
      Don't build libraries with profiling information.  You may want to
      use this option if you don't plan to do profiling.
diff --git a/Makeconfig b/Makeconfig
index 1346109..99cc136 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -352,6 +352,14 @@ ifndef static-start-installed-name
 static-start-installed-name = $(start-installed-name)
 endif
 
+ifeq (yes,$(enable-static-pie))
+# Link with rcrt1.o, instead of crt1.o, to call _dl_relocate_static_pie
+# to relocate static PIE.
+real-static-start-installed-name = r$(static-start-installed-name)
+else
+real-static-start-installed-name = $(static-start-installed-name)
+endif
+
 ifeq (yesyes,$(build-shared)$(have-z-combreloc))
 combreloc-LDFLAGS = -Wl,-z,combreloc
 LDFLAGS.so += $(combreloc-LDFLAGS)
@@ -371,6 +379,20 @@ LDFLAGS.so += $(hashstyle-LDFLAGS)
 LDFLAGS-rtld += $(hashstyle-LDFLAGS)
 endif
 
+ifeq (yes,$(enable-static-pie))
+pic-default = -DPIC
+# Compile libc.a and libc_p.a with -fPIE/-fpie for static PIE.
+pie-default = $(pie-ccflag)
+ifeq (yes,$(have-static-pie))
+default-pie-ldflag = -static-pie
+else
+# Static PIE can't have dynamic relocations in read-only segments since
+# static PIE is mapped into memory by kernel.  --eh-frame-hdr is needed
+# for PIE to support exception.
+default-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text
+endif
+endif
+
 # If lazy relocations are disabled, add the -z now flag.  Use
 # LDFLAGS-lib.so instead of LDFLAGS.so, to avoid adding the flag to
 # test modules.
@@ -420,9 +442,9 @@ endif
 # Command for statically linking programs with the C library.
 ifndef +link-static
 +link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \
-	      $(DEFAULT-LDFLAGS-$(@F)) \
+	      $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)) \
 	      $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F))  \
-	      $(firstword $(CRT-$(@F)) $(csu-objpfx)$(static-start-installed-name)) \
+	      $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \
 	      $(+preinit) $(+prectorT) \
 	      $(filter-out $(addprefix $(csu-objpfx),start.o \
 						     $(start-installed-name))\
@@ -637,8 +659,14 @@ endif
 +prectorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginS.o`
 +postctorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtendS.o`
 # Variants of the two previous definitions for statically linking programs.
+ifeq (yes,$(enable-static-pie))
+# Static PIE must use PIE variants.
++prectorT = $(+prectorS)
++postctorT = $(+postctorS)
+else
 +prectorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginT.o`
 +postctorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o`
+endif
 csu-objpfx = $(common-objpfx)csu/
 elf-objpfx = $(common-objpfx)elf/
 
@@ -959,7 +987,8 @@ libtypes = $(foreach o,$(object-suffixes-for-libc),$(libtype$o))
 all-object-suffixes := .o .os .oS
 object-suffixes :=
 CPPFLAGS-.o = $(pic-default)
-CFLAGS-.o = $(filter %frame-pointer,$(+cflags))
+# libc.a must be compiled with -fPIE/-fpie for static PIE.
+CFLAGS-.o = $(filter %frame-pointer,$(+cflags)) $(pie-default)
 libtype.o := lib%.a
 object-suffixes += .o
 ifeq (yes,$(build-shared))
@@ -984,7 +1013,8 @@ ifeq (yes,$(build-profile))
 all-object-suffixes += .op
 object-suffixes += .op
 CPPFLAGS-.op = -DPROF $(pic-default)
-CFLAGS-.op = -pg
+# libc_p.a must be compiled with -fPIE/-fpie for static PIE.
+CFLAGS-.op = -pg $(pie-default)
 libtype.op = lib%_p.a
 endif
 
diff --git a/NEWS b/NEWS
index c5607c8..61fed65 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,15 @@ Version 2.27
 
 Major new features:
 
+* The GNU C Library can now be compiled with support for building static
+  PIE executables (See --enable-static-pie in INSTALL).  These static PIE
+  exectuables are like static executables but can be loaded at any address
+  and provide additional security hardening benefits at the cost of some
+  memory and performance.  When the library is built with --enable-static-pie
+  the resulting libc.a is usable with GCC 8 and above to create static PIE
+  executables using the GCC option '-static-pie'.  This feature is currently
+  supported on i386, x86_64 and x32.
+
 * Optimized x86-64 asin, atan2, exp, expf, log, pow, atan, sin, cosf,
   sinf and tan with FMA, contributed by Arjan van de Ven and H.J. Lu
   from Intel.
diff --git a/config.h.in b/config.h.in
index 3c91d59..d928e7d 100644
--- a/config.h.in
+++ b/config.h.in
@@ -238,6 +238,9 @@
 /* Build glibc with tunables support.  */
 #define HAVE_TUNABLES 0
 
+/* Define if static PIE is enabled.  */
+#define ENABLE_STATIC_PIE 0
+
 /* Some compiler options may now allow to use ebp in __asm__ (used mainly
    in i386 6 argument syscall issue).  */
 #define CAN_USE_REGISTER_ASM_EBP 0
diff --git a/configure b/configure
index 4a85706..9da9fb2 100755
--- a/configure
+++ b/configure
@@ -763,6 +763,7 @@ with_default_link
 enable_sanity_checks
 enable_shared
 enable_profile
+enable_static_pie
 enable_timezone_tools
 enable_hardcoded_path_in_tests
 enable_stackguard_randomization
@@ -1417,6 +1418,8 @@ Optional Features:
                           in special situations) [default=yes]
   --enable-shared         build shared library [default=yes if GNU ld]
   --enable-profile        build profiled library [default=no]
+  --enable-static-pie     enable static PIE support and use it in the
+                          testsuite [default=no]
   --disable-timezone-tools
                           do not install timezone tools [default=install]
   --enable-hardcoded-path-in-tests
@@ -3350,6 +3353,13 @@ else
   profile=no
 fi
 
+# Check whether --enable-static-pie was given.
+if test "${enable_static_pie+set}" = set; then :
+  enableval=$enable_static_pie; static_pie=$enableval
+else
+  static_pie=no
+fi
+
 # Check whether --enable-timezone-tools was given.
 if test "${enable_timezone_tools+set}" = set; then :
   enableval=$enable_timezone_tools; enable_timezone_tools=$enableval
@@ -5806,6 +5816,62 @@ fi
 $as_echo "$libc_linker_feature" >&6; }
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports --no-dynamic-linker" >&5
+$as_echo_n "checking for linker that supports --no-dynamic-linker... " >&6; }
+libc_linker_feature=no
+if test x"$gnu_ld" = x"yes"; then
+  libc_linker_check=`$LD -v --help 2>/dev/null | grep "\--no-dynamic-linker"`
+  if test -n "$libc_linker_check"; then
+    cat > conftest.c <<EOF
+int _start (void) { return 42; }
+EOF
+    if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
+				-Wl,--no-dynamic-linker -nostdlib -nostartfiles
+				-fPIC -shared -o conftest.so conftest.c
+				1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+      libc_linker_feature=yes
+    fi
+    rm -f conftest*
+  fi
+fi
+if test $libc_linker_feature = yes; then
+  libc_cv_no_dynamic_linker=yes
+else
+  libc_cv_no_dynamic_linker=no
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5
+$as_echo "$libc_linker_feature" >&6; }
+config_vars="$config_vars
+have-no-dynamic-linker = $libc_cv_no_dynamic_linker"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -static-pie" >&5
+$as_echo_n "checking for -static-pie... " >&6; }
+if ${libc_cv_static_pie+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if { ac_try='${CC-cc} -static-pie -xc /dev/null -S -o /dev/null'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  libc_cv_static_pie=yes
+else
+  libc_cv_static_pie=no
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie" >&5
+$as_echo "$libc_cv_static_pie" >&6; }
+config_vars="$config_vars
+have-static-pie = $libc_cv_static_pie"
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fpie" >&5
 $as_echo_n "checking for -fpie... " >&6; }
 if ${libc_cv_fpie+:} false; then :
@@ -6705,6 +6771,19 @@ $as_echo "$libc_cv_pie_default" >&6; }
 libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
 
 
+if test "$static_pie" = yes; then
+  # The linker must support --no-dynamic-linker.
+  if test "$libc_cv_no_dynamic_linker" != yes; then
+    as_fn_error $? "linker support for --no-dynamic-linker needed" "$LINENO" 5
+  fi
+  # Default to PIE.
+  libc_cv_pie_default=yes
+  $as_echo "#define ENABLE_STATIC_PIE 1" >>confdefs.h
+
+fi
+config_vars="$config_vars
+enable-static-pie = $static_pie"
+
 
 
 
diff --git a/configure.ac b/configure.ac
index edf6627..8e4006f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -170,6 +170,11 @@ AC_ARG_ENABLE([profile],
 			     [build profiled library @<:@default=no@:>@]),
 	      [profile=$enableval],
 	      [profile=no])
+AC_ARG_ENABLE([static-pie],
+	      AC_HELP_STRING([--enable-static-pie],
+			     [enable static PIE support and use it in the testsuite @<:@default=no@:>@]),
+	      [static_pie=$enableval],
+	      [static_pie=no])
 AC_ARG_ENABLE([timezone-tools],
 	      AC_HELP_STRING([--disable-timezone-tools],
 			     [do not install timezone tools @<:@default=install@:>@]),
@@ -1287,6 +1292,19 @@ LIBC_LINKER_FEATURE([-z execstack], [-Wl,-z,execstack],
 		    [libc_cv_z_execstack=yes], [libc_cv_z_execstack=no])
 AC_SUBST(libc_cv_z_execstack)
 
+LIBC_LINKER_FEATURE([--no-dynamic-linker],
+		    [-Wl,--no-dynamic-linker],
+		    [libc_cv_no_dynamic_linker=yes],
+		    [libc_cv_no_dynamic_linker=no])
+LIBC_CONFIG_VAR([have-no-dynamic-linker], [$libc_cv_no_dynamic_linker])
+
+AC_CACHE_CHECK(for -static-pie, libc_cv_static_pie, [dnl
+LIBC_TRY_CC_OPTION([-static-pie],
+		   [libc_cv_static_pie=yes],
+		   [libc_cv_static_pie=no])
+])
+LIBC_CONFIG_VAR([have-static-pie], [$libc_cv_static_pie])
+
 AC_CACHE_CHECK(for -fpie, libc_cv_fpie, [dnl
 LIBC_TRY_CC_OPTION([-fpie], [libc_cv_fpie=yes], [libc_cv_fpie=no])
 ])
@@ -1794,6 +1812,17 @@ AC_SUBST(libc_cv_pie_default)
 libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
 AC_SUBST(libc_cv_multidir)
 
+if test "$static_pie" = yes; then
+  # The linker must support --no-dynamic-linker.
+  if test "$libc_cv_no_dynamic_linker" != yes; then
+    AC_MSG_ERROR([linker support for --no-dynamic-linker needed])
+  fi
+  # Default to PIE.
+  libc_cv_pie_default=yes
+  AC_DEFINE(ENABLE_STATIC_PIE)
+fi
+LIBC_CONFIG_VAR([enable-static-pie], [$static_pie])
+
 AC_SUBST(profile)
 AC_SUBST(static_nss)
 
diff --git a/csu/Makefile b/csu/Makefile
index e42a32b..86b95a9 100644
--- a/csu/Makefile
+++ b/csu/Makefile
@@ -37,7 +37,9 @@ extra-objs = start.o \
 	     S$(start-installed-name)
 omit-deps = $(patsubst %.o,%,$(start-installed-name) g$(start-installed-name) \
 			     b$(start-installed-name) $(csu-dummies) \
-			     S$(start-installed-name))
+			     S$(start-installed-name) \
+			     r$(start-installed-name) \
+			     gr$(start-installed-name))
 install-lib = $(start-installed-name) g$(start-installed-name) $(csu-dummies)
 
 # No tests are allowed in the csu/ subdirectory because the startup
@@ -60,10 +62,17 @@ extra-objs += gmon-start.o
 endif
 
 ifneq ($(start-installed-name),$(static-start-installed-name))
+# FIXME: Only Hurd defines static-start-installed-name.  Hurd needs to
+# provide special rules to support static PIE.
 extra-objs += $(static-start-installed-name) g$(static-start-installed-name)
 omit-deps += $(patsubst %.o,%,$(static-start-installed-name) \
 			     g$(static-start-installed-name))
 install-lib += $(static-start-installed-name) g$(static-start-installed-name)
+else
+ifeq (yes,$(enable-static-pie))
+extra-objs += r$(start-installed-name) gr$(start-installed-name)
+install-lib += r$(start-installed-name) gr$(start-installed-name)
+endif
 endif
 
 before-compile += $(objpfx)abi-tag.h
@@ -82,7 +91,10 @@ multilib-extra-objs = $(addprefix $(multidir)/, $(install-lib))
 extra-objs += $(multilib-extra-objs)
 endif
 
-extra-objs += abi-note.o init.o
+extra-objs += abi-note.o init.o static-reloc.o
+ifeq (yes,$(build-shared))
+extra-objs += static-reloc.os
+endif
 asm-CPPFLAGS += -I$(objpfx).
 
 # Enable unwinding so backtrace unwinds to __libc_start_main
@@ -101,6 +113,9 @@ ifndef start-installed-name-rule
 # We link the ELF startfile along with a SHT_NOTE section indicating
 # the kernel ABI the binaries linked with this library will require.
 $(objpfx)$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o \
+				  $(objpfx)init.o $(objpfx)static-reloc.o
+	$(link-relocatable)
+$(objpfx)r$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o \
 				  $(objpfx)init.o
 	$(link-relocatable)
 $(objpfx)S$(start-installed-name): $(objpfx)start.os $(objpfx)abi-note.o \
@@ -113,7 +128,10 @@ endif
 # to turn on profiling code at startup.
 ifeq (yes,$(build-shared))
 $(objpfx)g$(start-installed-name): \
-  $(objpfx)g%: $(objpfx)S% $(objpfx)gmon-start.os
+  $(objpfx)g%: $(objpfx)S% $(objpfx)gmon-start.os $(objpfx)static-reloc.os
+	$(link-relocatable)
+$(objpfx)gr$(start-installed-name): \
+  $(objpfx)gr%: $(objpfx)r% $(objpfx)gmon-start.o
 	$(link-relocatable)
 ifneq ($(start-installed-name),$(static-start-installed-name))
 $(objpfx)g$(static-start-installed-name): \
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 24c63be..34dd125 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -141,6 +141,8 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
   __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up;
 
 #ifndef SHARED
+  _dl_relocate_static_pie ();
+
   char **ev = &argv[argc + 1];
 
   __environ = ev;
diff --git a/csu/libc-tls.c b/csu/libc-tls.c
index 00138eb..1f8ddaf 100644
--- a/csu/libc-tls.c
+++ b/csu/libc-tls.c
@@ -114,6 +114,8 @@ __libc_setup_tls (void)
   size_t tcb_offset;
   const ElfW(Phdr) *phdr;
 
+  struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+
   /* Look through the TLS segment if there is any.  */
   if (_dl_phdr != NULL)
     for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr)
@@ -122,7 +124,7 @@ __libc_setup_tls (void)
 	  /* Remember the values we need.  */
 	  memsz = phdr->p_memsz;
 	  filesz = phdr->p_filesz;
-	  initimage = (void *) phdr->p_vaddr;
+	  initimage = (void *) phdr->p_vaddr + main_map->l_addr;
 	  align = phdr->p_align;
 	  if (phdr->p_align > max_align)
 	    max_align = phdr->p_align;
@@ -163,8 +165,6 @@ __libc_setup_tls (void)
   _dl_static_dtv[0].counter = (sizeof (_dl_static_dtv) / sizeof (_dl_static_dtv[0])) - 2;
   // _dl_static_dtv[1].counter = 0;		would be needed if not already done
 
-  struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
-
   /* Initialize the TLS block.  */
 #if TLS_TCB_AT_TP
   _dl_static_dtv[2].pointer.val = ((char *) tlsblock + tcb_offset
diff --git a/csu/static-reloc.c b/csu/static-reloc.c
new file mode 100644
index 0000000..37be72c
--- /dev/null
+++ b/csu/static-reloc.c
@@ -0,0 +1,26 @@
+/* Special startup support for non-PIE static executables.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#if ENABLE_STATIC_PIE
+#include <ldsodefs.h>
+
+void
+_dl_relocate_static_pie (void)
+{
+}
+#endif
diff --git a/elf/Makefile b/elf/Makefile
index 8563555..47c3d23 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -24,7 +24,8 @@ include ../Makeconfig
 headers		= elf.h bits/elfclass.h link.h bits/link.h
 routines	= $(all-dl-routines) dl-support dl-iteratephdr \
 		  dl-addr dl-addr-obj enbl-secure dl-profstub \
-		  dl-origin dl-libc dl-sym dl-sysdep dl-error
+		  dl-origin dl-libc dl-sym dl-sysdep dl-error \
+		  dl-reloc-static-pie
 
 # The core dynamic linking functions are in libc for the static and
 # profiled libraries.
@@ -52,7 +53,7 @@ endif
 all-dl-routines = $(dl-routines) $(sysdep-dl-routines)
 # But they are absent from the shared libc, because that code is in ld.so.
 elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \
-		    dl-sysdep dl-exception
+		    dl-sysdep dl-exception dl-reloc-static-pie
 shared-only-routines += dl-caller
 
 # ld.so uses those routines, plus some special stuff for being the program
@@ -153,7 +154,7 @@ tests-static-internal := tst-tls1-static tst-tls2-static \
 	       tst-tls1-static-non-pie
 
 CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o
-DEFAULT-LDFLAGS-tst-tls1-static-non-pie = $(no-pie-ldflag)
+tst-tls1-static-non-pie-no-pie = yes
 
 tests := tst-tls9 tst-leaks1 \
 	tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \
diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
new file mode 100644
index 0000000..6e43aea
--- /dev/null
+++ b/elf/dl-reloc-static-pie.c
@@ -0,0 +1,52 @@
+/* Support for relocating static PIE.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#if ENABLE_STATIC_PIE
+#include <unistd.h>
+#include <ldsodefs.h>
+#include "dynamic-link.h"
+
+/* Relocate static executable with PIE.  */
+
+void
+_dl_relocate_static_pie (void)
+{
+  struct link_map *main_map = _dl_get_dl_main_map ();
+
+# define STATIC_PIE_BOOTSTRAP
+# define BOOTSTRAP_MAP (main_map)
+# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
+# include "dynamic-link.h"
+
+  /* Figure out the run-time load address of static PIE.  */
+  main_map->l_addr = elf_machine_load_address ();
+
+  /* Read our own dynamic section and fill in the info array.  */
+  main_map->l_ld = ((void *) main_map->l_addr + elf_machine_dynamic ());
+  elf_get_dynamic_info (main_map, NULL);
+
+# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
+  ELF_MACHINE_BEFORE_RTLD_RELOC (main_map->l_info);
+# endif
+
+  /* Relocate ourselves so we can do normal function calls and
+     data access using the global offset table.  */
+  ELF_DYNAMIC_RELOCATE (main_map, 0, 0, 0);
+  main_map->l_relocated = 1;
+}
+#endif
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 235d3a7..b9fc1a6 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -385,3 +385,14 @@ _dl_non_dynamic_init (void)
 #ifdef DL_SYSINFO_IMPLEMENTATION
 DL_SYSINFO_IMPLEMENTATION
 #endif
+
+#if ENABLE_STATIC_PIE
+/* Since relocation to hidden _dl_main_map causes relocation overflow on
+   aarch64, a function is used to get the address of _dl_main_map.  */
+
+struct link_map *
+_dl_get_dl_main_map (void)
+{
+  return &_dl_main_map;
+}
+#endif
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index ebea756..6278649 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -94,7 +94,7 @@ elf_machine_lazy_rel (struct link_map *map,
 
 #ifdef RESOLVE_MAP
 
-# ifdef RTLD_BOOTSTRAP
+# if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
 #  define ELF_DURING_STARTUP (1)
 # else
 #  define ELF_DURING_STARTUP (0)
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index 7525c3a..eb26d23 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -38,7 +38,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
   typedef Elf64_Xword d_tag_utype;
 #endif
 
-#ifndef RTLD_BOOTSTRAP
+#if !defined RTLD_BOOTSTRAP && !defined STATIC_PIE_BOOTSTRAP
   if (dyn == NULL)
     return;
 #endif
@@ -139,9 +139,11 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
   /* Only the bind now flags are allowed.  */
   assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
 	  || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
+  /* Flags must not be set for ld.so.  */
   assert (info[DT_FLAGS] == NULL
 	  || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
-  /* Flags must not be set for ld.so.  */
+#endif
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
   assert (info[DT_RUNPATH] == NULL);
   assert (info[DT_RPATH] == NULL);
 #else
diff --git a/gmon/Makefile b/gmon/Makefile
index 89ab3fc..29e7467 100644
--- a/gmon/Makefile
+++ b/gmon/Makefile
@@ -39,6 +39,10 @@ tests-static += tst-gmon-static
 ifeq (yesyes,$(have-fpie)$(build-shared))
 tests += tst-gmon-pie
 tests-pie += tst-gmon-pie
+ifeq (yes,$(enable-static-pie))
+tests += tst-gmon-static-pie
+tests-static += tst-gmon-static-pie
+endif
 endif
 
 # The mcount code won't work without a frame pointer.
@@ -54,7 +58,7 @@ endif
 
 CFLAGS-tst-gmon-static.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg
 CRT-tst-gmon-static := $(csu-objpfx)gcrt1.o
-DEFAULT-LDFLAGS-tst-gmon-static = $(no-pie-ldflag)
+tst-gmon-static-no-pie = yes
 tst-gmon-static-ENV := GMON_OUT_PREFIX=$(objpfx)tst-gmon-static.data
 ifeq ($(run-built-tests),yes)
 tests-special += $(objpfx)tst-gmon-static-gprof.out
@@ -67,6 +71,15 @@ ifeq ($(run-built-tests),yes)
 tests-special += $(objpfx)tst-gmon-pie-gprof.out
 endif
 
+ifeq (yes,$(enable-static-pie))
+CFLAGS-tst-gmon-static-pie.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg
+CRT-tst-gmon-static-pie := $(csu-objpfx)grcrt1.o
+tst-gmon-static-pie-ENV := GMON_OUT_PREFIX=$(objpfx)tst-gmon-static-pie.data
+ifeq ($(run-built-tests),yes)
+tests-special += $(objpfx)tst-gmon-static-pie-gprof.out
+endif
+endif
+
 
 include ../Rules
 
@@ -111,3 +124,13 @@ clean-tst-gmon-pie-data:
 $(objpfx)tst-gmon-pie-gprof.out: tst-gmon-gprof.sh $(objpfx)tst-gmon-pie.out
 	$(SHELL) $< $(GPROF) $(objpfx)tst-gmon-pie $(objpfx)tst-gmon-pie.data.* > $@; \
 	$(evaluate-test)
+
+$(objpfx)tst-gmon-static-pie.out: clean-tst-gmon-static-pie-data
+clean-tst-gmon-static-pie-data:
+	rm -f $(objpfx)tst-gmon-static-pie.data.*
+
+$(objpfx)tst-gmon-static-pie-gprof.out: tst-gmon-static-gprof.sh \
+					$(objpfx)tst-gmon-static-pie.out
+	$(SHELL) $< $(GPROF) $(objpfx)tst-gmon-static-pie \
+		$(objpfx)tst-gmon-static-pie.data.* > $@; \
+	$(evaluate-test)
diff --git a/gmon/tst-gmon-static-pie.c b/gmon/tst-gmon-static-pie.c
new file mode 100644
index 0000000..1eef258
--- /dev/null
+++ b/gmon/tst-gmon-static-pie.c
@@ -0,0 +1 @@
+#include "tst-gmon.c"
diff --git a/manual/install.texi b/manual/install.texi
index e81f1c5..fb956b5 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -116,6 +116,15 @@ Don't build shared libraries even if it is possible.  Not all systems
 support shared libraries; you need ELF support and (currently) the GNU
 linker.
 
+@item --enable-static-pie
+Enable static position independent executable (static PIE) support.
+Static PIE is similar to static executable, but can be loaded at any
+address without help from a dynamic linker.  All static programs as
+well as static tests are built as static PIE, except for those marked
+with no-pie.  The resulting glibc can be used with the GCC option,
+-static-pie, which is available with GCC 8 or above, to create static
+PIE.
+
 @item --disable-profile
 Don't build libraries with profiling information.  You may want to use
 this option if you don't plan to do profiling.
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 7a65dc6..1965138 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1051,6 +1051,17 @@ extern void _dl_determine_tlsoffset (void) attribute_hidden;
    stack protector, among other things).  */
 void __libc_setup_tls (void);
 
+# if ENABLE_STATIC_PIE
+/* Relocate static executable with PIE.  */
+extern void _dl_relocate_static_pie (void) attribute_hidden;
+
+/* Get a pointer to _dl_main_map.  */
+extern struct link_map * _dl_get_dl_main_map (void)
+  __attribute__ ((visibility ("hidden")));
+# else
+#  define _dl_relocate_static_pie()
+# endif
+
 /* Initialization of libpthread for statically linked applications.
    If libpthread is not linked in, this is an empty function.  */
 void __pthread_initialize_minimal (void) weak_function;
diff --git a/sysdeps/i386/configure b/sysdeps/i386/configure
index 4cf968d..90c63ca 100644
--- a/sysdeps/i386/configure
+++ b/sysdeps/i386/configure
@@ -50,6 +50,39 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_compiler_builtin_inlined" >&5
 $as_echo "$libc_compiler_builtin_inlined" >&6; }
 
+if test "$static_pie" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker static PIE support" >&5
+$as_echo_n "checking for linker static PIE support... " >&6; }
+if ${libc_cv_ld_static_pie+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.s <<\EOF
+	.text
+	.global _start
+_start:
+	movl	_start@GOT(%ebx), %eax
+EOF
+  libc_cv_pie_option="-Wl,-pie"
+  libc_cv_ld_static_pie=no
+  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    if $READELF -r conftest | grep 'There are no relocations in this file.' > /dev/null; then
+      libc_cv_ld_static_pie=yes
+    fi
+  fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ld_static_pie" >&5
+$as_echo "$libc_cv_ld_static_pie" >&6; }
+  if test "$libc_cv_ld_static_pie" != yes; then
+    as_fn_error $? "linker support for static PIE needed" "$LINENO" 5
+  fi
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Intel MPX support" >&5
 $as_echo_n "checking for Intel MPX support... " >&6; }
 if ${libc_cv_asm_mpx+:} false; then :
diff --git a/sysdeps/i386/configure.ac b/sysdeps/i386/configure.ac
index b598b12..6d2068d 100644
--- a/sysdeps/i386/configure.ac
+++ b/sysdeps/i386/configure.ac
@@ -30,6 +30,29 @@ LIBC_COMPILER_BUILTIN_INLINED(
 *** Please use host i786, i686, i586, or i486.
 *** For example: /source/glibc/configure CFLAGS='-O2 -march=i686' ...])])
 
+dnl Check if linker can convert "movl main@GOT(%ebx), %eax" to
+dnl "leal main@GOTOFF(%ebx), %eax" for static PIE.
+if test "$static_pie" = yes; then
+  AC_CACHE_CHECK(for linker static PIE support, libc_cv_ld_static_pie, [dnl
+cat > conftest.s <<\EOF
+	.text
+	.global _start
+_start:
+	movl	_start@GOT(%ebx), %eax
+EOF
+  libc_cv_pie_option="-Wl,-pie"
+  libc_cv_ld_static_pie=no
+  if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 1>&AS_MESSAGE_LOG_FD); then
+    if $READELF -r conftest | grep 'There are no relocations in this file.' > /dev/null; then
+      libc_cv_ld_static_pie=yes
+    fi
+  fi
+rm -f conftest*])
+  if test "$libc_cv_ld_static_pie" != yes; then
+    AC_MSG_ERROR([linker support for static PIE needed])
+  fi
+fi
+
 dnl Check whether asm supports Intel MPX
 AC_CACHE_CHECK(for Intel MPX support, libc_cv_asm_mpx, [dnl
 cat > conftest.s <<\EOF
diff --git a/sysdeps/mips/Makefile b/sysdeps/mips/Makefile
index fd891dd..7ac6fa5 100644
--- a/sysdeps/mips/Makefile
+++ b/sysdeps/mips/Makefile
@@ -23,6 +23,9 @@ CPPFLAGS-crtn.S += $(pic-ccflag)
 endif
 
 ASFLAGS-.os += $(pic-ccflag)
+# libc.a and libc_p.a must be compiled with -fPIE/-fpie for static PIE.
+ASFLAGS-.o += $(pie-default)
+ASFLAGS-.op += $(pie-default)
 
 ifeq ($(subdir),elf)
 ifneq ($(o32-fpabi),)
diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure
index efef46b..8674d14 100644
--- a/sysdeps/x86_64/configure
+++ b/sysdeps/x86_64/configure
@@ -85,6 +85,39 @@ if test x"$build_mathvec" = xnotset; then
   build_mathvec=yes
 fi
 
+if test "$static_pie" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker static PIE support" >&5
+$as_echo_n "checking for linker static PIE support... " >&6; }
+if ${libc_cv_ld_static_pie+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.s <<\EOF
+	.text
+	.global _start
+	.weak foo
+_start:
+	leaq	foo(%rip), %rax
+EOF
+  libc_cv_pie_option="-Wl,-pie"
+  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    libc_cv_ld_static_pie=yes
+  else
+    libc_cv_ld_static_pie=no
+  fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ld_static_pie" >&5
+$as_echo "$libc_cv_ld_static_pie" >&6; }
+  if test "$libc_cv_ld_static_pie" != yes; then
+    as_fn_error $? "linker support for static PIE needed" "$LINENO" 5
+  fi
+fi
+
 $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
 
 
diff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac
index fa86e95..b7d2c01 100644
--- a/sysdeps/x86_64/configure.ac
+++ b/sysdeps/x86_64/configure.ac
@@ -44,6 +44,31 @@ if test x"$build_mathvec" = xnotset; then
   build_mathvec=yes
 fi
 
+dnl Check if linker supports static PIE with the fix for
+dnl
+dnl https://sourceware.org/bugzilla/show_bug.cgi?id=21782
+dnl
+if test "$static_pie" = yes; then
+  AC_CACHE_CHECK(for linker static PIE support, libc_cv_ld_static_pie, [dnl
+cat > conftest.s <<\EOF
+	.text
+	.global _start
+	.weak foo
+_start:
+	leaq	foo(%rip), %rax
+EOF
+  libc_cv_pie_option="-Wl,-pie"
+  if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 1>&AS_MESSAGE_LOG_FD); then
+    libc_cv_ld_static_pie=yes
+  else
+    libc_cv_ld_static_pie=no
+  fi
+rm -f conftest*])
+  if test "$libc_cv_ld_static_pie" != yes; then
+    AC_MSG_ERROR([linker support for static PIE needed])
+  fi
+fi
+
 dnl It is always possible to access static and hidden symbols in an
 dnl position independent way.
 AC_DEFINE(PI_STATIC_AND_HIDDEN)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8116d0e4a14422efda45fd5292db1a58b3ce6f98

commit 8116d0e4a14422efda45fd5292db1a58b3ce6f98
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date:   Fri Nov 24 07:13:10 2017 -0800

    aarch64: fix start code for static pie
    
    with upcoming static pie patches there are three flavors of the crt startup code:
    
    1) crt1.o used for non-pie static linking (executable has no relocs),
    2) Scrt1.o used for dynamic linking (dynamic linker relocates),
    3) rcrt1.o used for static pie linking (self relocation is needed)
    
    when crt1.o and rcrt1.o is built in the --enable-static-pie case -DPIC is passed,
    when Scrt1.o is built then -DPIC -DSHARED is passed.
    
    (crt1.o gets a dummy _dl_relocate_static_pie that interposes the one in
    libc so no self-relocation is done in that case in __libc_start_main)
    
    the Scrt1.o code is position independent but it relies on GOT entries that
    need to be relocated which happens later and the static linker cannot relax
    the GOT loads, so rcrt1.o needs separate implementation.
    
    This implementation works with .text <= 4G files, which is fine, currently
    the toolchain does not support larger position independent executables.
    
    tests pass with ld/22269 and ld/22263 binutils bugs fixed.
    this patch is on top of master but assumes the static pie patches.
    
    	* sysdeps/aarch64/start.S (_start): Handle PIC && !SHARED case.

diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S
index c20433a..cd7ba7d 100644
--- a/sysdeps/aarch64/start.S
+++ b/sysdeps/aarch64/start.S
@@ -60,7 +60,8 @@ _start:
 	/* Setup stack limit in argument register */
 	mov	x6, sp
 
-#ifdef SHARED
+#ifdef PIC
+# ifdef SHARED
         adrp    x0, :got:main
 	ldr     PTR_REG (0), [x0, #:got_lo12:main]
 
@@ -69,6 +70,15 @@ _start:
 
         adrp    x4, :got:__libc_csu_fini
 	ldr     PTR_REG (4), [x4, #:got_lo12:__libc_csu_fini]
+
+# else
+	adrp	x0, main
+	add	x0, x0, :lo12:main
+	adrp	x3, __libc_csu_init
+	add	x3, x3, :lo12:__libc_csu_init
+	adrp	x4, __libc_csu_fini
+	add	x4, x4, :lo12:__libc_csu_fini
+# endif
 #else
 	/* Set up the other arguments in registers */
 	MOVL (0, main)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=adda173d26aad05529a82ff9997584e5541ae42e

commit adda173d26aad05529a82ff9997584e5541ae42e
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Dec 1 09:49:25 2017 -0800

    nios2: Don't use MIN in dl-machine.h
    
    MIN is used, but param.h may not be included, so expand its single use
    inline.
    
    	* sysdeps/nios2/dl-machine.h (elf_machine_rela): Expand MIN.

diff --git a/sysdeps/nios2/dl-machine.h b/sysdeps/nios2/dl-machine.h
index b5fdd9b..67d8c89 100644
--- a/sysdeps/nios2/dl-machine.h
+++ b/sysdeps/nios2/dl-machine.h
@@ -271,7 +271,8 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
 				strtab + refsym->st_name);
             }
           memcpy (reloc_addr_arg, (void *) value,
-                  MIN (sym->st_size, refsym->st_size));
+		  sym->st_size < refsym->st_size
+		  ? sym->st_size : refsym->st_size);
           break;
 	case R_NIOS2_GLOB_DAT:
 	case R_NIOS2_JUMP_SLOT:

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]