{"id":808847,"url":"http://patchwork.ozlabs.org/api/1.2/patches/808847/?format=json","web_url":"http://patchwork.ozlabs.org/project/glibc/patch/20170901174909.GA11261@gmail.com/","project":{"id":41,"url":"http://patchwork.ozlabs.org/api/1.2/projects/41/?format=json","name":"GNU C Library","link_name":"glibc","list_id":"libc-alpha.sourceware.org","list_email":"libc-alpha@sourceware.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20170901174909.GA11261@gmail.com>","list_archive_url":null,"date":"2017-09-01T17:49:09","name":"Add --enable-static-pie to build static PIE","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"fbb0c096fa3bb81242cb864976136cb137595879","submitter":{"id":4412,"url":"http://patchwork.ozlabs.org/api/1.2/people/4412/?format=json","name":"H.J. Lu","email":"hongjiu.lu@intel.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/glibc/patch/20170901174909.GA11261@gmail.com/mbox/","series":[{"id":1087,"url":"http://patchwork.ozlabs.org/api/1.2/series/1087/?format=json","web_url":"http://patchwork.ozlabs.org/project/glibc/list/?series=1087","date":"2017-09-01T17:49:09","name":"Add --enable-static-pie to build static PIE","version":1,"mbox":"http://patchwork.ozlabs.org/series/1087/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/808847/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/808847/checks/","tags":{},"related":[],"headers":{"Return-Path":"<libc-alpha-return-84043-incoming=patchwork.ozlabs.org@sourceware.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":["patchwork-incoming@bilbo.ozlabs.org","mailing list libc-alpha@sourceware.org"],"Authentication-Results":["ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=sourceware.org\n\t(client-ip=209.132.180.131; helo=sourceware.org;\n\tenvelope-from=libc-alpha-return-84043-incoming=patchwork.ozlabs.org@sourceware.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tsecure) header.d=sourceware.org header.i=@sourceware.org\n\theader.b=\"xZAEB/W8\"; dkim-atps=neutral","sourceware.org; auth=none"],"Received":["from sourceware.org (server1.sourceware.org [209.132.180.131])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xkRZj5pbNz9t3F\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat,  2 Sep 2017 03:49:33 +1000 (AEST)","(qmail 24546 invoked by alias); 1 Sep 2017 17:49:17 -0000","(qmail 24053 invoked by uid 89); 1 Sep 2017 17:49:16 -0000"],"DomainKey-Signature":"a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id\n\t:list-unsubscribe:list-subscribe:list-archive:list-post\n\t:list-help:sender:date:from:to:subject:message-id:reply-to\n\t:mime-version:content-type; q=dns; s=default; b=byxRNQBB1b3J0hWe\n\tmrkC9x9PgNuyoFXIXtb+m7oHHCMNgw4pYemAV6F6laefo/8y/aLZsFPm5D4HavBx\n\tBYwt8uBSRNl+syWkOku6LMQAwWNuMYKS2jm5Td48gMvPVB/9wF+ld7sg1gzo0Lgc\n\tQZAvly/2PG19+xqNVqLbybdpllM=","DKIM-Signature":"v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id\n\t:list-unsubscribe:list-subscribe:list-archive:list-post\n\t:list-help:sender:date:from:to:subject:message-id:reply-to\n\t:mime-version:content-type; s=default; bh=qSc9ZupyKAakNqFRQ6m4dn\n\t6G1nc=; b=xZAEB/W8j0B5INViFY4Ps6kXFXt9+fy7Q+1aqw8kuYeYcHSDlbjmqj\n\tgdYOqXPQCWVLN/BCSJVzJf05IFpJKnf3Rt2PBkMT7QyUVAehCS70Sbzo4cdbwpNI\n\t1tUbooLPk84ml98qkSeSDTFzskPdjLPDwFZdaAhTdANPyJBRH56Mc=","Mailing-List":"contact libc-alpha-help@sourceware.org; run by ezmlm","Precedence":"bulk","List-Id":"<libc-alpha.sourceware.org>","List-Unsubscribe":"<mailto:libc-alpha-unsubscribe-incoming=patchwork.ozlabs.org@sourceware.org>","List-Subscribe":"<mailto:libc-alpha-subscribe@sourceware.org>","List-Archive":"<http://sourceware.org/ml/libc-alpha/>","List-Post":"<mailto:libc-alpha@sourceware.org>","List-Help":"<mailto:libc-alpha-help@sourceware.org>,\n\t<http://sourceware.org/ml/#faqs>","Sender":"libc-alpha-owner@sourceware.org","X-Virus-Found":"No","X-Spam-SWARE-Status":"No, score=-24.5 required=5.0 tests=AWL, BAYES_00,\n\tGIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3,\n\tKAM_LAZY_DOMAIN_SECURITY, NO_DNS_FOR_FROM,\n\tRP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=LD","X-HELO":"mga05.intel.com","X-ExtLoop1":"1","Date":"Fri, 1 Sep 2017 10:49:09 -0700","From":"\"H.J. Lu\" <hongjiu.lu@intel.com>","To":"GNU C Library <libc-alpha@sourceware.org>","Subject":"[PATCH] Add --enable-static-pie to build static PIE","Message-ID":"<20170901174909.GA11261@gmail.com>","Reply-To":"\"H.J. Lu\" <hjl.tools@gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","User-Agent":"Mutt/1.8.3 (2017-05-23)"},"content":"--enable-static-pie configures glibc to compile libc.a as PIE and\ncreates static executables as PIE.  A static position independent\nexecutable (static PIE) is similar to static executable, but can be\nloaded at any address without help from a dynamic linker.  All linker\ninput files must be compiled with -fpie or -fPIE.  \"-z text\" is also\npassed to linker to prevent dynamic relocations in read-only segments.\nIt passes -static-pie to the GCC driver with the patch:\n\nhttps://gcc.gnu.org/ml/gcc-patches/2017-08/msg01455.html\n\nThis patch requires:\n\n1. Linker supports --no-dynamic-linker to remove PT_INTERP segment from\nstatic PIE.\n2. Linker can create working static PIE.  The x86-64 linker needs the\nfix for\n\nhttps://sourceware.org/bugzilla/show_bug.cgi?id=21782\n\nBinutils 2.29 or above are OK.\n\nTested on i686 and x86-64.\n\nOK for master?\n\nH.J.\n---\n\t* Makeconfig (pic-default): Updated for --enable-static-pie.\n\t(pie-default): New for --enable-static-pie.\n\t(default-pie-ldflag): Likewise.\n\t(+link-static-before-libc): Add $(default-pie-ldflag).\n\t(+prectorT): Updated for --enable-static-pie.\n\t(+postctorT): Likewise.\n\t(CFLAGS-.o): Add $(pie-default).\n\t(CFLAGS-.op): Likewise.\n\t* config.h.in (ENABLE_STATIC_PIE): New.\n\t* configure.ac (--enable-static-pie): New configure option.\n\t(have-no-dynamic-linker): New LIBC_CONFIG_VAR.\n\t(have-static-pie): Likewise.\n\tEnable static PIE if linker supports --no-dynamic-linker.\n\t(ENABLE_STATIC_PIE): New AC_DEFINE.\n\t(enable-static-pie): New LIBC_CONFIG_VAR.\n\t* configure: Regenerated.\n\t* csu/libc-start.c (LIBC_START_MAIN): Call _dl_relocate_static_pie\n\tin libc.a.\n\t* csu/libc-tls.c (__libc_setup_tls): Add main_map->l_addr to\n\tinitimage.\n\t* elf/dl-support.c: Include \"dynamic-link.h\" and don't include\n\t\"get-dynamic-info.h\" for --enable-static-pie.\n\t(_dl_relocate_static_pie): New function for --enable-static-pie.\n\t(STATIC_PIE_BOOTSTRAP): New for --enable-static-pie.\n\t(RESOLVE_MAP): Likewise.\n\t* elf/dynamic-link.h (ELF_DURING_STARTUP): Also check\n\tSTATIC_PIE_BOOTSTRAP.\n\t* elf/get-dynamic-info.h (elf_get_dynamic_info): Likewise.\n\t* sysdeps/generic/ldsodefs.h (_dl_relocate_static_pie): New.\n\t* sysdeps/x86_64/configure.ac: Check if linker supports static PIE.\n\t* sysdeps/x86_64/configure: Regenerated.\n---\n Makeconfig                  | 20 ++++++++++--\n config.h.in                 |  3 ++\n configure                   | 78 +++++++++++++++++++++++++++++++++++++++++++++\n configure.ac                | 29 +++++++++++++++++\n csu/libc-start.c            |  2 ++\n csu/libc-tls.c              |  6 ++--\n elf/dl-support.c            | 39 +++++++++++++++++++++--\n elf/dynamic-link.h          |  2 +-\n elf/get-dynamic-info.h      |  6 ++--\n sysdeps/generic/ldsodefs.h  |  7 ++++\n sysdeps/x86_64/configure    | 33 +++++++++++++++++++\n sysdeps/x86_64/configure.ac | 22 +++++++++++++\n 12 files changed, 237 insertions(+), 10 deletions(-)","diff":"diff --git a/Makeconfig b/Makeconfig\nindex b51904b797..b45209fe5f 100644\n--- a/Makeconfig\n+++ b/Makeconfig\n@@ -386,6 +386,16 @@ LDFLAGS.so += $(hashstyle-LDFLAGS)\n LDFLAGS-rtld += $(hashstyle-LDFLAGS)\n endif\n \n+ifeq (yes,$(enable-static-pie))\n+pic-default = -DPIC\n+pie-default = $(pie-ccflag)\n+ifeq (yes,$(have-static-pie))\n+default-pie-ldflag = -static-pie\n+else\n+default-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text\n+endif\n+endif\n+\n # If lazy relocations are disabled, add the -z now flag.  Use\n # LDFLAGS-lib.so instead of LDFLAGS.so, to avoid adding the flag to\n # test modules.\n@@ -435,6 +445,7 @@ endif\n # Command for statically linking programs with the C library.\n ifndef +link-static\n +link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \\\n+\t      $(default-pie-ldflag) \\\n \t      $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F))  \\\n \t      $(addprefix $(csu-objpfx),$(static-start-installed-name)) \\\n \t      $(+preinit) $(+prectorT) \\\n@@ -651,8 +662,13 @@ endif\n +prectorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginS.o`\n +postctorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtendS.o`\n # Variants of the two previous definitions for statically linking programs.\n+ifeq (yes,$(enable-static-pie))\n++prectorT = $(+prectorS)\n++postctorT = $(+postctorS)\n+else\n +prectorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginT.o`\n +postctorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o`\n+endif\n csu-objpfx = $(common-objpfx)csu/\n elf-objpfx = $(common-objpfx)elf/\n \n@@ -973,7 +989,7 @@ libtypes = $(foreach o,$(object-suffixes-for-libc),$(libtype$o))\n all-object-suffixes := .o .os .oS\n object-suffixes :=\n CPPFLAGS-.o = $(pic-default)\n-CFLAGS-.o = $(filter %frame-pointer,$(+cflags))\n+CFLAGS-.o = $(filter %frame-pointer,$(+cflags)) $(pie-default)\n libtype.o := lib%.a\n object-suffixes += .o\n ifeq (yes,$(build-shared))\n@@ -998,7 +1014,7 @@ ifeq (yes,$(build-profile))\n all-object-suffixes += .op\n object-suffixes += .op\n CPPFLAGS-.op = -DPROF $(pic-default)\n-CFLAGS-.op = -pg\n+CFLAGS-.op = -pg $(pie-default)\n libtype.op = lib%_p.a\n endif\n \ndiff --git a/config.h.in b/config.h.in\nindex 014fb4ea0e..26ed7865ef 100644\n--- a/config.h.in\n+++ b/config.h.in\n@@ -236,6 +236,9 @@\n /* Build glibc with tunables support.  */\n #define HAVE_TUNABLES 0\n \n+/* Define if static PIE is enabled.  */\n+#define ENABLE_STATIC_PIE 0\n+\n /* Some compiler options may now allow to use ebp in __asm__ (used mainly\n    in i386 6 argument syscall issue).  */\n #define CAN_USE_REGISTER_ASM_EBP 0\ndiff --git a/configure b/configure\nindex 5cb5210107..a04c59bacd 100755\n--- a/configure\n+++ b/configure\n@@ -767,6 +767,7 @@ with_default_link\n enable_sanity_checks\n enable_shared\n enable_profile\n+enable_static_pie\n enable_timezone_tools\n enable_hardcoded_path_in_tests\n enable_stackguard_randomization\n@@ -1424,6 +1425,7 @@ Optional Features:\n                           in special situations) [default=yes]\n   --enable-shared         build shared library [default=yes if GNU ld]\n   --enable-profile        build profiled library [default=no]\n+  --enable-static-pie     build static executables as PIE [default=no]\n   --disable-timezone-tools\n                           do not install timezone tools [default=install]\n   --enable-hardcoded-path-in-tests\n@@ -3372,6 +3374,13 @@ else\n   profile=no\n fi\n \n+# Check whether --enable-static-pie was given.\n+if test \"${enable_static_pie+set}\" = set; then :\n+  enableval=$enable_static_pie; static_pie=$enableval\n+else\n+  static_pie=no\n+fi\n+\n # Check whether --enable-timezone-tools was given.\n if test \"${enable_timezone_tools+set}\" = set; then :\n   enableval=$enable_timezone_tools; enable_timezone_tools=$enableval\n@@ -5994,6 +6003,62 @@ fi\n $as_echo \"$libc_linker_feature\" >&6; }\n \n \n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for linker that supports --no-dynamic-linker\" >&5\n+$as_echo_n \"checking for linker that supports --no-dynamic-linker... \" >&6; }\n+libc_linker_feature=no\n+if test x\"$gnu_ld\" = x\"yes\"; then\n+  libc_linker_check=`$LD -v --help 2>/dev/null | grep \"\\--no-dynamic-linker\"`\n+  if test -n \"$libc_linker_check\"; then\n+    cat > conftest.c <<EOF\n+int _start (void) { return 42; }\n+EOF\n+    if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp\n+\t\t\t\t-Wl,--no-dynamic-linker -nostdlib -nostartfiles\n+\t\t\t\t-fPIC -shared -o conftest.so conftest.c\n+\t\t\t\t1>&5'\n+  { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_try\\\"\"; } >&5\n+  (eval $ac_try) 2>&5\n+  ac_status=$?\n+  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n+  test $ac_status = 0; }; }\n+    then\n+      libc_linker_feature=yes\n+    fi\n+    rm -f conftest*\n+  fi\n+fi\n+if test $libc_linker_feature = yes; then\n+  libc_cv_no_dynamic_linker=yes\n+else\n+  libc_cv_no_dynamic_linker=no\n+fi\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature\" >&5\n+$as_echo \"$libc_linker_feature\" >&6; }\n+config_vars=\"$config_vars\n+have-no-dynamic-linker = $libc_cv_no_dynamic_linker\"\n+\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for -static-pie\" >&5\n+$as_echo_n \"checking for -static-pie... \" >&6; }\n+if ${libc_cv_static_pie+:} false; then :\n+  $as_echo_n \"(cached) \" >&6\n+else\n+  if { ac_try='${CC-cc} -static-pie -xc /dev/null -S -o /dev/null'\n+  { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_try\\\"\"; } >&5\n+  (eval $ac_try) 2>&5\n+  ac_status=$?\n+  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n+  test $ac_status = 0; }; }; then :\n+  libc_cv_static_pie=yes\n+else\n+  libc_cv_static_pie=no\n+fi\n+\n+fi\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie\" >&5\n+$as_echo \"$libc_cv_static_pie\" >&6; }\n+config_vars=\"$config_vars\n+have-static-pie = $libc_cv_static_pie\"\n+\n { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for -fpie\" >&5\n $as_echo_n \"checking for -fpie... \" >&6; }\n if ${libc_cv_fpie+:} false; then :\n@@ -6888,6 +6953,19 @@ fi\n $as_echo \"$libc_cv_pie_default\" >&6; }\n \n \n+if test \"$static_pie\" = yes; then\n+  # The linker must support --no-dynamic-linker.\n+  if test \"$libc_cv_no_dynamic_linker\" != yes; then\n+    as_fn_error $? \"linker support for --no-dynamic-linker needed\" \"$LINENO\" 5\n+  fi\n+  # Default to PIE.\n+  libc_cv_pie_default=yes\n+  $as_echo \"#define ENABLE_STATIC_PIE 1\" >>confdefs.h\n+\n+fi\n+config_vars=\"$config_vars\n+enable-static-pie = $static_pie\"\n+\n \n \n \ndiff --git a/configure.ac b/configure.ac\nindex 2c6308883c..96af835ce8 100644\n--- a/configure.ac\n+++ b/configure.ac\n@@ -176,6 +176,11 @@ AC_ARG_ENABLE([profile],\n \t\t\t     [build profiled library @<:@default=no@:>@]),\n \t      [profile=$enableval],\n \t      [profile=no])\n+AC_ARG_ENABLE([static-pie],\n+\t      AC_HELP_STRING([--enable-static-pie],\n+\t\t\t     [build static executables as PIE @<:@default=no@:>@]),\n+\t      [static_pie=$enableval],\n+\t      [static_pie=no])\n AC_ARG_ENABLE([timezone-tools],\n \t      AC_HELP_STRING([--disable-timezone-tools],\n \t\t\t     [do not install timezone tools @<:@default=install@:>@]),\n@@ -1460,6 +1465,19 @@ LIBC_LINKER_FEATURE([-z execstack], [-Wl,-z,execstack],\n \t\t    [libc_cv_z_execstack=yes], [libc_cv_z_execstack=no])\n AC_SUBST(libc_cv_z_execstack)\n \n+LIBC_LINKER_FEATURE([--no-dynamic-linker],\n+\t\t    [-Wl,--no-dynamic-linker],\n+\t\t    [libc_cv_no_dynamic_linker=yes],\n+\t\t    [libc_cv_no_dynamic_linker=no])\n+LIBC_CONFIG_VAR([have-no-dynamic-linker], [$libc_cv_no_dynamic_linker])\n+\n+AC_CACHE_CHECK(for -static-pie, libc_cv_static_pie, [dnl\n+LIBC_TRY_CC_OPTION([-static-pie],\n+\t\t   [libc_cv_static_pie=yes],\n+\t\t   [libc_cv_static_pie=no])\n+])\n+LIBC_CONFIG_VAR([have-static-pie], [$libc_cv_static_pie])\n+\n AC_CACHE_CHECK(for -fpie, libc_cv_fpie, [dnl\n LIBC_TRY_CC_OPTION([-fpie], [libc_cv_fpie=yes], [libc_cv_fpie=no])\n ])\n@@ -1962,6 +1980,17 @@ fi\n rm -f conftest.*])\n AC_SUBST(libc_cv_pie_default)\n \n+if test \"$static_pie\" = yes; then\n+  # The linker must support --no-dynamic-linker.\n+  if test \"$libc_cv_no_dynamic_linker\" != yes; then\n+    AC_MSG_ERROR([linker support for --no-dynamic-linker needed])\n+  fi\n+  # Default to PIE.\n+  libc_cv_pie_default=yes\n+  AC_DEFINE(ENABLE_STATIC_PIE)\n+fi\n+LIBC_CONFIG_VAR([enable-static-pie], [$static_pie])\n+\n AC_SUBST(profile)\n AC_SUBST(static_nss)\n \ndiff --git a/csu/libc-start.c b/csu/libc-start.c\nindex 24c63be02f..34dd125260 100644\n--- a/csu/libc-start.c\n+++ b/csu/libc-start.c\n@@ -141,6 +141,8 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),\n   __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up;\n \n #ifndef SHARED\n+  _dl_relocate_static_pie ();\n+\n   char **ev = &argv[argc + 1];\n \n   __environ = ev;\ndiff --git a/csu/libc-tls.c b/csu/libc-tls.c\nindex 00138eb43a..1f8ddaf543 100644\n--- a/csu/libc-tls.c\n+++ b/csu/libc-tls.c\n@@ -114,6 +114,8 @@ __libc_setup_tls (void)\n   size_t tcb_offset;\n   const ElfW(Phdr) *phdr;\n \n+  struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;\n+\n   /* Look through the TLS segment if there is any.  */\n   if (_dl_phdr != NULL)\n     for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr)\n@@ -122,7 +124,7 @@ __libc_setup_tls (void)\n \t  /* Remember the values we need.  */\n \t  memsz = phdr->p_memsz;\n \t  filesz = phdr->p_filesz;\n-\t  initimage = (void *) phdr->p_vaddr;\n+\t  initimage = (void *) phdr->p_vaddr + main_map->l_addr;\n \t  align = phdr->p_align;\n \t  if (phdr->p_align > max_align)\n \t    max_align = phdr->p_align;\n@@ -163,8 +165,6 @@ __libc_setup_tls (void)\n   _dl_static_dtv[0].counter = (sizeof (_dl_static_dtv) / sizeof (_dl_static_dtv[0])) - 2;\n   // _dl_static_dtv[1].counter = 0;\t\twould be needed if not already done\n \n-  struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;\n-\n   /* Initialize the TLS block.  */\n #if TLS_TCB_AT_TP\n   _dl_static_dtv[2].pointer.val = ((char *) tlsblock + tcb_offset\ndiff --git a/elf/dl-support.c b/elf/dl-support.c\nindex 48340f7959..09b2229d48 100644\n--- a/elf/dl-support.c\n+++ b/elf/dl-support.c\n@@ -26,7 +26,11 @@\n #include <sys/param.h>\n #include <stdint.h>\n #include <ldsodefs.h>\n-#include <dl-machine.h>\n+#if ENABLE_STATIC_PIE\n+# include \"dynamic-link.h\"\n+#else\n+# include <dl-machine.h>\n+#endif\n #include <libc-lock.h>\n #include <dl-cache.h>\n #include <dl-librecon.h>\n@@ -199,7 +203,9 @@ const ElfW(Ehdr) *_dl_sysinfo_dso;\n \n struct link_map *_dl_sysinfo_map;\n \n-# include \"get-dynamic-info.h\"\n+# if !ENABLE_STATIC_PIE\n+#  include \"get-dynamic-info.h\"\n+# endif\n #endif\n #include \"setup-vdso.h\"\n \n@@ -303,6 +309,35 @@ _dl_aux_init (ElfW(auxv_t) *av)\n }\n #endif\n \n+#if ENABLE_STATIC_PIE\n+/* Relocate static executable with PIE.  */\n+\n+void\n+_dl_relocate_static_pie (void)\n+{\n+# define STATIC_PIE_BOOTSTRAP\n+# define RESOLVE_MAP(sym, version, flags) (&_dl_main_map)\n+# include \"dynamic-link.h\"\n+\n+  /* Figure out the run-time load addres of static PIE.  */\n+  _dl_main_map.l_addr = elf_machine_load_address ();\n+\n+  /* Read our own dynamic section and fill in the info array.  */\n+  _dl_main_map.l_ld = ((void *) _dl_main_map.l_addr\n+\t\t       + elf_machine_dynamic ());\n+  elf_get_dynamic_info (&_dl_main_map, NULL);\n+\n+# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC\n+  ELF_MACHINE_BEFORE_RTLD_RELOC (_dl_main_map.l_info);\n+# endif\n+\n+  /* Relocate ourselves so we can do normal function calls and\n+     data access using the global offset table.  */\n+  ELF_DYNAMIC_RELOCATE (&_dl_main_map, 0, 0, 0);\n+  _dl_main_map.l_relocated = 1;\n+}\n+#endif\n+\n \n void\n internal_function\ndiff --git a/elf/dynamic-link.h b/elf/dynamic-link.h\nindex 60f2d91151..d3935f7da7 100644\n--- a/elf/dynamic-link.h\n+++ b/elf/dynamic-link.h\n@@ -95,7 +95,7 @@ elf_machine_lazy_rel (struct link_map *map,\n \n #ifdef RESOLVE_MAP\n \n-# ifdef RTLD_BOOTSTRAP\n+# if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP\n #  define ELF_DURING_STARTUP (1)\n # else\n #  define ELF_DURING_STARTUP (0)\ndiff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h\nindex 7525c3a5b2..eb26d23649 100644\n--- a/elf/get-dynamic-info.h\n+++ b/elf/get-dynamic-info.h\n@@ -38,7 +38,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)\n   typedef Elf64_Xword d_tag_utype;\n #endif\n \n-#ifndef RTLD_BOOTSTRAP\n+#if !defined RTLD_BOOTSTRAP && !defined STATIC_PIE_BOOTSTRAP\n   if (dyn == NULL)\n     return;\n #endif\n@@ -139,9 +139,11 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)\n   /* Only the bind now flags are allowed.  */\n   assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL\n \t  || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);\n+  /* Flags must not be set for ld.so.  */\n   assert (info[DT_FLAGS] == NULL\n \t  || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);\n-  /* Flags must not be set for ld.so.  */\n+#endif\n+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP\n   assert (info[DT_RUNPATH] == NULL);\n   assert (info[DT_RPATH] == NULL);\n #else\ndiff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h\nindex 49e673dd24..83791103cf 100644\n--- a/sysdeps/generic/ldsodefs.h\n+++ b/sysdeps/generic/ldsodefs.h\n@@ -1069,6 +1069,13 @@ extern void _dl_determine_tlsoffset (void) internal_function attribute_hidden;\n    stack protector, among other things).  */\n void __libc_setup_tls (void);\n \n+# if ENABLE_STATIC_PIE\n+/* Relocate static executable with PIE.  */\n+void _dl_relocate_static_pie (void) attribute_hidden;\n+# else\n+#  define _dl_relocate_static_pie()\n+# endif\n+\n /* Initialization of libpthread for statically linked applications.\n    If libpthread is not linked in, this is an empty function.  */\n void __pthread_initialize_minimal (void) weak_function;\ndiff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure\nindex efef46b1b7..8ee15b8a25 100644\n--- a/sysdeps/x86_64/configure\n+++ b/sysdeps/x86_64/configure\n@@ -85,6 +85,39 @@ if test x\"$build_mathvec\" = xnotset; then\n   build_mathvec=yes\n fi\n \n+if test \"$static_pie\" = yes; then\n+  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for linker static PIE support\" >&5\n+$as_echo_n \"checking for linker static PIE support... \" >&6; }\n+if ${libc_cv_ld_static_pie+:} false; then :\n+  $as_echo_n \"(cached) \" >&6\n+else\n+  cat > conftest.s <<\\EOF\n+\t.text\n+\t.global _start\n+\t.weak foo\n+_start:\n+\tleaq\tfoo(%rip), %rax\n+EOF\n+  libc_cv_pie_option=\"-Wl,-pie\"\n+  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option conftest.s 1>&5'\n+  { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_try\\\"\"; } >&5\n+  (eval $ac_try) 2>&5\n+  ac_status=$?\n+  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n+  test $ac_status = 0; }; }; then\n+    libc_cv_ld_static_pie=yes\n+  else\n+    libc_cv_ld_static_pie=no\n+  fi\n+rm -f conftest*\n+fi\n+{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $libc_cv_ld_static_pie\" >&5\n+$as_echo \"$libc_cv_ld_static_pie\" >&6; }\n+  if test \"$libc_cv_ld_static_pie\" != yes; then\n+    as_fn_error $? \"linker support for static PIE needed\" \"$LINENO\" 5\n+  fi\n+fi\n+\n $as_echo \"#define PI_STATIC_AND_HIDDEN 1\" >>confdefs.h\n \n \ndiff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac\nindex fa86e953ee..c2d7cf3e61 100644\n--- a/sysdeps/x86_64/configure.ac\n+++ b/sysdeps/x86_64/configure.ac\n@@ -44,6 +44,28 @@ if test x\"$build_mathvec\" = xnotset; then\n   build_mathvec=yes\n fi\n \n+dnl Check if linker supports static PIE.\n+if test \"$static_pie\" = yes; then\n+  AC_CACHE_CHECK(for linker static PIE support, libc_cv_ld_static_pie, [dnl\n+cat > conftest.s <<\\EOF\n+\t.text\n+\t.global _start\n+\t.weak foo\n+_start:\n+\tleaq\tfoo(%rip), %rax\n+EOF\n+  libc_cv_pie_option=\"-Wl,-pie\"\n+  if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option conftest.s 1>&AS_MESSAGE_LOG_FD); then\n+    libc_cv_ld_static_pie=yes\n+  else\n+    libc_cv_ld_static_pie=no\n+  fi\n+rm -f conftest*])\n+  if test \"$libc_cv_ld_static_pie\" != yes; then\n+    AC_MSG_ERROR([linker support for static PIE needed])\n+  fi\n+fi\n+\n dnl It is always possible to access static and hidden symbols in an\n dnl position independent way.\n AC_DEFINE(PI_STATIC_AND_HIDDEN)\n","prefixes":[]}