From patchwork Thu Oct 5 13:11:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 23342 Received: (qmail 42640 invoked by alias); 5 Oct 2017 13:12:01 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 42522 invoked by uid 89); 5 Oct 2017 13:11:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.9 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS, URIBL_RED autolearn=ham version=3.3.2 spammy= X-HELO: mail-oi0-f68.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=AnL3T6FG4oQcFPA8pIa/OD3wQFA2JKg6OrcfgR0aLoA=; b=jinSa3Oc2P20YdwHs8b/LKiUz8GNHSBbsodubFAvdyx2/Q1bWHc/49+dUYv9o0zv5z szeajeIfsi+jbSZG0A0QMNSmm5MZKQ83R+qodSHvf9kLMwHxkEFKtK03r/Pc4GQLFVC5 EVtcFai1B1ZGiQjr1Zkv8Sx/3qwKfJFgCUnaWksDBs4l89wNu40e4qi6CYsMzCcLvTVR SBVEyBVTVd7D66PkphSG90yEwgkT3OKFYAZeFjW3ZGTFhbgUgOprK/8yVFv379TI3zQM iLagh4gIUMqEQgPaq2Aa/Rx+SaWg9flZQGOg1ndbo79gVlflyUgdjgOAp0u6tNHsq+GD AI9g== X-Gm-Message-State: AMCzsaW4cRp2hoedA1fmouyLWexI+tpRDaWebvOWkLyLEqu0WcwOr3ls krdIGSb8KzMOkWfeeB7PrIHOONIydLWKS3zR8NU= X-Google-Smtp-Source: AOwi7QB/cQ71b2njLD+bpbSibNmS7jWrJpqyx/AP3BaUFeVf+7l/BGaw9Wy+70m1GZ/HcMuVUvveozPy32iiSZtAGnI= X-Received: by 10.202.171.216 with SMTP id u207mr6525086oie.430.1507209106923; Thu, 05 Oct 2017 06:11:46 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: References: From: "H.J. Lu" Date: Thu, 5 Oct 2017 06:11:45 -0700 Message-ID: Subject: Re: PING: [PATCH] Add --enable-static-pie to build static PIE To: Joseph Myers Cc: GNU C Library On 9/29/17, H.J. Lu wrote: > On 9/28/17, Joseph Myers wrote: >> On Wed, 27 Sep 2017, H.J. Lu wrote: >> >>> > static-PIE libraries) - although adding one or two additional >>> > static-PIE >>> > configurations to build-many-glibcs.py might be - but for testing >>> > purposes >>> > it's very useful to understand how widely this option works (or at >>> > least >>> > builds) for other architectures. >>> >>> Many architectures failed to build static PIE due to asm statements in >>> elf_machine_dynamic and elf_machine_load_address. I didn't check >>> start.S which will fail at run-time if there are any dynamic >>> relocations. >> >> In that case: (a) the install.texi / NEWS entries need to make clear the >> limited nature of architecture support for this feature; (b) if the >> feature achieves consensus to go in mainline at all, >> will need updating with a >> list of all the architectures lacking support and detailed information >> for >> architecture maintainers regarding how to make the feature work on their >> architectures and how to tell whether it is working. >> > > I submitted patches for other targets to address obvious issues with static > PIE. Build results of build-many-glibcs.py with --enable-static-pie with > all > patches for static PIE applied are > > PASS: glibcs-aarch64_be-linux-gnu build > PASS: glibcs-aarch64-linux-gnu build > PASS: glibcs-armeb-linux-gnueabi build > PASS: glibcs-armeb-linux-gnueabi-be8 build > PASS: glibcs-armeb-linux-gnueabihf build > PASS: glibcs-armeb-linux-gnueabihf-be8 build > PASS: glibcs-arm-linux-gnueabi build > PASS: glibcs-arm-linux-gnueabihf build > PASS: glibcs-hppa-linux-gnu build > PASS: glibcs-i486-linux-gnu build > PASS: glibcs-i586-linux-gnu build > PASS: glibcs-i686-linux-gnu build > PASS: glibcs-i686-linux-gnu-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-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-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-nios2-linux-gnu build > PASS: glibcs-powerpc64le-linux-gnu build > PASS: glibcs-powerpc64-linux-gnu build > PASS: glibcs-s390x-linux-gnu build > PASS: glibcs-x86_64-linux-gnu build > PASS: glibcs-x86_64-linux-gnu-disable-multi-arch build > PASS: glibcs-x86_64-linux-gnu-x32 build > > 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-ia64-linux-gnu build > > elf/sln is failed to link due to: > > libc.a(sched_yield.o): non-pic code with imm relocation against > dynamic symbol `_dl_sysinfo' > > This is caused by non-PICi version of DO_CALL macro in ia64 sysdep.h. PIE > libc.a should use PIC version of DO_CALL, except during startup in static > PIE. An ia64 startup.h, similar to i386 startup.h, is needed to handle > this. > > FAIL: glibcs-mips64el-linux-gnu-n32 build > FAIL: glibcs-mips64el-linux-gnu-n32-nan2008 build > FAIL: glibcs-mips64el-linux-gnu-n32-nan2008-soft build > FAIL: glibcs-mips64el-linux-gnu-n32-soft build > FAIL: glibcs-mips64-linux-gnu-n32 build > FAIL: glibcs-mips64-linux-gnu-n32-nan2008 build > FAIL: glibcs-mips64-linux-gnu-n32-nan2008-soft build > FAIL: glibcs-mips64-linux-gnu-n32-soft build > FAIL: glibcs-mipsel-linux-gnu build > FAIL: glibcs-mipsel-linux-gnu-nan2008 build > FAIL: glibcs-mipsel-linux-gnu-nan2008-soft build > FAIL: glibcs-mipsel-linux-gnu-soft build > FAIL: glibcs-mips-linux-gnu build > FAIL: glibcs-mips-linux-gnu-nan2008 build > FAIL: glibcs-mips-linux-gnu-nan2008-soft build > FAIL: glibcs-mips-linux-gnu-soft build > > elf/sln is failed to link due to: > > crt1.o: relocation R_MIPS_HI16 against `_gp' can not be used when > making a shared object; recompile with -fPIC > > This is caused by linker bug and/or non-PIC code in crt1.o. > > 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. > > 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:14242 > > 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. > > FAIL: glibcs-sparc64-linux-gnu build > FAIL: glibcs-sparcv9-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. > > 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. > > Here is the updated patch to state that i686, x86-64 and x32 targets > are verified to work. I encourage target maintainers to try hjl/pie/static > branch to verify if static PIE works for your targets. > Here is the updated patch. The related glibc/binutils bugs are: https://sourceware.org/bugzilla/show_bug.cgi?id=22264 https://sourceware.org/bugzilla/show_bug.cgi?id=20179 https://sourceware.org/bugzilla/show_bug.cgi?id=22263 From c9972a39895ce2aeb19d0f783569aea750f1698f Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 17 Jul 2017 08:17:32 -0700 Subject: [PATCH 01/11] Add --enable-static-pie configure option to build static PIE [BZ #19574] 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. crt1.o, which is used to create dynamic and non-PIE static executables, is updated to include a dummy _dl_relocate_static_pie. Pcrt1.o is added to create static PIE, which will link in the real _dl_relocate_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 statice PIE are local functions. If PIE start.S can't reach main () defined in a shared object, the code sequence: pass addess 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, m68k, s390 and sh. 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 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. Tested on i686 and x86-64. Build results of build-many-glibcs.py with --enable-static-pie with all patches for static PIE applied are PASS: glibcs-aarch64_be-linux-gnu build PASS: glibcs-aarch64-linux-gnu build PASS: glibcs-armeb-linux-gnueabi build PASS: glibcs-armeb-linux-gnueabi-be8 build PASS: glibcs-armeb-linux-gnueabihf build PASS: glibcs-armeb-linux-gnueabihf-be8 build PASS: glibcs-arm-linux-gnueabi build PASS: glibcs-arm-linux-gnueabihf build PASS: glibcs-hppa-linux-gnu build PASS: glibcs-i486-linux-gnu build PASS: glibcs-i586-linux-gnu build PASS: glibcs-i686-linux-gnu build PASS: glibcs-i686-linux-gnu-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-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-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-nios2-linux-gnu build PASS: glibcs-powerpc64le-linux-gnu build PASS: glibcs-powerpc64-linux-gnu build PASS: glibcs-s390x-linux-gnu build PASS: glibcs-x86_64-linux-gnu build PASS: glibcs-x86_64-linux-gnu-disable-multi-arch build PASS: glibcs-x86_64-linux-gnu-x32 build 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-ia64-linux-gnu build elf/sln is failed to link due to: libc.a(sched_yield.o): non-pic code with imm relocation against dynamic symbol `_dl_sysinfo' This is caused by non-PIC version of DO_CALL macro in ia64 sysdep.h. PIE libc.a should use PIC version of DO_CALL, except during startup in static PIE. An ia64 startup.h, similar to i386 startup.h, is needed to handle this. FAIL: glibcs-mips64el-linux-gnu-n32 build FAIL: glibcs-mips64el-linux-gnu-n32-nan2008 build FAIL: glibcs-mips64el-linux-gnu-n32-nan2008-soft build FAIL: glibcs-mips64el-linux-gnu-n32-soft build FAIL: glibcs-mips64-linux-gnu-n32 build FAIL: glibcs-mips64-linux-gnu-n32-nan2008 build FAIL: glibcs-mips64-linux-gnu-n32-nan2008-soft build FAIL: glibcs-mips64-linux-gnu-n32-soft build FAIL: glibcs-mipsel-linux-gnu build FAIL: glibcs-mipsel-linux-gnu-nan2008 build FAIL: glibcs-mipsel-linux-gnu-nan2008-soft build FAIL: glibcs-mipsel-linux-gnu-soft build FAIL: glibcs-mips-linux-gnu build FAIL: glibcs-mips-linux-gnu-nan2008 build FAIL: glibcs-mips-linux-gnu-nan2008-soft build FAIL: glibcs-mips-linux-gnu-soft build elf/sln is failed to link due to: crt1.o: relocation R_MIPS_HI16 against `_gp' can not be used when making a shared object; recompile with -fPIC This is caused by linker bug and/or non-PIC code in crt1.o. 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:14242 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. FAIL: glibcs-sparc64-linux-gnu build FAIL: glibcs-sparcv9-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=20179 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 (static-start-installed-name): Add the `P' prefix for --enable-static-pie. (pic-default): Updated for --enable-static-pie. (pie-default): New for --enable-static-pie. (default-pie-ldflag): Likewise. (+link-static-before-libc): Use the first of $(DEFAULT-LDFLAGS-$(@F)) and $(default-pie-ldflag). Use the first of $(CRT-$(@F)) and $(csu-objpfx)$(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 P$(start-installed-name) for --enable-static-pie. (extra-objs): Likewise. (install-lib): Likewise. Don't add gPcrt1.o. (extra-objs): Add static-reloc.o. ($(objpfx)$(start-installed-name)): Include $(objpfx)static-reloc.o. ($(objpfx)P$(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. * dl-reloc-static-pie.c: New file. * elf/dl-support.c (_dl_main_map): Make it hidden global. * 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/i386/configure.ac: Check if linker supports static PIE. * sysdeps/x86_64/configure.ac: Likewise. * sysdeps/i386/configure: Regenerated. * sysdeps/x86_64/configure: Likewise. --- INSTALL | 8 +++++ Makeconfig | 27 +++++++++++++--- NEWS | 6 ++++ config.h.in | 3 ++ configure | 78 +++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 29 +++++++++++++++++ csu/Makefile | 16 ++++++++-- csu/libc-start.c | 2 ++ csu/libc-tls.c | 6 ++-- csu/static-reloc.c | 26 +++++++++++++++ elf/Makefile | 5 +-- elf/dl-reloc-static-pie.c | 53 ++++++++++++++++++++++++++++++ elf/dl-support.c | 2 +- elf/dynamic-link.h | 2 +- elf/get-dynamic-info.h | 6 ++-- manual/install.texi | 8 +++++ sysdeps/generic/ldsodefs.h | 7 ++++ sysdeps/i386/configure | 33 +++++++++++++++++++ sysdeps/i386/configure.ac | 23 +++++++++++++ sysdeps/x86_64/configure | 33 +++++++++++++++++++ sysdeps/x86_64/configure.ac | 25 +++++++++++++++ 21 files changed, 383 insertions(+), 15 deletions(-) create mode 100644 csu/static-reloc.c create mode 100644 elf/dl-reloc-static-pie.c diff --git a/INSTALL b/INSTALL index 4d9024c667..55361a0fd3 100644 --- a/INSTALL +++ b/INSTALL @@ -106,6 +106,14 @@ 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. Only + i686, x86-64 and x32 targets are verified to work. + '--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 0ceff92a3d..ac79083912 100644 --- a/Makeconfig +++ b/Makeconfig @@ -367,6 +367,10 @@ ifndef static-start-installed-name static-start-installed-name = $(start-installed-name) endif +ifeq (yes,$(enable-static-pie)) +static-start-installed-name := P$(static-start-installed-name) +endif + ifeq (yesyes,$(build-shared)$(have-z-combreloc)) combreloc-LDFLAGS = -Wl,-z,combreloc LDFLAGS.so += $(combreloc-LDFLAGS) @@ -386,6 +390,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,9 +449,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)) \ + $(firstword $(DEFAULT-LDFLAGS-$(@F)) $(default-pie-ldflag)) \ $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ - $(addprefix $(csu-objpfx),$(static-start-installed-name)) \ + $(firstword $(CRT-$(@F)) $(csu-objpfx)$(static-start-installed-name)) \ $(+preinit) $(+prectorT) \ $(filter-out $(addprefix $(csu-objpfx),start.o \ $(start-installed-name))\ @@ -652,8 +666,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/ @@ -974,7 +993,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)) @@ -999,7 +1018,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 f5821411ca..60f5def617 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,12 @@ 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). Only i686, x86-64 and x32 targets are verified + to work. + * 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 c140ff3ecb..f7db916711 100644 --- a/config.h.in +++ b/config.h.in @@ -244,6 +244,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 a7c72eaaa6..6bf3c6c1af 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 @@ -5998,6 +6007,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 <&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 : @@ -6892,6 +6957,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 4b83ae5a09..b2f727224f 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@:>@]), @@ -1464,6 +1469,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]) ]) @@ -1966,6 +1984,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/Makefile b/csu/Makefile index fd668a5d00..e342a19956 100644 --- a/csu/Makefile +++ b/csu/Makefile @@ -37,7 +37,8 @@ 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) \ + P$(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 @@ -55,16 +56,24 @@ extra-objs += gmon-start.o endif install-lib += S$(start-installed-name) generated += start.os +ifeq (yes,$(enable-static-pie)) +extra-objs += P$(start-installed-name) +install-lib += P$(start-installed-name) +endif else extra-objs += gmon-start.o endif ifneq ($(start-installed-name),$(static-start-installed-name)) +# FIXME: If we want to support profiling static PIE, we need to create +# and install gPcrt1.o. +ifneq (P$(start-installed-name),$(static-start-installed-name)) 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) endif +endif before-compile += $(objpfx)abi-tag.h generated += abi-tag.h @@ -77,7 +86,7 @@ crtstuff = crti crtn install-lib += $(crtstuff:=.o) extra-objs += $(crtstuff:=.o) -extra-objs += abi-note.o init.o +extra-objs += abi-note.o init.o static-reloc.o asm-CPPFLAGS += -I$(objpfx). # Enable unwinding so backtrace unwinds to __libc_start_main @@ -96,6 +105,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)P$(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 \ diff --git a/csu/libc-start.c b/csu/libc-start.c index 24c63be02f..34dd125260 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 00138eb43a..1f8ddaf543 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 0000000000..37be72c8ea --- /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 + . */ + +#if ENABLE_STATIC_PIE +#include + +void +_dl_relocate_static_pie (void) +{ +} +#endif diff --git a/elf/Makefile b/elf/Makefile index a31fb72498..cb035e63aa 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 diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c new file mode 100644 index 0000000000..630482a28a --- /dev/null +++ b/elf/dl-reloc-static-pie.c @@ -0,0 +1,53 @@ +/* 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 + . */ + +#if ENABLE_STATIC_PIE +#include +#include +#include "dynamic-link.h" + +/* Relocate static executable with PIE. */ + +extern struct link_map _dl_main_map __attribute__((visibility ("hidden"))); + +void +_dl_relocate_static_pie (void) +{ +# define STATIC_PIE_BOOTSTRAP +# define BOOTSTRAP_MAP (&_dl_main_map) +# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP +# include "dynamic-link.h" + + /* Figure out the run-time load addres of static PIE. */ + _dl_main_map.l_addr = elf_machine_load_address (); + + /* 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 diff --git a/elf/dl-support.c b/elf/dl-support.c index 5e3de90598..99ad0f1781 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -72,7 +72,7 @@ int _dl_bind_not; /* A dummy link map for the executable, used by dlopen to access the global scope. We don't export any symbols ourselves, so this can be minimal. */ -static struct link_map _dl_main_map = +struct link_map _dl_main_map __attribute__((visibility ("hidden"))) = { .l_name = (char *) "", .l_real = &_dl_main_map, diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index ebea7567cd..6278649711 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 7525c3a5b2..eb26d23649 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 35948b1bbb..54df6abb97 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -136,6 +136,14 @@ 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. Only i686, x86-64 +and x32 targets are verified to work. + @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 5efae2d96d..dbcc1ec766 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/i386/configure b/sysdeps/i386/configure index 4cf968d8bc..90c63caf35 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 b598b120bc..6d2068d2b3 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/x86_64/configure b/sysdeps/x86_64/configure index efef46b1b7..8674d14569 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 fa86e953ee..b7d2c0124f 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) -- 2.13.6