mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 12:30:06 +00:00
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. 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. 5. elf_machine_load_address in dl-machine.h are updated to support static PIE. 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.
This commit is contained in:
parent
95511aab9d
commit
9d7a3741c9
72
ChangeLog
72
ChangeLog
@ -1,3 +1,75 @@
|
||||
2017-12-15 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
[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.
|
||||
|
||||
2017-12-15 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* io/Makefile (tst-open-tmpfile-ARGS): New variable.
|
||||
|
9
INSTALL
9
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.
|
||||
|
38
Makeconfig
38
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
|
||||
|
||||
|
9
NEWS
9
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.
|
||||
|
@ -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
|
||||
|
79
configure
vendored
79
configure
vendored
@ -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"
|
||||
|
||||
|
||||
|
||||
|
||||
|
29
configure.ac
29
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)
|
||||
|
||||
|
24
csu/Makefile
24
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): \
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
26
csu/static-reloc.c
Normal file
26
csu/static-reloc.c
Normal file
@ -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
|
@ -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 \
|
||||
|
52
elf/dl-reloc-static-pie.c
Normal file
52
elf/dl-reloc-static-pie.c
Normal file
@ -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
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
1
gmon/tst-gmon-static-pie.c
Normal file
1
gmon/tst-gmon-static-pie.c
Normal file
@ -0,0 +1 @@
|
||||
#include "tst-gmon.c"
|
@ -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.
|
||||
|
@ -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;
|
||||
|
33
sysdeps/i386/configure
vendored
33
sysdeps/i386/configure
vendored
@ -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 :
|
||||
|
@ -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
|
||||
|
@ -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),)
|
||||
|
33
sysdeps/x86_64/configure
vendored
33
sysdeps/x86_64/configure
vendored
@ -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
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user