This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch hjl/pie/static created. glibc-2.26-416-g0a410bf
- From: hjl at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 28 Sep 2017 12:20:41 -0000
- Subject: GNU C Library master sources branch hjl/pie/static created. glibc-2.26-416-g0a410bf
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 0a410bf70424964a0e7888b32800160b02873842 (commit)
- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=0a410bf70424964a0e7888b32800160b02873842
commit 0a410bf70424964a0e7888b32800160b02873842
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 8ce1c6f..013c96d 100755
--- a/scripts/build-many-glibcs.py
+++ b/scripts/build-many-glibcs.py
@@ -1343,6 +1343,7 @@ class Glibc(object):
cfg_cmd = [os.path.join(srcdir_copy, 'configure'),
'--prefix=/usr',
'--enable-add-ons',
+ '--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=c90d917f22948a6f172bb88ddd9899a20315034f
commit c90d917f22948a6f172bb88ddd9899a20315034f
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Thu Sep 28 05:11:03 2017 -0700
Add a test for non-PIE static executable
tst-tls1-static-non-pie is built with $(no-pie-ldflag) to make it a
non-PIE static executable, regardless if --enable-static-pie is used
to configure glibc.
* elf/Makefile (tests-static-internal): Add
tst-tls1-static-non-pie.
(LDFLAGS-tst-tls1-static-non-pie): New.
* elf/tst-tls1-static-non-pie.c: New file.
diff --git a/elf/Makefile b/elf/Makefile
index e21f37e..c6edebd 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -149,7 +149,10 @@ tests-static-normal := tst-leaks1-static tst-array1-static tst-array5-static \
tst-tlsalign-static tst-tlsalign-extern-static \
tst-linkall-static tst-env-setuid tst-env-setuid-tunables
tests-static-internal := tst-tls1-static tst-tls2-static \
- tst-ptrguard1-static tst-stackguard1-static
+ tst-ptrguard1-static tst-stackguard1-static \
+ tst-tls1-static-non-pie
+
+LDFLAGS-tst-tls1-static-non-pie = $(no-pie-ldflag)
tests := tst-tls9 tst-leaks1 \
tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \
diff --git a/elf/tst-tls1-static-non-pie.c b/elf/tst-tls1-static-non-pie.c
new file mode 100644
index 0000000..a010080
--- /dev/null
+++ b/elf/tst-tls1-static-non-pie.c
@@ -0,0 +1 @@
+#include "tst-tls1.c"
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=50c4168ff212adb93982626bda198051f8dbbdee
commit 50c4168ff212adb93982626bda198051f8dbbdee
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Thu Sep 28 05:04:35 2017 -0700
x86: Allow undefined _DYNAMIC in static executable
When --enable-static-pie is used to build static PIE, _DYNAMIC is used
to compute the load address of static PIE. But _DYNAMIC is undefined
when creating static executable. This patch makes _DYNAMIC weak in PIE
libc.a so that it can be undefined.
* sysdeps/i386/dl-machine.h (elf_machine_load_address): Allow
undefined _DYNAMIC in PIE libc.a.
* sysdeps/x86_64/dl-machine.h (elf_machine_load_address):
Likewse.
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index 2e17eba..0a5c833 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -54,8 +54,21 @@ elf_machine_load_address (void)
/* Compute the difference between the runtime address of _DYNAMIC as seen
by a GOTOFF reference, and the link-time address found in the special
unrelocated first GOT entry. */
- extern Elf32_Dyn bygotoff[] asm ("_DYNAMIC") attribute_hidden;
- return (Elf32_Addr) &bygotoff - elf_machine_dynamic ();
+#ifdef SHARED
+ extern Elf32_Dyn _DYNAMIC[] attribute_hidden;
+ return (Elf32_Addr) &_DYNAMIC - elf_machine_dynamic ();
+#else
+ extern Elf32_Dyn _DYNAMIC[] __attribute__((weak, visibility ("hidden")));
+ if (_DYNAMIC)
+ {
+ /* The address of dynamic must be taken as non-weak to avoid
+ dynamic relocation. */
+ extern Elf32_Dyn dynamic[] asm ("_DYNAMIC") attribute_hidden;
+ return (Elf32_Addr) &dynamic - elf_machine_dynamic ();
+ }
+ else
+ return 0;
+#endif
}
/* Set up the loaded object described by L so its unrelocated PLT
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index 6a04cbc..4114c79 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -55,8 +55,21 @@ elf_machine_load_address (void)
/* Compute the difference between the runtime address of _DYNAMIC as seen
by an IP-relative reference, and the link-time address found in the
special unrelocated first GOT entry. */
+#ifdef SHARED
extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
return (ElfW(Addr)) &_DYNAMIC - elf_machine_dynamic ();
+#else
+ extern ElfW(Dyn) _DYNAMIC[] __attribute__((weak, visibility ("hidden")));
+ if (_DYNAMIC)
+ {
+ /* The address of dynamic must be taken as non-weak to avoid
+ dynamic relocation. */
+ extern ElfW(Dyn) dynamic[] asm ("_DYNAMIC") attribute_hidden;
+ return (ElfW(Addr)) &dynamic - elf_machine_dynamic ();
+ }
+ else
+ return 0;
+#endif
}
/* Set up the loaded object described by L so its unrelocated PLT
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2f5e8ead960bdf992919297b313b99c5f7949428
commit 2f5e8ead960bdf992919297b313b99c5f7949428
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Tue Aug 22 15:37:10 2017 -0700
Don't use hidden visibility in libc.a with PIE on i386
On i386, when multi-arch is enabled, all external functions must be
called via PIC PLT in PIE, which requires setting up EBX register,
since they may be IFUNC functions.
* config.h.in (NO_HIDDEN_EXTERN_FUNC_IN_PIE): New.
* include/libc-symbols.h (__hidden_proto_hiddenattr): Add check
for PIC and NO_HIDDEN_EXTERN_FUNC_IN_PIE.
* sysdeps/i386/configure.ac (NO_HIDDEN_EXTERN_FUNC_IN_PIE): New
AC_DEFINE if multi-arch is enabled.
* sysdeps/i386/configure: Regenerated.
diff --git a/config.h.in b/config.h.in
index 26ed786..d397eea 100644
--- a/config.h.in
+++ b/config.h.in
@@ -86,6 +86,10 @@
#undef PI_STATIC_AND_HIDDEN
/* Define this to disable the 'hidden_proto' et al macros in
+ include/libc-symbols.h that avoid PLT slots in PIE. */
+#undef NO_HIDDEN_EXTERN_FUNC_IN_PIE
+
+/* Define this to disable the 'hidden_proto' et al macros in
include/libc-symbols.h that avoid PLT slots in the shared objects. */
#undef NO_HIDDEN
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 10fd206..3881a2b 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -507,6 +507,7 @@ for linking")
#else
# ifndef __ASSEMBLER__
# if !defined SHARED && IS_IN (libc) && !defined LIBC_NONSHARED \
+ && (!defined PIC || !defined NO_HIDDEN_EXTERN_FUNC_IN_PIE) \
&& !defined NO_HIDDEN
# define __hidden_proto_hiddenattr(attrs...) \
__attribute__ ((visibility ("hidden"), ##attrs))
diff --git a/sysdeps/i386/configure b/sysdeps/i386/configure
index 4d6685f..4cf968d 100644
--- a/sysdeps/i386/configure
+++ b/sysdeps/i386/configure
@@ -26,7 +26,7 @@ libc_compiler_builtin_inlined=no
cat > conftest.c <<EOF
int _start (void) { int a, b, c; __sync_val_compare_and_swap (&a, b, c); return 0; }
EOF
-if ! { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+if ! { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
-O0 -nostdlib -nostartfiles
-S conftest.c -o - | fgrep "__sync_val_compare_and_swap"
1>&5'
@@ -79,3 +79,8 @@ fi
$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
+
+if test x"$multi_arch" != xno; then
+ $as_echo "#define NO_HIDDEN_EXTERN_FUNC_IN_PIE 1" >>confdefs.h
+
+fi
diff --git a/sysdeps/i386/configure.ac b/sysdeps/i386/configure.ac
index f7766ad..b598b12 100644
--- a/sysdeps/i386/configure.ac
+++ b/sysdeps/i386/configure.ac
@@ -48,3 +48,9 @@ fi
dnl It is always possible to access static and hidden symbols in an
dnl position independent way.
AC_DEFINE(PI_STATIC_AND_HIDDEN)
+
+dnl When multi-arch is enabled, all external functions must be called
+dnl via PIC PLT in PIE, which requires setting up EBX register.
+if test x"$multi_arch" != xno; then
+ AC_DEFINE(NO_HIDDEN_EXTERN_FUNC_IN_PIE)
+fi
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f09a1df2e8d57577daaf8b8cce10da007de26597
commit f09a1df2e8d57577daaf8b8cce10da007de26597
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
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. 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 allowed in static PIE.
Static PIE can work on all architectures which support PIE, provided
1. 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, like
commit 1e8e527dd9718eaebe8417b73befb0c821b7b327
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Fri Aug 4 12:59:35 2017 -0700
i386: Support static PIE in start.S
Since start.o may be compiled as PIC, we should check PIC instead of
SHARED. Also avoid dynamic relocation against main in static PIE since
_start is the entry point before the executable is relocated.
2. elf_machine_dynamic and elf_machine_load_address in dl-machine.h are
updated to support static PIE, similar to x86_64 dl-machine.h:
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
first element of the GOT. This must be inlined in a function which
uses global data. */
static inline ElfW(Addr) __attribute__ ((unused))
elf_machine_dynamic (void)
{
/* This produces an IP-relative reloc which is resolved at link time. */
extern const ElfW(Addr) _GLOBAL_OFFSET_TABLE_[] attribute_hidden;
return _GLOBAL_OFFSET_TABLE_[0];
}
/* Return the run-time load address of the shared object. */
static inline ElfW(Addr) __attribute__ ((unused))
elf_machine_load_address (void)
{
/* Compute the difference between the runtime address of _DYNAMIC as seen
by an IP-relative reference, and the link-time address found in the
special unrelocated first GOT entry. */
#ifdef SHARED
extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
return (ElfW(Addr)) &_DYNAMIC - elf_machine_dynamic ();
#else
extern ElfW(Dyn) _DYNAMIC[] __attribute__((weak, visibility ("hidden")));
if (_DYNAMIC)
{
/* The address of dynamic must be taken as non-weak to avoid
dynamic relocation. */
extern ElfW(Dyn) dynamic[] asm ("_DYNAMIC") attribute_hidden;
return (ElfW(Addr)) &dynamic - elf_machine_dynamic ();
}
else
return 0;
#endif
}
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 wether 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.
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
Binutils 2.29 or above are OK.
Tested on i686 and x86-64.
* INSTALL: Regenerated.
* Makeconfig (pic-default): Updated for --enable-static-pie.
(pie-default): New for --enable-static-pie.
(default-pie-ldflag): Likewise.
(+link-static-before-libc): Add $(default-pie-ldflag).
(+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/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.
* elf/dl-support.c: Include "dynamic-link.h" and don't include
"get-dynamic-info.h" for --enable-static-pie.
(_dl_relocate_static_pie): New function for --enable-static-pie.
(STATIC_PIE_BOOTSTRAP): New for --enable-static-pie.
(RESOLVE_MAP): Likewise.
* elf/dynamic-link.h (ELF_DURING_STARTUP): Also check
STATIC_PIE_BOOTSTRAP.
* elf/get-dynamic-info.h (elf_get_dynamic_info): Likewise.
* manual/install.texi: Document --enable-static-pie.
* sysdeps/generic/ldsodefs.h (_dl_relocate_static_pie): New.
* sysdeps/x86_64/configure.ac: Check if linker supports static PIE.
* sysdeps/x86_64/configure: Regenerated.
diff --git a/INSTALL b/INSTALL
index 4d9024c..862544f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -106,6 +106,13 @@ 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'
+ Build static executables, including tests, as position independent
+ executable (static PIE) which is similar to static executable, but
+ can be loaded at any address without help from a dynamic linker.
+ The resulting libc.a 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 b51904b..b45209f 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -386,6 +386,16 @@ LDFLAGS.so += $(hashstyle-LDFLAGS)
LDFLAGS-rtld += $(hashstyle-LDFLAGS)
endif
+ifeq (yes,$(enable-static-pie))
+pic-default = -DPIC
+pie-default = $(pie-ccflag)
+ifeq (yes,$(have-static-pie))
+default-pie-ldflag = -static-pie
+else
+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.
@@ -435,6 +445,7 @@ endif
# Command for statically linking programs with the C library.
ifndef +link-static
+link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \
+ $(default-pie-ldflag) \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
$(addprefix $(csu-objpfx),$(static-start-installed-name)) \
$(+preinit) $(+prectorT) \
@@ -651,8 +662,13 @@ 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))
++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/
@@ -973,7 +989,7 @@ 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))
+CFLAGS-.o = $(filter %frame-pointer,$(+cflags)) $(pie-default)
libtype.o := lib%.a
object-suffixes += .o
ifeq (yes,$(build-shared))
@@ -998,7 +1014,7 @@ ifeq (yes,$(build-profile))
all-object-suffixes += .op
object-suffixes += .op
CPPFLAGS-.op = -DPROF $(pic-default)
-CFLAGS-.op = -pg
+CFLAGS-.op = -pg $(pie-default)
libtype.op = lib%_p.a
endif
diff --git a/NEWS b/NEWS
index e346d2a..681ba8c 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,11 @@ Version 2.27
Major new features:
+* Add --enable-static-pie configure option to build static PIE. The
+ resulting libc.a can be used with the GCC option, -static-pie, which
+ is available with GCC 8 or above, to create static position independent
+ executable (static PIE).
+
* Optimized x86-64 asin, atan2, exp, expf, log, pow, atan, sin 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 014fb4e..26ed786 100644
--- a/config.h.in
+++ b/config.h.in
@@ -236,6 +236,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 067d92d..cd5cf57 100755
--- a/configure
+++ b/configure
@@ -767,6 +767,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
@@ -1424,6 +1425,7 @@ 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 build static executables as PIE [default=no]
--disable-timezone-tools
do not install timezone tools [default=install]
--enable-hardcoded-path-in-tests
@@ -3372,6 +3374,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
@@ -5994,6 +6003,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 :
@@ -6888,6 +6953,19 @@ fi
$as_echo "$libc_cv_pie_default" >&6; }
+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 d412104..09e1c7f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -176,6 +176,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],
+ [build static executables as PIE @<:@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@:>@]),
@@ -1460,6 +1465,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])
])
@@ -1962,6 +1980,17 @@ fi
rm -f conftest.*])
AC_SUBST(libc_cv_pie_default)
+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/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/elf/dl-support.c b/elf/dl-support.c
index 5e3de90..dc99462 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -26,7 +26,11 @@
#include <sys/param.h>
#include <stdint.h>
#include <ldsodefs.h>
-#include <dl-machine.h>
+#if ENABLE_STATIC_PIE
+# include "dynamic-link.h"
+#else
+# include <dl-machine.h>
+#endif
#include <libc-lock.h>
#include <dl-cache.h>
#include <dl-librecon.h>
@@ -199,7 +203,9 @@ const ElfW(Ehdr) *_dl_sysinfo_dso;
struct link_map *_dl_sysinfo_map;
-# include "get-dynamic-info.h"
+# if !ENABLE_STATIC_PIE
+# include "get-dynamic-info.h"
+# endif
#endif
#include "setup-vdso.h"
@@ -302,6 +308,39 @@ _dl_aux_init (ElfW(auxv_t) *av)
}
#endif
+#if ENABLE_STATIC_PIE
+/* Relocate static executable with PIE. */
+
+void
+_dl_relocate_static_pie (void)
+{
+# define STATIC_PIE_BOOTSTRAP
+# define RESOLVE_MAP(sym, version, flags) (&_dl_main_map)
+# include "dynamic-link.h"
+
+ /* Figure out the run-time load addres of static PIE. */
+ _dl_main_map.l_addr = elf_machine_load_address ();
+
+ /* Skip if this is a non-PIE static executable. */
+ if (!_dl_main_map.l_addr)
+ return;
+
+ /* Read our own dynamic section and fill in the info array. */
+ _dl_main_map.l_ld = ((void *) _dl_main_map.l_addr
+ + elf_machine_dynamic ());
+ elf_get_dynamic_info (&_dl_main_map, NULL);
+
+# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
+ ELF_MACHINE_BEFORE_RTLD_RELOC (_dl_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 (&_dl_main_map, 0, 0, 0);
+ _dl_main_map.l_relocated = 1;
+}
+#endif
+
void
_dl_non_dynamic_init (void)
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/manual/install.texi b/manual/install.texi
index 35948b1..2a2a430 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -136,6 +136,13 @@ 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
+Build static executables, including tests, as position independent
+executable (static PIE) which is similar to static executable, but can
+be loaded at any address without help from a dynamic linker. The
+resulting libc.a 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 1a4449e..b4c032a 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1048,6 +1048,13 @@ 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. */
+void _dl_relocate_static_pie (void) attribute_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/x86_64/configure b/sysdeps/x86_64/configure
index efef46b..8ee15b8 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 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..53e4a82 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 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)
-----------------------------------------------------------------------
hooks/post-receive
--
GNU C Library master sources