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


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

GNU C Library master sources branch hjl/cet/property created. glibc-2.25-640-g88681bb


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

The branch, hjl/cet/property has been created
        at  88681bbba6364298f7ab787d8c8630cb7b7fa4bb (commit)

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

commit 88681bbba6364298f7ab787d8c8630cb7b7fa4bb
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jun 28 15:16:46 2017 -0700

    i386: Add _dl_runtime_resolve_shstk [BZ #21598]
    
    Add a SHSTK compatible symbol resolver to support Shadow Stack in Intel
    Control-flow Enforcement Technology (CET) instructions:
    
    https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
    
    and replace _dl_runtime_resolve with _dl_runtime_resolve_shstk if SHSTK
    is enabled.
    
    	 [BZ #21598]
    	 * sysdeps/i386/dl-trampoline.S (_dl_runtime_resolve_shstk): New.
    	 * sysdeps/unix/sysv/linux/i386/dl-cet.c: New file.

diff --git a/sysdeps/i386/dl-trampoline.S b/sysdeps/i386/dl-trampoline.S
index 6e7f3ae..92029f7 100644
--- a/sysdeps/i386/dl-trampoline.S
+++ b/sysdeps/i386/dl-trampoline.S
@@ -50,6 +50,29 @@ _dl_runtime_resolve:
 	cfi_endproc
 	.size _dl_runtime_resolve, .-_dl_runtime_resolve
 
+# The SHSTK compatible version.
+	.text
+	.globl _dl_runtime_resolve_shstk
+	.type _dl_runtime_resolve_shstk, @function
+	cfi_startproc
+	.align 16
+_dl_runtime_resolve_shstk:
+	cfi_adjust_cfa_offset (8)
+	pushl %eax		# Preserve registers otherwise clobbered.
+	cfi_adjust_cfa_offset (4)
+	pushl %edx
+	cfi_adjust_cfa_offset (4)
+	movl 12(%esp), %edx	# Copy args pushed by PLT in register.  Note
+	movl 8(%esp), %eax	# that `fixup' takes its parameters in regs.
+	call _dl_fixup		# Call resolver.
+	movl (%esp), %edx	# Get register content back.
+	movl %eax, %ecx		# Store the function address.
+	movl 4(%esp), %eax	# Get register content back.
+	addl $16, %esp		# Adjust stack: PLT1 + PLT2 + %eax + %edx
+	cfi_adjust_cfa_offset (-16)
+	jmp *%ecx		# Jump to function address.
+	cfi_endproc
+	.size _dl_runtime_resolve_shstk, .-_dl_runtime_resolve_shstk
 
 #ifndef PROF
 	.globl _dl_runtime_profile
diff --git a/sysdeps/unix/sysv/linux/i386/dl-cet.c b/sysdeps/unix/sysv/linux/i386/dl-cet.c
new file mode 100644
index 0000000..7f63b55
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/dl-cet.c
@@ -0,0 +1,60 @@
+/* Linux/i386 CET initializers function.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   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/>.  */
+
+#ifdef SHARED
+# define LINKAGE static inline
+# define _dl_cet_init cet_init
+# include <sysdeps/unix/sysv/linux/x86/dl-cet.c>
+# undef _dl_cet_init
+
+void
+internal_function
+_dl_cet_init (struct link_map *main_map, int argc, char **argv, char **env)
+{
+  cet_init (main_map, argc, argv, env);
+
+  if ((GL(dl_x86_feature_1) & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
+    {
+      /* Replace _dl_runtime_resolve with _dl_runtime_resolve_shstk if
+	 SHSTK is enabled.  */
+      extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden;
+      extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden;
+      unsigned int i;
+      struct link_map *l;
+      Elf32_Addr *got;
+
+      if (main_map->l_info[DT_JMPREL])
+	{
+	  got = (Elf32_Addr *) D_PTR (main_map, l_info[DT_PLTGOT]);
+	  if (got[2] == (Elf32_Addr) &_dl_runtime_resolve)
+	    got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk;
+	}
+
+      i = main_map->l_searchlist.r_nlist;
+      while (i-- > 0)
+	{
+	  l = main_map->l_initfini[i];
+	  if (l->l_info[DT_JMPREL])
+	    {
+	      got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
+	      if (got[2] == (Elf32_Addr) &_dl_runtime_resolve)
+		got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk;
+	    }
+	}
+    }
+}
+#endif

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

commit 0546542b6af7d6a59df979e94fa34049b2be8583
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Jun 22 04:15:39 2017 -0700

    x86: Support IBT and SHSTK from Intel CET
    
    Intel Control-flow Enforcement Technology (CET) instructions:
    
    https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-en
    forcement-technology-preview.pdf
    
    includes Indirect Branch Tracking (IBT) and Shadow Stack (SHSTK).
    
    GNU_PROPERTY_X86_FEATURE_1_IBT is added to GNU program property to
    indicate that all executable sections are compatible with IBT when
    ENDBR instruction starts each valid target where an indirect branch
    instruction can land.  GNU_PROPERTY_X86_FEATURE_1_IBT is set on output
    only if it is set on all relocatable inputs.
    
    On an IBT capable processor, the following steps should be taken:
    
    1. When loading an executable, if GNU_PROPERTY_X86_FEATURE_1_IBT is
    set on the executable, enable IBT.
    2. If IBT is enabled, when loading a shared object without
    GNU_PROPERTY_X86_FEATURE_1_IBT:
      a. If legacy interwork is allowed, then mark all pages in executable
         PT_LOAD segments in legacy code page bitmap.  Failure of legacy code
         page bitmap allocation causes an error.
      b. If legacy interwork isn't allowed, it causes an error.
    
    GNU_PROPERTY_X86_FEATURE_1_SHSTK is added to GNU program property to
    indicate that all executable sections are compatible with SHSTK where
    return address popped from shadow stack always matches return address
    popped from normal stack.  GNU_PROPERTY_X86_FEATURE_1_SHSTK is set on
    output only if it is set on all relocatable inputs.
    
    On a SHSTK capable processor, the following steps should be taken:
    
    1. When loading an executable, if GNU_PROPERTY_X86_FEATURE_1_SHSTK is
    set on the executable as well as all shared objects loaded via the
    DT_NEEDED tag, enable SHSTK.
    2. After SHSTK is enabled, it is an error to load a shared object
    without GNU_PROPERTY_X86_FEATURE_1_SHSTK.
    
    When glibc is built with a compiler which defines defines__IBT__ and
    __SHSTK__, CET is enabled, unless --disable-cet is used to configure
    glibc.  When CET is enabled, both compiler and assembler must support
    CET.  Otherwise, it is a configure-time error.
    
    To support CET run-time control,
    
    1. _dl_x86_feature_1 is added to the writable ld.so namespace to indicate
    if IBT or SHSTK are enabled at run-time.
    2. For dynamic executables:
       a. A l_cet field is added to struct link_map to indicate if IBT or
          SHSTK is enabled in an ELF module.  The optional DL_PROCESS_PT_NOTE
          is called to process PT_NOTE segment for GNU program property and
          set l_cet.
       b. _dl_start_user calls _dl_cet_init, instead of _dl_init, which sets
         _dl_x86_feature_1 as well as sets up IBT and SHSTK.
    3. For static executables, _dl_setup_cet is called to process PT_NOTE
    segment for GNU program property to set _dl_x86_feature_1 as well as set
    up IBT and SHSTK.
    
    <sys/cet.h> is added so that it can be included by assembly codes to
    add GNU_PROPERTY_X86_FEATURE_1_IBT and GNU_PROPERTY_X86_FEATURE_1_SHSTK
    to GNU program property if __IBT__ or __SHSTK__ is defined.
    
    	* config.h.in (ENABLE_CET): New #undef.
    	* configure.ac: Add --enable-cet.
    	* configure: Regenerated.
    	* elf/dl-load.c (filebuf): Moved before "dynamic-link.h".
    	(_dl_map_object_from_fd): Call DL_PROCESS_PT_NOTE on PT_NOTE
    	segment if DL_PROCESS_PT_NOTE is defined.
    	* elf/rtld.c (dl_main): Likewise.
    	* elf/dl-support.c: Include <dl-procruntime.c>.
    	* include/link.h: Include <link_map.h>.
    	* sysdeps/generic/dl-procruntime.c: New file.
    	* sysdeps/generic/link_map.h: Likewise.
    	* sysdeps/unix/sysv/linux/i386/dl-machine.h: Likewise.
    	* sysdeps/unix/sysv/linux/x86/configure: Likewise.
    	* sysdeps/unix/sysv/linux/x86/configure.ac: Likewise.
    	* sysdeps/unix/sysv/linux/x86/dl-cet-nonshared.c: Likewise.
    	* sysdeps/unix/sysv/linux/x86/dl-cet.c: Likewise.
    	* sysdeps/unix/sysv/linux/x86/dl-cet.h: Likewise.
    	* sysdeps/unix/sysv/linux/x86/dl-procruntime.c: Likewise.
    	* sysdeps/unix/sysv/linux/x86/libc-start.c: Likewise.
    	* sysdeps/unix/sysv/linux/x86/link_map.h: Likewise.
    	* sysdeps/unix/sysv/linux/x86/sys/cet.h: Likewise.
    	* sysdeps/unix/sysv/linux/x86_64/dl-machine.h: Likewise.
    	* sysdeps/generic/ldsodefs.h: Include <dl-procruntime.c> in
    	the writable ld.so namespace.
    	* sysdeps/i386/dl-machine.h (DL_INIT): New.
    	(_dl_start_user): Replace _dl_init with DL_INIT.
    	* sysdeps/unix/sysv/linux/x86/Makefile (sysdep_routines): Add
    	dl-cet-nonshared if CET is enabled.
    	(sysdep-dl-routines): Add dl-cet if CET is enabled.
    	(sysdep_headers): Add sys/cet.h if CET is enabled.
    	(asm-CPPFLAGS): Include sysdeps/unix/sysv/linux/x86/sys/cet.h
    	if CET is enabled.
    	* sysdeps/x86/libc-start.c (ARCH_INIT_CPU_FEATURES): Define
    	only if it is undefined.
    	* sysdeps/x86_64/dl-machine.h (DL_INIT): New.
    	(_dl_start_user): Replace _dl_init with DL_INIT.

diff --git a/config.h.in b/config.h.in
index 989554a..d7fe802 100644
--- a/config.h.in
+++ b/config.h.in
@@ -136,6 +136,10 @@
 /* Define if lock elision should be enabled by default.  */
 #undef ENABLE_LOCK_ELISION
 
+/* Define if Intel Control-flow Enforcement Technology (CET) should be
+   enabled.  */
+#undef ENABLE_CET
+
 /* Package description.  */
 #undef PKGVERSION
 
diff --git a/configure b/configure
index 8e5c5bd..f9373c9 100755
--- a/configure
+++ b/configure
@@ -788,6 +788,7 @@ enable_nscd
 enable_pt_chown
 enable_tunables
 enable_mathvec
+enable_cet
 with_cpu
 '
       ac_precious_vars='build_alias
@@ -1463,6 +1464,8 @@ Optional Features:
                           'no' and 'valstring'
   --enable-mathvec        Enable building and installing mathvec [default
                           depends on architecture]
+  --enable-cet            enable Intel Control-flow Enforcement Technology
+                          (CET), x86 only
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -3754,6 +3757,14 @@ else
 fi
 
 
+# Check whether --enable-cet was given.
+if test "${enable_cet+set}" = set; then :
+  enableval=$enable_cet; enable_cet=$enableval
+else
+  enable_cet=default
+fi
+
+
 # We keep the original values in `$config_*' and never modify them, so we
 # can write them unchanged into config.make.  Everything else uses
 # $machine, $vendor, and $os, and changes them whenever convenient.
diff --git a/configure.ac b/configure.ac
index 7e03019..9a65401 100644
--- a/configure.ac
+++ b/configure.ac
@@ -460,6 +460,12 @@ AC_ARG_ENABLE([mathvec],
 	      [build_mathvec=$enableval],
 	      [build_mathvec=notset])
 
+AC_ARG_ENABLE([cet],
+	      AC_HELP_STRING([--enable-cet],
+			     [enable Intel Control-flow Enforcement Technology (CET), x86 only]),
+	      [enable_cet=$enableval],
+	      [enable_cet=default])
+
 # We keep the original values in `$config_*' and never modify them, so we
 # can write them unchanged into config.make.  Everything else uses
 # $machine, $vendor, and $os, and changes them whenever convenient.
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 14cf164..ea31214 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -30,6 +30,32 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+
+/* Type for the buffer we put the ELF header and hopefully the program
+   header.  This buffer does not really have to be too large.  In most
+   cases the program header follows the ELF header directly.  If this
+   is not the case all bets are off and we can make the header
+   arbitrarily large and still won't get it read.  This means the only
+   question is how large are the ELF and program header combined.  The
+   ELF header 32-bit files is 52 bytes long and in 64-bit files is 64
+   bytes long.  Each program header entry is again 32 and 56 bytes
+   long respectively.  I.e., even with a file which has 10 program
+   header entries we only have to read 372B/624B respectively.  Add to
+   this a bit of margin for program notes and reading 512B and 832B
+   for 32-bit and 64-bit files respecitvely is enough.  If this
+   heuristic should really fail for some file the code in
+   `_dl_map_object_from_fd' knows how to recover.  */
+struct filebuf
+{
+  ssize_t len;
+#if __WORDSIZE == 32
+# define FILEBUF_SIZE 512
+#else
+# define FILEBUF_SIZE 832
+#endif
+  char buf[FILEBUF_SIZE] __attribute__ ((aligned (__alignof (ElfW(Ehdr)))));
+};
+
 #include "dynamic-link.h"
 #include <abi-tag.h>
 #include <stackinfo.h>
@@ -69,31 +95,6 @@ int __stack_prot attribute_hidden attribute_relro
 #endif
 
 
-/* Type for the buffer we put the ELF header and hopefully the program
-   header.  This buffer does not really have to be too large.  In most
-   cases the program header follows the ELF header directly.  If this
-   is not the case all bets are off and we can make the header
-   arbitrarily large and still won't get it read.  This means the only
-   question is how large are the ELF and program header combined.  The
-   ELF header 32-bit files is 52 bytes long and in 64-bit files is 64
-   bytes long.  Each program header entry is again 32 and 56 bytes
-   long respectively.  I.e., even with a file which has 10 program
-   header entries we only have to read 372B/624B respectively.  Add to
-   this a bit of margin for program notes and reading 512B and 832B
-   for 32-bit and 64-bit files respecitvely is enough.  If this
-   heuristic should really fail for some file the code in
-   `_dl_map_object_from_fd' knows how to recover.  */
-struct filebuf
-{
-  ssize_t len;
-#if __WORDSIZE == 32
-# define FILEBUF_SIZE 512
-#else
-# define FILEBUF_SIZE 832
-#endif
-  char buf[FILEBUF_SIZE] __attribute__ ((aligned (__alignof (ElfW(Ehdr)))));
-};
-
 /* This is the decomposed LD_LIBRARY_PATH search path.  */
 static struct r_search_path_struct env_path_list attribute_relro;
 
@@ -1153,6 +1154,12 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
 	  l->l_relro_addr = ph->p_vaddr;
 	  l->l_relro_size = ph->p_memsz;
 	  break;
+
+#ifdef DL_PROCESS_PT_NOTE
+	case PT_NOTE:
+	  DL_PROCESS_PT_NOTE (l, ph, fd, fbp);
+	  break;
+#endif
 	}
 
     if (__glibc_unlikely (nloadcmds == 0))
diff --git a/elf/dl-support.c b/elf/dl-support.c
index b98cc4e..7e30e04 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -126,6 +126,7 @@ int _dl_starting_up = 1;
 void *_dl_random;
 
 /* Get architecture specific initializer.  */
+#include <dl-procruntime.c>
 #include <dl-procinfo.c>
 
 /* Initial value of the CPU clock.  */
diff --git a/elf/rtld.c b/elf/rtld.c
index 65647fb..05c87ee 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1240,6 +1240,12 @@ of this helper program; chances are you did not intend to run this program.\n\
 	main_map->l_relro_addr = ph->p_vaddr;
 	main_map->l_relro_size = ph->p_memsz;
 	break;
+
+#ifdef DL_PROCESS_PT_NOTE
+      case PT_NOTE:
+	DL_PROCESS_PT_NOTE (main_map, ph);
+	break;
+#endif
       }
 
   /* Adjust the address of the TLS initialization image in case
diff --git a/include/link.h b/include/link.h
index eeb5f4d..74548a1 100644
--- a/include/link.h
+++ b/include/link.h
@@ -203,6 +203,8 @@ struct link_map
 				       freed, ie. not allocated with
 				       the dummy malloc in ld.so.  */
 
+#include <link_map.h>
+
     /* Collected information about own RPATH directories.  */
     struct r_search_path_struct l_rpath_dirs;
 
diff --git a/sysdeps/generic/dl-procruntime.c b/sysdeps/generic/dl-procruntime.c
new file mode 100644
index 0000000..a056184
--- /dev/null
+++ b/sysdeps/generic/dl-procruntime.c
@@ -0,0 +1 @@
+/* No architecture specific definitions.  */
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 3c7ebd1..037b1b1 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -374,6 +374,13 @@ struct rtld_global
   EXTERN void (*_dl_rtld_unlock_recursive) (void *);
 #endif
 
+  /* Get architecture specific definitions.  */
+#define PROCINFO_DECL
+#ifndef PROCINFO_CLASS
+# define PROCINFO_CLASS EXTERN
+#endif
+#include <dl-procruntime.c>
+
   /* If loading a shared object requires that we make the stack executable
      when it was not, we do it by calling this function.
      It returns an errno code or zero on success.  */
@@ -530,10 +537,6 @@ struct rtld_global_ro
 #endif
 
   /* Get architecture specific definitions.  */
-#define PROCINFO_DECL
-#ifndef PROCINFO_CLASS
-# define PROCINFO_CLASS EXTERN
-#endif
 #include <dl-procinfo.c>
 
   /* Names of shared object for which the RPATH should be ignored.  */
diff --git a/sysdeps/generic/link_map.h b/sysdeps/generic/link_map.h
new file mode 100644
index 0000000..a056184
--- /dev/null
+++ b/sysdeps/generic/link_map.h
@@ -0,0 +1 @@
+/* No architecture specific definitions.  */
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index 9ee9d02..8ef067d 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -137,6 +137,10 @@ extern ElfW(Addr) _dl_profile_fixup (struct link_map *l,
    where the dynamic linker should not map anything.  */
 #define ELF_MACHINE_USER_ADDRESS_MASK	0xf8000000UL
 
+#ifndef DL_INIT
+# define DL_INIT	"_dl_init"
+#endif
+
 /* Initial entry point code for the dynamic linker.
    The C function `_dl_start' is the real entry point;
    its return value is the user program's entry point.  */
@@ -189,7 +193,7 @@ _dl_start_user:\n\
 	# Clear %ebp, so that even constructors have terminated backchain.\n\
 	xorl %ebp, %ebp\n\
 	# Call the function to run the initializers.\n\
-	call _dl_init\n\
+	call " DL_INIT "\n\
 	# Pass our finalizer function to the user in %edx, as per ELF ABI.\n\
 	leal _dl_fini@GOTOFF(%ebx), %edx\n\
 	# Restore %esp _start expects.\n\
diff --git a/sysdeps/x86/libc-start.c b/sysdeps/unix/sysv/linux/i386/dl-machine.h
similarity index 70%
copy from sysdeps/x86/libc-start.c
copy to sysdeps/unix/sysv/linux/i386/dl-machine.h
index e11b490..303358f 100644
--- a/sysdeps/x86/libc-start.c
+++ b/sysdeps/unix/sysv/linux/i386/dl-machine.h
@@ -1,4 +1,6 @@
-/* Copyright (C) 2015-2017 Free Software Foundation, Inc.
+/* Machine-dependent ELF dynamic relocation inline functions.
+   Linux/i386 version.
+   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
@@ -15,14 +17,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifndef SHARED
-#include <ldsodefs.h>
-# include <cpu-features.h>
-# include <cpu-features.c>
-
-extern struct cpu_features _dl_x86_cpu_features;
-
-#define ARCH_INIT_CPU_FEATURES() init_cpu_features (&_dl_x86_cpu_features)
-
+#ifdef ENABLE_CET
+# include <sysdeps/unix/sysv/linux/x86/dl-cet.h>
 #endif
-# include <csu/libc-start.c>
+#include <sysdeps/i386/dl-machine.h>
diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
index 9e6ec44..6a0a959 100644
--- a/sysdeps/unix/sysv/linux/x86/Makefile
+++ b/sysdeps/unix/sysv/linux/x86/Makefile
@@ -22,3 +22,16 @@ endif
 ifeq ($(subdir),elf)
 sysdep_routines += dl-vdso
 endif
+
+ifeq ($(enable-cet),yes)
+ifeq ($(subdir),elf)
+sysdep_routines += dl-cet-nonshared
+sysdep-dl-routines += dl-cet
+endif
+
+# Make <sys/cet.h> available to all assembly codes.
+sysdep_headers += sys/cet.h
+
+# Compile assembly codes with <sys/cet.h> if CET is enabled.
+asm-CPPFLAGS += -include $(..)sysdeps/unix/sysv/linux/x86/sys/cet.h
+endif
diff --git a/sysdeps/unix/sysv/linux/x86/configure b/sysdeps/unix/sysv/linux/x86/configure
new file mode 100644
index 0000000..13873fd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/configure
@@ -0,0 +1,74 @@
+# This file is generated from configure.ac by Autoconf.  DO NOT EDIT!
+ # Local configure fragment for sysdeps/unix/sysv/linux/x86.
+
+if test x"$enable_cet" = xdefault || test x"$enable_cet" = xyes; then
+  # See whether CET is default.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CET is default" >&5
+$as_echo_n "checking whether CET is default... " >&6; }
+if ${libc_cv_x86_cet_default+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.c <<EOF
+#if !defined __IBT__ || !defined __SHSTK__
+# error CET isn't enabled.
+#endif
+EOF
+		 if { ac_try='${CC-cc} -S $CFLAGS conftest.c -o 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_x86_cet_default=yes
+		 else
+		   libc_cv_x86_cet_default=no
+		 fi
+		 rm -rf conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_cet_default" >&5
+$as_echo "$libc_cv_x86_cet_default" >&6; }
+  if test $libc_cv_x86_cet_default = yes; then
+    if test x"$enable_cet" = xdefault; then
+      enable_cet=yes
+    fi
+  else
+    if test x"$enable_cet" = xdefault; then
+      enable_cet=no
+    else
+      as_fn_error $? "$CC doesn't default to CET" "$LINENO" 5
+    fi
+  fi
+fi
+if test $enable_cet = yes; then
+  # Check if assembler supports CET.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $AS supports CET" >&5
+$as_echo_n "checking whether $AS supports CET... " >&6; }
+if ${libc_cv_x86_cet_as+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.s <<EOF
+	incsspd %ecx
+EOF
+		 if { ac_try='${CC-cc} -c $CFLAGS conftest.s -o conftest.o 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_x86_cet_as=yes
+		 else
+		   libc_cv_x86_cet_as=no
+		 fi
+		 rm -rf conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_cet_as" >&5
+$as_echo "$libc_cv_x86_cet_as" >&6; }
+  if test $libc_cv_x86_cet_as = no; then
+    as_fn_error $? "$AS doesn't support CET" "$LINENO" 5
+  fi
+
+$as_echo "#define ENABLE_CET 1" >>confdefs.h
+
+fi
+config_vars="$config_vars
+enable-cet = $enable_cet"
diff --git a/sysdeps/unix/sysv/linux/x86/configure.ac b/sysdeps/unix/sysv/linux/x86/configure.ac
new file mode 100644
index 0000000..8c8fe18
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/configure.ac
@@ -0,0 +1,50 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/unix/sysv/linux/x86.
+
+if test x"$enable_cet" = xdefault || test x"$enable_cet" = xyes; then
+  # See whether CET is default.
+  AC_CACHE_CHECK(whether CET is default,
+		 libc_cv_x86_cet_default, [dnl
+cat > conftest.c <<EOF
+#if !defined __IBT__ || !defined __SHSTK__
+# error CET isn't enabled.
+#endif
+EOF
+		 if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+		   libc_cv_x86_cet_default=yes
+		 else
+		   libc_cv_x86_cet_default=no
+		 fi
+		 rm -rf conftest*])
+  if test $libc_cv_x86_cet_default = yes; then
+    if test x"$enable_cet" = xdefault; then
+      enable_cet=yes
+    fi
+  else
+    if test x"$enable_cet" = xdefault; then
+      enable_cet=no
+    else
+      AC_MSG_ERROR([$CC doesn't default to CET])
+    fi
+  fi
+fi
+if test $enable_cet = yes; then
+  # Check if assembler supports CET.
+  AC_CACHE_CHECK(whether $AS supports CET,
+		 libc_cv_x86_cet_as, [dnl
+cat > conftest.s <<EOF
+	incsspd %ecx
+EOF
+		 if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s -o conftest.o 1>&AS_MESSAGE_LOG_FD); then
+		   libc_cv_x86_cet_as=yes
+		 else
+		   libc_cv_x86_cet_as=no
+		 fi
+		 rm -rf conftest*])
+  if test $libc_cv_x86_cet_as = no; then
+    AC_MSG_ERROR([$AS doesn't support CET])
+  fi
+  AC_DEFINE(ENABLE_CET, 1,
+	    [Enable Intel Control-flow Enforcement Technology (CET)])
+fi
+LIBC_CONFIG_VAR([enable-cet], [$enable_cet])
diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet-nonshared.c b/sysdeps/unix/sysv/linux/x86/dl-cet-nonshared.c
new file mode 100644
index 0000000..570c0a3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/dl-cet-nonshared.c
@@ -0,0 +1,104 @@
+/* Linux/x86 CET setup function for static executable.
+   This file is part of the GNU C Library.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   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/>.  */
+
+
+#ifndef SHARED
+# include <link.h>
+# include <ldsodefs.h>
+# include "dl-cet.h"
+
+/* Set up IBT and SHSTK for static executable.   */
+
+void
+internal_function
+_dl_setup_cet (const ElfW(Phdr) *phdr, size_t phnum,
+	       const ElfW(Addr) addr)
+{
+  const struct cpu_features *cpu_features = __get_cpu_features ();
+  size_t i;
+
+  for (i = 0; i < phnum; i++)
+    if (phdr[i].p_type == PT_NOTE)
+      {
+	const ElfW(Addr) start = phdr[i].p_vaddr + addr;
+	const ElfW(Nhdr) *note = (const void *) start;
+
+	while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
+	  {
+	    /* Find the NT_GNU_PROPERTY_TYPE_0 note.  */
+	    if (note->n_namesz == 4
+		&& note->n_type == NT_GNU_PROPERTY_TYPE_0
+		&& memcmp (note + 1, "GNU", 4) == 0)
+	      {
+		/* Check for invalid property.  */
+		if (note->n_descsz < 8
+		    || (note->n_descsz % sizeof (ElfW(Addr))) != 0)
+		  break;
+
+		/* Start and end of property array.  */
+		unsigned char *ptr = (unsigned char *) (note + 1) + 4;
+		unsigned char *ptr_end = ptr + note->n_descsz;
+
+		while (1)
+		  {
+		    unsigned int type = *(unsigned int *) ptr;
+		    unsigned int datasz = *(unsigned int *) (ptr + 4);
+
+		    ptr += 8;
+		    if ((ptr + datasz) > ptr_end)
+		      break;
+
+		    if (type == GNU_PROPERTY_X86_FEATURE_1_AND
+			&& datasz == 4)
+		      {
+			unsigned int feature_1 = ptr[0];
+
+			if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT))
+			  {
+			    if (CPU_FEATURES_CPU_P (cpu_features, IBT))
+			      {
+				/* FIXME: Set up IBT.  */
+			      }
+			    else
+			      /* Disable IBT.  */
+			      feature_1 &= ~GNU_PROPERTY_X86_FEATURE_1_IBT;
+			  }
+
+			if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
+			  {
+			    if (CPU_FEATURES_CPU_P (cpu_features, SHSTK))
+			      {
+				/* FIXME: Set up SHSTK.  */
+			      }
+			    else
+			      /* Disable SHSTK.  */
+			      feature_1 &= ~GNU_PROPERTY_X86_FEATURE_1_SHSTK;
+			  }
+
+			GL(dl_x86_feature_1) = feature_1;
+			return;
+		      }
+		  }
+	      }
+	    note = ((const void *) (note + 1)
+		    + ROUND_NOTE (note->n_namesz)
+		    + ROUND_NOTE (note->n_descsz));
+	  }
+      }
+}
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.c b/sysdeps/unix/sysv/linux/x86/dl-cet.c
new file mode 100644
index 0000000..cac8fa1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/dl-cet.c
@@ -0,0 +1,87 @@
+/* Linux/x86 CET initializers function.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   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/>.  */
+
+#ifdef SHARED
+# include <ldsodefs.h>
+
+# ifndef LINKAGE
+#  define LINKAGE
+# endif
+
+LINKAGE
+void
+internal_function
+_dl_cet_init (struct link_map *main_map, int argc, char **argv, char **env)
+{
+  const struct cpu_features *cpu_features = __get_cpu_features ();
+
+  /* Enable IBT if if it is enabled in executable.  */
+  bool enable_ibt = (CPU_FEATURES_CPU_P (cpu_features, IBT)
+		     && (main_map->l_cet & lc_ibt));
+  if (enable_ibt)
+    {
+      /* Enable IBT.  */
+      GL(dl_x86_feature_1) |= GNU_PROPERTY_X86_FEATURE_1_IBT;
+
+      /* FIXME: Enable IBT.  */
+    }
+
+  /* Enable SHSTK only if it is enabled in executable.  */
+  bool enable_shstk = (CPU_FEATURES_CPU_P (cpu_features, SHSTK)
+		       && (main_map->l_cet & lc_shstk));
+
+  if (enable_ibt || enable_shstk)
+    {
+      unsigned int i;
+      struct link_map *l;
+
+      i = main_map->l_searchlist.r_nlist;
+      while (i-- > 0)
+	{
+	  /* Check each shared object to see if IBT and SHSTK are
+	     enabled.  */
+	  l = main_map->l_initfini[i];
+	  if (enable_ibt && !(l->l_cet & lc_ibt))
+	    {
+	      /* FIXME: Put all PT_LOAD segments in legacy code page
+		 bitmap.  */
+	      ;
+	    }
+
+	  /* SHSTK is enabled only if it is enabled in executable as
+	     well as all shared objects.  */
+	  enable_shstk = !!(l->l_cet & lc_shstk);
+
+	  /* Stop if both IBT and SHSTCK are disabled.  */
+	  if (!enable_ibt && !enable_shstk)
+	    break;
+	}
+    }
+
+  if (enable_shstk)
+    {
+      /* Enable SHSTK.  */
+      GL(dl_x86_feature_1) |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
+
+      /* FIXME: Set up SHSTK.  */
+    }
+
+  /* FIXME: We must handle dlopened shared objects.  */
+
+  _dl_init (main_map, argc, argv, env);
+}
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h
new file mode 100644
index 0000000..1b4b866
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h
@@ -0,0 +1,121 @@
+/* Linux/x86 CET inline functions.
+   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/>.  */
+
+#ifndef _dl_cet_h
+#define _dl_cet_h
+
+extern void _dl_cet_init (struct link_map *, int, char **, char **)
+    internal_function attribute_hidden;
+
+#define DL_INIT "_dl_cet_init"
+
+/* Note sections like .note.ABI-tag and .note.gnu.build-id are aligned
+   to 4 bytes in 64-bit ELF objects.  */
+#define ROUND_NOTE(len) \
+  (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
+
+#ifdef ElfW
+static inline void __attribute__ ((unused))
+dl_process_cet_property_note (struct link_map *l,
+			      const ElfW(Nhdr) *note,
+			      ElfW(Addr) size)
+{
+  const ElfW(Addr) start = (ElfW(Addr)) note;
+
+  while ((ElfW(Addr)) (note + 1) - start < size)
+    {
+      /* Find the NT_GNU_PROPERTY_TYPE_0 note.  */
+      if (note->n_namesz == 4
+	  && note->n_type == NT_GNU_PROPERTY_TYPE_0
+	  && memcmp (note + 1, "GNU", 4) == 0)
+	{
+	  /* Check for invalid property.  */
+	  if (note->n_descsz < 8
+	      || (note->n_descsz % sizeof (ElfW(Addr))) != 0)
+	    break;
+
+	  /* Start and end of property array.  */
+	  unsigned char *ptr = (unsigned char *) (note + 1) + 4;
+	  unsigned char *ptr_end = ptr + note->n_descsz;
+
+	  while (1)
+	    {
+	      unsigned int type = *(unsigned int *) ptr;
+	      unsigned int datasz = *(unsigned int *) (ptr + 4);
+
+	      ptr += 8;
+	      if ((ptr + datasz) > ptr_end)
+		break;
+
+	      if (type == GNU_PROPERTY_X86_FEATURE_1_AND
+		  && datasz == 4)
+		{
+		  unsigned int feature_1 = ptr[0];
+		  if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT))
+		    l->l_cet |= lc_ibt;
+		  if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
+		    l->l_cet |= lc_shstk;
+		  return;
+		}
+	    }
+	}
+
+      /* Note sections like .note.ABI-tag and .note.gnu.build-id are
+       * aligned to 4 bytes in 64-bit ELF objects.  */
+      note = ((const void *) (note + 1)
+	      + ROUND_NOTE (note->n_namesz)
+	      + ROUND_NOTE (note->n_descsz));
+    }
+}
+
+# ifdef FILEBUF_SIZE
+#  define DL_PROCESS_PT_NOTE(l, ph, fd, fbp) \
+  dl_process_pt_note ((l), (ph), (fd), (fbp))
+
+static inline void __attribute__ ((unused))
+dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph,
+		    int fd, struct filebuf *fbp)
+{
+  const ElfW(Nhdr) *note;
+  ElfW(Addr) size = ph->p_filesz;
+
+  if (ph->p_offset + size <= (size_t) fbp->len)
+    note = (const void *) (fbp->buf + ph->p_offset);
+  else
+    {
+      note = alloca (size);
+      __lseek (fd, ph->p_offset, SEEK_SET);
+      if (__libc_read (fd, (void *) note, size) != size)
+	return;
+    }
+
+  dl_process_cet_property_note (l, note, size);
+}
+# else
+#  define DL_PROCESS_PT_NOTE(l, ph) dl_process_pt_note ((l), (ph))
+
+static inline void __attribute__ ((unused))
+dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph)
+{
+  const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr);
+  dl_process_cet_property_note (l, note, ph->p_memsz);
+}
+# endif
+#endif
+
+#endif	/* _dl_cet_h */
diff --git a/sysdeps/unix/sysv/linux/x86/dl-procruntime.c b/sysdeps/unix/sysv/linux/x86/dl-procruntime.c
new file mode 100644
index 0000000..17c3546
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/dl-procruntime.c
@@ -0,0 +1,57 @@
+/* Data for processor runtime information.  Linux/x86 version.
+   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/>.  */
+
+/* This information must be kept in sync with the _DL_HWCAP_COUNT,
+   HWCAP_PLATFORMS_START and HWCAP_PLATFORMS_COUNT definitions in
+   dl-hwcap.h.
+
+   If anything should be added here check whether the size of each string
+   is still ok with the given array size.
+
+   All the #ifdefs in the definitions are quite irritating but
+   necessary if we want to avoid duplicating the information.  There
+   are three different modes:
+
+   - PROCINFO_DECL is defined.  This means we are only interested in
+     declarations.
+
+   - PROCINFO_DECL is not defined:
+
+     + if SHARED is defined the file is included in an array
+       initializer.  The .element = { ... } syntax is needed.
+
+     + if SHARED is not defined a normal array initialization is
+       needed.
+  */
+
+#ifndef PROCINFO_CLASS
+# define PROCINFO_CLASS
+#endif
+
+#if !IS_IN (ldconfig)
+# if !defined PROCINFO_DECL && defined SHARED
+  ._dl_x86_feature_1
+# else
+PROCINFO_CLASS unsigned int _dl_x86_feature_1
+# endif
+# if !defined SHARED || defined PROCINFO_DECL
+;
+# else
+,
+# endif
+#endif
diff --git a/sysdeps/x86/libc-start.c b/sysdeps/unix/sysv/linux/x86/libc-start.c
similarity index 70%
copy from sysdeps/x86/libc-start.c
copy to sysdeps/unix/sysv/linux/x86/libc-start.c
index e11b490..16832f6 100644
--- a/sysdeps/x86/libc-start.c
+++ b/sysdeps/unix/sysv/linux/x86/libc-start.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Free Software Foundation, Inc.
+/* 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
@@ -15,14 +15,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifndef SHARED
-#include <ldsodefs.h>
-# include <cpu-features.h>
-# include <cpu-features.c>
-
-extern struct cpu_features _dl_x86_cpu_features;
-
-#define ARCH_INIT_CPU_FEATURES() init_cpu_features (&_dl_x86_cpu_features)
-
+#ifdef ENABLE_CET
+# include <link.h>
+# define ARCH_INIT_CPU_FEATURES() \
+  {								\
+    init_cpu_features (&_dl_x86_cpu_features);			\
+    _dl_setup_cet (_dl_phdr, _dl_phnum, 0);			\
+  }
 #endif
-# include <csu/libc-start.c>
+
+#include <sysdeps/x86/libc-start.c>
diff --git a/sysdeps/x86/libc-start.c b/sysdeps/unix/sysv/linux/x86/link_map.h
similarity index 64%
copy from sysdeps/x86/libc-start.c
copy to sysdeps/unix/sysv/linux/x86/link_map.h
index e11b490..86e098e 100644
--- a/sysdeps/x86/libc-start.c
+++ b/sysdeps/unix/sysv/linux/x86/link_map.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2015-2017 Free Software Foundation, Inc.
+/* Additional fields in struct link_map.  Linux/x86 version.
+   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
@@ -15,14 +16,11 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifndef SHARED
-#include <ldsodefs.h>
-# include <cpu-features.h>
-# include <cpu-features.c>
-
-extern struct cpu_features _dl_x86_cpu_features;
-
-#define ARCH_INIT_CPU_FEATURES() init_cpu_features (&_dl_x86_cpu_features)
-
-#endif
-# include <csu/libc-start.c>
+/* If this object is enabled with CET.  */
+enum
+  {
+    lc_none = 0,			 /* Not enabled with CET.  */
+    lc_ibt = 1 << 0,			 /* Enabled with IBT.  */
+    lc_shstk = 1 << 1,			 /* Enabled with STSHK.  */
+    lc_ibt_and_shstk = lc_ibt | lc_shstk /* Enabled with both.  */
+  } l_cet:2;
diff --git a/sysdeps/unix/sysv/linux/x86/sys/cet.h b/sysdeps/unix/sysv/linux/x86/sys/cet.h
new file mode 100644
index 0000000..9b0bf04
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/sys/cet.h
@@ -0,0 +1,82 @@
+/* ELF program property for Intel CET.
+   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/>.  */
+
+#ifndef _SYS_CET_H
+#define _SYS_CET_H	1
+
+/* Add x86 feature with IBT and/or SHSTK bits to ELF program property
+   if they are enabled.  Otherwise, contents in this header file are
+   unused.  */
+
+# ifdef __ASSEMBLER__
+
+#  ifdef __LP64__
+#   define __PROPERTY_ALIGN 3
+#  else
+#   define __PROPERTY_ALIGN 2
+#  endif
+
+#  ifdef __IBT__
+	.pushsection ".note.gnu.property", "a"
+	.p2align __PROPERTY_ALIGN
+	.long 1f - 0f		/* name length.  */
+	.long 4f - 1f		/* data length.  */
+	/* NT_GNU_PROPERTY_TYPE_0.   */
+	.long 5			/* note type.  */
+0:
+	.asciz "GNU"		/* vendor name.  */
+1:
+	.p2align __PROPERTY_ALIGN
+	/* GNU_PROPERTY_X86_FEATURE_1_AND.  */
+	.long 0xc0000002	/* pr_type.  */
+	.long 3f - 2f		/* pr_datasz.  */
+2:
+	/* GNU_PROPERTY_X86_FEATURE_1_IBT.  */
+	.long 0x1
+3:
+	.p2align __PROPERTY_ALIGN
+4:
+	.popsection
+#  endif
+
+#  ifdef __SHSTK__
+	.pushsection ".note.gnu.property", "a"
+	.p2align __PROPERTY_ALIGN
+	.long 1f - 0f		/* name length.  */
+	.long 4f - 1f		/* data length.  */
+	/* NT_GNU_PROPERTY_TYPE_0.   */
+	.long 5			/* note type.  */
+0:
+	.asciz "GNU"		/* vendor name.  */
+1:
+	.p2align __PROPERTY_ALIGN
+	/* GNU_PROPERTY_X86_FEATURE_1_AND.  */
+	.long 0xc0000002	/* pr_type.  */
+	.long 3f - 2f		/* pr_datasz.  */
+2:
+	/* GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
+	.long 0x2
+3:
+	.p2align __PROPERTY_ALIGN
+4:
+	.popsection
+#  endif
+
+# endif
+
+#endif	/* _SYS_CET_H */
diff --git a/sysdeps/x86/libc-start.c b/sysdeps/unix/sysv/linux/x86_64/dl-machine.h
similarity index 70%
copy from sysdeps/x86/libc-start.c
copy to sysdeps/unix/sysv/linux/x86_64/dl-machine.h
index e11b490..c2d7cae 100644
--- a/sysdeps/x86/libc-start.c
+++ b/sysdeps/unix/sysv/linux/x86_64/dl-machine.h
@@ -1,4 +1,6 @@
-/* Copyright (C) 2015-2017 Free Software Foundation, Inc.
+/* Machine-dependent ELF dynamic relocation inline functions.
+   Linux/x86-64 version.
+   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
@@ -15,14 +17,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifndef SHARED
-#include <ldsodefs.h>
-# include <cpu-features.h>
-# include <cpu-features.c>
-
-extern struct cpu_features _dl_x86_cpu_features;
-
-#define ARCH_INIT_CPU_FEATURES() init_cpu_features (&_dl_x86_cpu_features)
-
+#ifdef ENABLE_CET
+# include <sysdeps/unix/sysv/linux/x86/dl-cet.h>
 #endif
-# include <csu/libc-start.c>
+#include <sysdeps/x86_64/dl-machine.h>
diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h
index 6bf7cb0..69e171a 100644
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -234,6 +234,11 @@ struct cpu_features
 extern const struct cpu_features *__get_cpu_features (void)
      __attribute__ ((const));
 
+# ifdef ElfW
+extern void _dl_setup_cet (const ElfW(Phdr) *, size_t, const ElfW(Addr))
+    internal_function attribute_hidden;
+# endif
+
 # if defined (_LIBC) && !IS_IN (nonlib)
 /* Unused for x86.  */
 #  define INIT_ARCH()
diff --git a/sysdeps/x86/libc-start.c b/sysdeps/x86/libc-start.c
index e11b490..bcd6002 100644
--- a/sysdeps/x86/libc-start.c
+++ b/sysdeps/x86/libc-start.c
@@ -16,13 +16,16 @@
    <http://www.gnu.org/licenses/>.  */
 
 #ifndef SHARED
-#include <ldsodefs.h>
+# include <ldsodefs.h>
 # include <cpu-features.h>
 # include <cpu-features.c>
 
 extern struct cpu_features _dl_x86_cpu_features;
 
-#define ARCH_INIT_CPU_FEATURES() init_cpu_features (&_dl_x86_cpu_features)
-
+# ifndef ARCH_INIT_CPU_FEATURES
+#  define ARCH_INIT_CPU_FEATURES() \
+  init_cpu_features (&_dl_x86_cpu_features)
+# endif
 #endif
-# include <csu/libc-start.c>
+
+#include <csu/libc-start.c>
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index 6a04cbc..91d11af 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -153,6 +153,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
   return lazy;
 }
 
+#ifndef DL_INIT
+# define DL_INIT	"_dl_init"
+#endif
+
 /* Initial entry point code for the dynamic linker.
    The C function `_dl_start' is the real entry point;
    its return value is the user program's entry point.  */
@@ -194,7 +198,7 @@ _dl_start_user:\n\
 	# Clear %rbp to mark outermost frame obviously even for constructors.\n\
 	xorl %ebp, %ebp\n\
 	# Call the function to run the initializers.\n\
-	call _dl_init\n\
+	call " DL_INIT "\n\
 	# Pass our finalizer function to the user in %rdx, as per ELF ABI.\n\
 	leaq _dl_fini(%rip), %rdx\n\
 	# And make sure %rsp points to argc stored on the stack.\n\

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

commit b41e164179805977489b38eee138066e0a2e8a67
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Jun 22 08:51:42 2017 -0700

    x86: Add IBT/SHSTK bits to cpu-features
    
    Add IBT/SHSTK bits to cpu-features for Shadow Stack in Intel Control-flow
    Enforcement Technology (CET) instructions:
    
    https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
    
    	* sysdeps/x86/cpu-features.h (bit_cpu_BIT): New.
    	(bit_cpu_SHSTK): Likewise.
    	(index_cpu_IBT): Likewise.
    	(index_cpu_SHSTK): Likewise.
    	(reg_IBT): Likewise.
    	(reg_SHSTK): Likewise.

diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h
index 3ed67f5..6bf7cb0 100644
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -74,6 +74,8 @@
 #define bit_cpu_AVX512CD	(1 << 28)
 #define bit_cpu_AVX512BW	(1 << 30)
 #define bit_cpu_AVX512VL	(1u << 31)
+#define bit_cpu_IBT		(1u << 20)
+#define bit_cpu_SHSTK		(1u << 7)
 
 /* XCR0 Feature flags.  */
 #define bit_XMM_state		(1 << 1)
@@ -103,6 +105,8 @@
 # define index_cpu_AVX2	COMMON_CPUID_INDEX_7*CPUID_SIZE+CPUID_EBX_OFFSET
 # define index_cpu_ERMS	COMMON_CPUID_INDEX_7*CPUID_SIZE+CPUID_EBX_OFFSET
 # define index_cpu_MOVBE COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET
+# define index_cpu_IBT	COMMON_CPUID_INDEX_7*CPUID_SIZE+CPUID_EDX_OFFSET
+# define index_cpu_SHSTK COMMON_CPUID_INDEX_7*CPUID_SIZE+CPUID_ECX_OFFSET
 
 # define index_arch_Fast_Rep_String	FEATURE_INDEX_1*FEATURE_SIZE
 # define index_arch_Fast_Copy_Backward	FEATURE_INDEX_1*FEATURE_SIZE
@@ -277,6 +281,8 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define index_cpu_LZCNT	COMMON_CPUID_INDEX_1
 # define index_cpu_MOVBE	COMMON_CPUID_INDEX_1
 # define index_cpu_POPCNT	COMMON_CPUID_INDEX_1
+# define index_cpu_IBT		COMMON_CPUID_INDEX_7
+# define index_cpu_SHSTK	COMMON_CPUID_INDEX_7
 
 # define reg_CX8		edx
 # define reg_CMOV		edx
@@ -306,6 +312,8 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define reg_LZCNT		ecx
 # define reg_MOVBE		ecx
 # define reg_POPCNT		ecx
+# define reg_IBT		edx
+# define reg_SHSTK		ecx
 
 # define index_arch_Fast_Rep_String	FEATURE_INDEX_1
 # define index_arch_Fast_Copy_Backward	FEATURE_INDEX_1

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

commit 6b608cf43e4ec70dfea9c80ec124cb0d299e589b
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jun 21 13:07:05 2017 -0700

    Add NT_GNU_PROPERTY_TYPE_0 macros
    
    Add macros used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0).
    
    	* elf/elf.h (NT_GNU_PROPERTY_TYPE_0): New.
    	(NOTE_GNU_PROPERTY_SECTION_NAME): Likewise.
    	(GNU_PROPERTY_STACK_SIZE): Likewie.
    	(GNU_PROPERTY_NO_COPY_ON_PROTECTED): Likewie.
    	(GNU_PROPERTY_LOPROC): Likewise.
    	(GNU_PROPERTY_HIPROC): Likewise.
    	(GNU_PROPERTY_LOUSER): Likewise.
    	(GNU_PROPERTY_HIUSER): Likewise.
    	(GNU_PROPERTY_X86_ISA_1_USED): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_NEEDED): Likwise.
    	(GNU_PROPERTY_X86_FEATURE_1_AND): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_486): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_586): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_686): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_SSE): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_SSE2): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_SSE3): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_SSSE3): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_SSE4_1): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_SSE4_2): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_AVX): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_AVX2): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_AVX512F): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_AVX512CD): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_AVX512ER): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_AVX512PF): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_AVX512VL): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_AVX512DQ): Likwise.
    	(GNU_PROPERTY_X86_ISA_1_AVX512BW): Likwise.
    	(GNU_PROPERTY_X86_FEATURE_1_IBT): Likwise.
    	(GNU_PROPERTY_X86_FEATURE_1_SHSTK): Likwise.

diff --git a/elf/elf.h b/elf/elf.h
index 3900b4c..237e35c 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -1247,6 +1247,62 @@ typedef struct
 /* Version note generated by GNU gold containing a version string.  */
 #define NT_GNU_GOLD_VERSION	4
 
+/* Program property.  */
+#define NT_GNU_PROPERTY_TYPE_0 5
+
+/* Note section name of program property.   */
+#define NOTE_GNU_PROPERTY_SECTION_NAME ".note.gnu.property"
+
+/* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0).  */
+
+/* Stack size.  */
+#define GNU_PROPERTY_STACK_SIZE			1
+/* No copy relocation on protected data symbol.  */
+#define GNU_PROPERTY_NO_COPY_ON_PROTECTED	2
+
+/* Processor-specific semantics, lo */
+#define GNU_PROPERTY_LOPROC			0xc0000000
+/* Processor-specific semantics, hi */
+#define GNU_PROPERTY_HIPROC			0xdfffffff
+/* Application-specific semantics, lo */
+#define GNU_PROPERTY_LOUSER			0xe0000000
+/* Application-specific semantics, hi */
+#define GNU_PROPERTY_HIUSER			0xffffffff
+
+/* The x86 instruction sets indicated by the corresponding bits are
+   used in program.  Their support in the hardware is optional.  */
+#define GNU_PROPERTY_X86_ISA_1_USED		0xc0000000
+/* The x86 instruction sets indicated by the corresponding bits are
+   used in program and they must be supported by the hardware.   */
+#define GNU_PROPERTY_X86_ISA_1_NEEDED		0xc0000001
+/* X86 processor-specific features used in program.  */
+#define GNU_PROPERTY_X86_FEATURE_1_AND		0xc0000002
+
+#define GNU_PROPERTY_X86_ISA_1_486		(1U << 0)
+#define GNU_PROPERTY_X86_ISA_1_586		(1U << 1)
+#define GNU_PROPERTY_X86_ISA_1_686		(1U << 2)
+#define GNU_PROPERTY_X86_ISA_1_SSE		(1U << 3)
+#define GNU_PROPERTY_X86_ISA_1_SSE2		(1U << 4)
+#define GNU_PROPERTY_X86_ISA_1_SSE3		(1U << 5)
+#define GNU_PROPERTY_X86_ISA_1_SSSE3		(1U << 6)
+#define GNU_PROPERTY_X86_ISA_1_SSE4_1		(1U << 7)
+#define GNU_PROPERTY_X86_ISA_1_SSE4_2		(1U << 8)
+#define GNU_PROPERTY_X86_ISA_1_AVX		(1U << 9)
+#define GNU_PROPERTY_X86_ISA_1_AVX2		(1U << 10)
+#define GNU_PROPERTY_X86_ISA_1_AVX512F		(1U << 11)
+#define GNU_PROPERTY_X86_ISA_1_AVX512CD		(1U << 12)
+#define GNU_PROPERTY_X86_ISA_1_AVX512ER		(1U << 13)
+#define GNU_PROPERTY_X86_ISA_1_AVX512PF		(1U << 14)
+#define GNU_PROPERTY_X86_ISA_1_AVX512VL		(1U << 15)
+#define GNU_PROPERTY_X86_ISA_1_AVX512DQ		(1U << 16)
+#define GNU_PROPERTY_X86_ISA_1_AVX512BW		(1U << 17)
+
+/* This indicates that all executable sections are compatible with
+   IBT.  */
+#define GNU_PROPERTY_X86_FEATURE_1_IBT		(1U << 0)
+/* This indicates that all executable sections are compatible with
+   SHSTK.  */
+#define GNU_PROPERTY_X86_FEATURE_1_SHSTK	(1U << 1)
 
 /* Move records.  */
 typedef struct

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

commit 9bfb3fa81c58d6e66c52a524f852ee56bc70887c
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Jun 16 14:27:02 2017 -0700

    Add private_function for private functions within glibc
    
    i386 _dl_runtime_resolve:
    
            movl (%esp), %ecx
            movl %eax, (%esp)       # Store the function address.
            movl 4(%esp), %eax
            ret $12                 # Jump to function address.
    
    is incompatible with Shadow Stack in Intel Control-flow Enforcement
    Technology (CET) instructions:
    
    https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
    
    since shadow stack doesn't match return stack.  We need to use register
    indirect branch via %ecx.  That means only 2 parameters can be passed
    in registers for external function calls with lazy binding.  However,
    internal_function, which should be used only with hidden function, is
    defined as
    
     # define internal_function __attribute__ ((regparm (3), stdcall))
    
    and used with private function calls between different shared objects of
    glibc.  We introduce private_function for such purpose:
    
     # define private_function __attribute__ ((regparm (2), stdcall))
    
    so that %ecx can be used by _dl_runtime_resolve as scratch register.
    
    	[BZ #21598]
    	* config.h.in (USE_REGPARMS): Removed.
    	(internal_function): Undef.
    	(private_function): New.  Undef.
    	* debug/fortify_fail.c (__fortify_fail): Replace internal_function
    	with private_function.
    	* elf/dl-addr.c (_dl_addr): Likewise.
    	* elf/dl-error-skeleton.c (_dl_signal_error): Likewise.
    	(_dl_catch_error): Likewise.
    	* elf/dl-execstack.c (_dl_make_stack_executable): Likewise.
    	* elf/dl-load.c (_dl_rtld_di_serinfo): Likewise.
    	* elf/dl-open.c (_dl_find_dso_for_object): Likewise.
    	* elf/dl-support.c (_dl_make_stack_executable_hook): Likewise.
    	* elf/dl-sym.c (_dl_vsym): Likewise.
    	(_dl_sym): Likewise.
    	* elf/dl-tls.c (_dl_get_tls_static_info): Likewise.
    	(_dl_allocate_tls_init): Likewise.
    	(_dl_allocate_tls): Likewise.
    	(_dl_deallocate_tls): Likewise.
    	* grp/grp-merge.c (__copy_grp): Likewise.
    	(__merge_grp): Likewise.
    	* grp/grp-merge.h (__copy_grp): Likewise.
    	(__merge_grp): Likewise.
    	* include/dlfcn.h (_dl_addr): Likewise.
    	(_dl_sym): Likewise.
    	(_dl_vsym): Likewise.
    	* include/rpc/pmap_clnt.h (__libc_rpc_getport): Likewise.
    	* include/stdio.h (__fortify_fail): Likewise.
    	* include/stdlib.h (__strtof_nan): Likewise.
    	(__strtod_nan): Likewise.
    	(__strtold_nan): Likewise.
    	(__wcstof_nan): Likewise.
    	(__wcstod_nan): Likewise.
    	(__wcstold_nan): Likewise.
    	(__strtof128_nan): Likewise.
    	(__wcstof128_nan): Likewise.
    	* inet/inet6_scopeid_pton.c (__inet6_scopeid_pton): Likewise.
    	* inet/net-internal.h (__inet6_scopeid_pton): Likewise.
    	* nptl/allocatestack.c (__make_stacks_executable): Likewise.
    	* nptl/libc_pthread_init.c (__libc_pthread_init): Likewise.
    	* nptl/pthreadP.h (__make_stacks_executable): Likewise.
    	(__libc_pthread_init): Likewise.
    	* nss/XXX-lookup.c (DB_LOOKUP_FCT): Likewise.
    	(DB_COMPAT_FCT): Likewise.
    	* nss/getXXbyYY_r.c (DB_LOOKUP_FCT): Likewise.
    	* nss/getXXent_r.c (DB_LOOKUP_FCT): Likewise.
    	* nss/nsswitch.h (db_lookup_function): Likewise.
    	* resolv/gai_misc.h (__gai_sigqueue): Likewise.
    	* resolv/gai_sigqueue.c (__gai_sigqueue): Likewise.
    	* stdlib/strtod_nan_main.c (STRTOD_NAN): Likewise.
    	* sunrpc/pm_getport.c (__libc_rpc_getport): Likewise.
    	* sysdeps/generic/ldsodefs.h (_dl_make_stack_executable_hook):
    	Likewise.
    	(_dl_make_stack_executable): Likewise.
    	(_dl_signal_error): Likewise.
    	(_dl_catch_error): Likewise.
    	(_dl_rtld_di_serinfo): Likewise.
    	(_dl_allocate_tls): Likewise.
    	(_dl_get_tls_static_info): Likewise.
    	(_dl_allocate_tls_init): Likewise.
    	(_dl_deallocate_tls): Likewise.
    	(_dl_find_dso_for_object): Likewise.
    	* sysdeps/unix/sysv/linux/dl-execstack.c
    	(_dl_make_stack_executable): Likewise.
    	* sysdeps/unix/sysv/linux/gai_sigqueue.c (__gai_sigqueue):
    	Likewise.
    	* sysdeps/unix/sysv/linux/netlink_assert_response.c
    	(__netlink_assert_response): Likewise.
    	* sysdeps/unix/sysv/linux/netlinkaccess.h
    	(__netlink_assert_response): Likewise.
    	* include/libc-symbols.h (private_function): New.
    	* sysdeps/i386/configure.ac (USE_REGPARMS): Removed.
    	(internal_function): New AC_DEFINE.
    	(private_function): Likewise.
    	* sysdeps/i386/configure: Regenerated.

diff --git a/config.h.in b/config.h.in
index 2241857..989554a 100644
--- a/config.h.in
+++ b/config.h.in
@@ -47,10 +47,6 @@
 #undef	STACK_PROTECTOR_LEVEL
 #endif
 
-/* Define if the regparm attribute shall be used for local functions
-   (gcc on ix86 only).  */
-#undef	USE_REGPARMS
-
 /* Defined on SPARC if GCC emits GOTDATA relocations.  */
 #undef  HAVE_GCC_GOTDATA
 
@@ -101,9 +97,10 @@
 
 
 /* Defined to some form of __attribute__ ((...)) if the compiler supports
-   a different, more efficient calling convention.  */
-#if defined USE_REGPARMS && !defined PROF
-# define internal_function __attribute__ ((regparm (3), stdcall))
+   a different, more efficient calling convention (gcc on ix86 only).  */
+#ifndef PROF
+# undef internal_function
+# undef private_function
 #endif
 
 /* Linux specific: minimum supported kernel version.  */
diff --git a/debug/fortify_fail.c b/debug/fortify_fail.c
index a31977a..c97e962 100644
--- a/debug/fortify_fail.c
+++ b/debug/fortify_fail.c
@@ -22,7 +22,7 @@
 extern char **__libc_argv attribute_hidden;
 
 void
-__attribute__ ((noreturn)) internal_function
+__attribute__ ((noreturn)) private_function
 __fortify_fail (const char *msg)
 {
   /* The loop is added only to keep gcc happy.  */
diff --git a/elf/dl-addr.c b/elf/dl-addr.c
index 1fac63d..edd42be 100644
--- a/elf/dl-addr.c
+++ b/elf/dl-addr.c
@@ -121,7 +121,7 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
 
 
 int
-internal_function
+private_function
 _dl_addr (const void *address, Dl_info *info,
 	  struct link_map **mapp, const ElfW(Sym) **symbolp)
 {
diff --git a/elf/dl-error-skeleton.c b/elf/dl-error-skeleton.c
index 8e5888d..7d4ad30 100644
--- a/elf/dl-error-skeleton.c
+++ b/elf/dl-error-skeleton.c
@@ -77,7 +77,7 @@ static receiver_fct receiver;
 #endif /* DL_ERROR_BOOTSTRAP */
 
 void
-internal_function
+private_function
 _dl_signal_error (int errcode, const char *objname, const char *occation,
 		  const char *errstring)
 {
@@ -169,7 +169,7 @@ _dl_signal_cerror (int errcode, const char *objname, const char *occation,
 
 
 int
-internal_function
+private_function
 _dl_catch_error (const char **objname, const char **errstring,
 		 bool *mallocedp, void (*operate) (void *), void *args)
 {
diff --git a/elf/dl-execstack.c b/elf/dl-execstack.c
index 875338b..c83de34 100644
--- a/elf/dl-execstack.c
+++ b/elf/dl-execstack.c
@@ -23,7 +23,7 @@
    so as to mprotect it.  */
 
 int
-internal_function
+private_function
 _dl_make_stack_executable (void **stack_endp)
 {
   return ENOSYS;
diff --git a/elf/dl-load.c b/elf/dl-load.c
index c1b6d4b..14cf164 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -2241,7 +2241,7 @@ add_path (struct add_path_state *p, const struct r_search_path_struct *sps,
 }
 
 void
-internal_function
+private_function
 _dl_rtld_di_serinfo (struct link_map *loader, Dl_serinfo *si, bool counting)
 {
   if (counting)
diff --git a/elf/dl-open.c b/elf/dl-open.c
index cec54db..865a3ef 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -162,7 +162,7 @@ add_to_global (struct link_map *new)
    address ADDR.  Returns the pointer to the link map of the matching DSO, or
    NULL if a match is not found.  */
 struct link_map *
-internal_function
+private_function
 _dl_find_dso_for_object (const ElfW(Addr) addr)
 {
   struct link_map *l;
diff --git a/elf/dl-support.c b/elf/dl-support.c
index c22be85..b98cc4e 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -181,7 +181,7 @@ ElfW(Word) _dl_stack_flags = DEFAULT_STACK_PERMS;
 /* If loading a shared object requires that we make the stack executable
    when it was not, we do it by calling this function.
    It returns an errno code or zero on success.  */
-int (*_dl_make_stack_executable_hook) (void **) internal_function
+int (*_dl_make_stack_executable_hook) (void **) private_function
   = _dl_make_stack_executable;
 
 
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index 7cd6e97..0ad270d 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -250,7 +250,7 @@ RTLD_NEXT used in code not dynamically loaded"));
 
 
 void *
-internal_function
+private_function
 _dl_vsym (void *handle, const char *name, const char *version, void *who)
 {
   struct r_found_version vers;
@@ -267,7 +267,7 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who)
 
 
 void *
-internal_function
+private_function
 _dl_sym (void *handle, const char *name, void *who)
 {
   return do_sym (handle, name, who, NULL, DL_LOOKUP_RETURN_NEWEST);
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 5aba33b..49af79d 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -308,7 +308,7 @@ allocate_dtv (void *result)
 
 /* Get size and alignment requirements of the static TLS block.  */
 void
-internal_function
+private_function
 _dl_get_tls_static_info (size_t *sizep, size_t *alignp)
 {
   *sizep = GL(dl_tls_static_size);
@@ -439,7 +439,7 @@ _dl_resize_dtv (dtv_t *dtv)
 
 
 void *
-internal_function
+private_function
 _dl_allocate_tls_init (void *result)
 {
   if (result == NULL)
@@ -532,7 +532,7 @@ _dl_allocate_tls_init (void *result)
 rtld_hidden_def (_dl_allocate_tls_init)
 
 void *
-internal_function
+private_function
 _dl_allocate_tls (void *mem)
 {
   return _dl_allocate_tls_init (mem == NULL
@@ -543,7 +543,7 @@ rtld_hidden_def (_dl_allocate_tls)
 
 
 void
-internal_function
+private_function
 _dl_deallocate_tls (void *tcb, bool dealloc_tcb)
 {
   dtv_t *dtv = GET_DTV (tcb);
diff --git a/grp/grp-merge.c b/grp/grp-merge.c
index 77c494d..9f1d14c 100644
--- a/grp/grp-merge.c
+++ b/grp/grp-merge.c
@@ -36,7 +36,7 @@
   })
 
 int
-internal_function
+private_function
 __copy_grp (const struct group srcgrp, const size_t buflen,
 	    struct group *destgrp, char *destbuf, char **endptr)
 {
@@ -109,7 +109,7 @@ libc_hidden_def (__copy_grp)
 /* Check that the name, GID and passwd fields match, then
    copy in the gr_mem array.  */
 int
-internal_function
+private_function
 __merge_grp (struct group *savedgrp, char *savedbuf, char *savedend,
 	     size_t buflen, struct group *mergegrp, char *mergebuf)
 {
diff --git a/grp/grp-merge.h b/grp/grp-merge.h
index 1ad9b9a..180beff 100644
--- a/grp/grp-merge.h
+++ b/grp/grp-merge.h
@@ -26,12 +26,12 @@
 int
 __copy_grp (const struct group srcgrp, const size_t buflen,
 	    struct group *destgrp, char *destbuf, char **endptr)
-	    internal_function;
+	    private_function;
 
 /* Merge the member lists of two grp structs together.  */
 int
 __merge_grp (struct group *savedgrp, char *savedbuf, char *savedend,
 	     size_t buflen, struct group *mergegrp, char *mergebuf)
-	     internal_function;
+	     private_function;
 
 #endif /* _GRP_MERGE_H */
diff --git a/include/dlfcn.h b/include/dlfcn.h
index 2524292..8fcd172 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -44,7 +44,7 @@ libc_hidden_proto (__libc_dlclose)
 #ifdef ElfW
 extern int _dl_addr (const void *address, Dl_info *info,
 		     struct link_map **mapp, const ElfW(Sym) **symbolp)
-     internal_function;
+     private_function;
 libc_hidden_proto (_dl_addr)
 #endif
 
@@ -61,7 +61,7 @@ extern void _dl_close_worker (struct link_map *map, bool force)
    RTLD_NEXT).  WHO is the calling function, for RTLD_NEXT.  Returns
    the symbol value, which may be NULL.  */
 extern void *_dl_sym (void *handle, const char *name, void *who)
-    internal_function;
+    private_function;
 
 /* Look up version VERSION of symbol NAME in shared object HANDLE
    (which may be RTLD_DEFAULT or RTLD_NEXT).  WHO is the calling
@@ -69,7 +69,7 @@ extern void *_dl_sym (void *handle, const char *name, void *who)
    NULL.  */
 extern void *_dl_vsym (void *handle, const char *name, const char *version,
 		       void *who)
-    internal_function;
+    private_function;
 
 /* Helper function for <dlfcn.h> functions.  Runs the OPERATE function via
    _dl_catch_error.  Returns zero for success, nonzero for failure; and
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 3310e3a..961cbd6 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -188,12 +188,17 @@
 #endif /* __ASSEMBLER__ */
 
 /* On some platforms we can make internal function calls (i.e., calls of
-   functions not exported) a bit faster by using a different calling
-   convention.  */
+   functions within the same shared object) or private function calls
+   (i.e., calls of functions between different shared objects of glibc)
+   a bit faster by using a different calling convention.  */
 #ifndef internal_function
 # define internal_function	/* empty */
 #endif
 
+#ifndef private_function
+# define private_function	/* empty */
+#endif
+
 /* Determine the return address.  */
 #define RETURN_ADDRESS(nr) \
   __builtin_extract_return_addr (__builtin_return_address (nr))
diff --git a/include/rpc/pmap_clnt.h b/include/rpc/pmap_clnt.h
index ec907c2..6a60d44 100644
--- a/include/rpc/pmap_clnt.h
+++ b/include/rpc/pmap_clnt.h
@@ -13,7 +13,7 @@ extern int __get_socket (struct sockaddr_in *saddr)
 extern u_short __libc_rpc_getport (struct sockaddr_in *address, u_long program,
 				   u_long version, u_int protocol,
 				   time_t timeout_sec, time_t tottimeout_sec)
-     internal_function;
+     private_function;
 libc_hidden_proto (__libc_rpc_getport)
 
 libc_hidden_proto (clnt_broadcast)
diff --git a/include/stdio.h b/include/stdio.h
index f68f633..b7d1168 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -91,7 +91,7 @@ extern void __libc_fatal (const char *__message)
      __attribute__ ((__noreturn__));
 extern void __libc_message (int do_abort, const char *__fnt, ...);
 extern void __fortify_fail (const char *msg)
-     __attribute__ ((__noreturn__)) internal_function;
+     __attribute__ ((__noreturn__)) private_function;
 libc_hidden_proto (__fortify_fail)
 
 /* Acquire ownership of STREAM.  */
diff --git a/include/stdlib.h b/include/stdlib.h
index 6fd8688..670134b 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -201,16 +201,18 @@ libc_hidden_proto (strtoll)
 libc_hidden_proto (strtoul)
 libc_hidden_proto (strtoull)
 
-extern float __strtof_nan (const char *, char **, char) internal_function;
-extern double __strtod_nan (const char *, char **, char) internal_function;
+extern float __strtof_nan (const char *, char **, char)
+     private_function;
+extern double __strtod_nan (const char *, char **, char)
+     private_function;
 extern long double __strtold_nan (const char *, char **, char)
-     internal_function;
+     private_function;
 extern float __wcstof_nan (const wchar_t *, wchar_t **, wchar_t)
-     internal_function;
+     private_function;
 extern double __wcstod_nan (const wchar_t *, wchar_t **, wchar_t)
-     internal_function;
+     private_function;
 extern long double __wcstold_nan (const wchar_t *, wchar_t **, wchar_t)
-     internal_function;
+     private_function;
 
 libc_hidden_proto (__strtof_nan)
 libc_hidden_proto (__strtod_nan)
@@ -229,9 +231,9 @@ libc_hidden_proto (__strtof128_l)
 libc_hidden_proto (strtof128)
 
 extern _Float128 __strtof128_nan (const char *, char **, char)
-     internal_function;
+     private_function;
 extern _Float128 __wcstof128_nan (const wchar_t *, wchar_t **, wchar_t)
-     internal_function;
+     private_function;
 
 libc_hidden_proto (__strtof128_nan)
 libc_hidden_proto (__wcstof128_nan)
diff --git a/inet/inet6_scopeid_pton.c b/inet/inet6_scopeid_pton.c
index e09b1cb..004cab2 100644
--- a/inet/inet6_scopeid_pton.c
+++ b/inet/inet6_scopeid_pton.c
@@ -28,7 +28,7 @@
 
 /* Parse SOURCE as a scope ID for ADDRESS.  Return 0 on success and -1
    on error.  */
-internal_function int
+private_function int
 __inet6_scopeid_pton (const struct in6_addr *address, const char *scope,
                       uint32_t *result)
 {
diff --git a/inet/net-internal.h b/inet/net-internal.h
index 2b2632c..501c211 100644
--- a/inet/net-internal.h
+++ b/inet/net-internal.h
@@ -26,7 +26,7 @@
 
 int __inet6_scopeid_pton (const struct in6_addr *address,
                           const char *scope, uint32_t *result)
-  internal_function attribute_hidden;
+  private_function attribute_hidden;
 libc_hidden_proto (__inet6_scopeid_pton)
 
 
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index ec7d42e..61df8f8 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -778,7 +778,7 @@ __deallocate_stack (struct pthread *pd)
 
 
 int
-internal_function
+private_function
 __make_stacks_executable (void **stack_endp)
 {
   /* First the main thread's stack.  */
diff --git a/nptl/libc_pthread_init.c b/nptl/libc_pthread_init.c
index 0db7a10..5c00161 100644
--- a/nptl/libc_pthread_init.c
+++ b/nptl/libc_pthread_init.c
@@ -38,7 +38,7 @@ extern int __libc_multiple_threads attribute_hidden;
 
 int *
 #endif
-internal_function
+private_function
 __libc_pthread_init (unsigned long int *ptr, void (*reclaim) (void),
 		     const struct pthread_functions *functions)
 {
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 6e7d6ff..3e37649 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -357,7 +357,7 @@ extern void __reclaim_stacks (void) attribute_hidden;
 
 /* Make all threads's stacks executable.  */
 extern int __make_stacks_executable (void **stack_endp)
-     internal_function attribute_hidden;
+     private_function attribute_hidden;
 
 /* longjmp handling.  */
 extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe);
@@ -388,12 +388,12 @@ hidden_proto (__nptl_death_event)
 extern void __libc_pthread_init (unsigned long int *ptr,
 				 void (*reclaim) (void),
 				 const struct pthread_functions *functions)
-     internal_function;
+     private_function;
 #else
 extern int *__libc_pthread_init (unsigned long int *ptr,
 				 void (*reclaim) (void),
 				 const struct pthread_functions *functions)
-     internal_function;
+     private_function;
 
 /* Variable set to a nonzero value either if more than one thread runs or ran,
    or if a single-threaded process is trying to cancel itself.  See
diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c
index 5a37fda..84c3f52 100644
--- a/nss/XXX-lookup.c
+++ b/nss/XXX-lookup.c
@@ -57,11 +57,11 @@ service_user *DATABASE_NAME_SYMBOL attribute_hidden;
 
 extern int DB_LOOKUP_FCT (service_user **ni, const char *fct_name,
 			  const char *fct2_name, void **fctp)
-  internal_function;
+  private_function;
 libc_hidden_proto (DB_LOOKUP_FCT)
 
 int
-internal_function
+private_function
 DB_LOOKUP_FCT (service_user **ni, const char *fct_name, const char *fct2_name,
 	       void **fctp)
 {
@@ -79,7 +79,7 @@ libc_hidden_def (DB_LOOKUP_FCT)
 
 #ifndef NO_COMPAT
 int
-internal_function attribute_compat_text_section
+private_function attribute_compat_text_section
 DB_COMPAT_FCT (service_user **ni, const char *fct_name, void **fctp)
 {
   return DB_LOOKUP_FCT (ni, fct_name, NULL, fctp);
diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
index 7cab825..e779d05 100644
--- a/nss/getXXbyYY_r.c
+++ b/nss/getXXbyYY_r.c
@@ -182,7 +182,7 @@ typedef enum nss_status (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *,
 /* The lookup function for the first entry of this service.  */
 extern int DB_LOOKUP_FCT (service_user **nip, const char *name,
 			  const char *name2, void **fctp)
-     internal_function;
+     private_function;
 libc_hidden_proto (DB_LOOKUP_FCT)
 
 
diff --git a/nss/getXXent_r.c b/nss/getXXent_r.c
index 2710c1c..9066d47 100644
--- a/nss/getXXent_r.c
+++ b/nss/getXXent_r.c
@@ -114,7 +114,7 @@ __libc_lock_define_initialized (static, lock)
 /* The lookup function for the first entry of this service.  */
 extern int DB_LOOKUP_FCT (service_user **nip, const char *name,
 			  const char *name2, void **fctp)
-     internal_function;
+     private_function;
 libc_hidden_proto (DB_LOOKUP_FCT)
 
 void
diff --git a/nss/nsswitch.h b/nss/nsswitch.h
index f3e756b..3ff3596 100644
--- a/nss/nsswitch.h
+++ b/nss/nsswitch.h
@@ -169,7 +169,7 @@ extern void __nss_disable_nscd (void (*) (size_t, struct traced_file *));
 
 typedef int (*db_lookup_function) (service_user **, const char *, const char *,
 				   void **)
-     internal_function;
+     private_function;
 typedef enum nss_status (*setent_function) (int);
 typedef enum nss_status (*endent_function) (void);
 typedef enum nss_status (*getent_function) (void *, char *, size_t,
diff --git a/resolv/gai_misc.h b/resolv/gai_misc.h
index 6679d2b..6f686c0 100644
--- a/resolv/gai_misc.h
+++ b/resolv/gai_misc.h
@@ -96,6 +96,6 @@ extern int __gai_notify_only (struct sigevent *sigev, pid_t caller_pid)
 
 /* Send the signal.  */
 extern int __gai_sigqueue (int sig, const union sigval val, pid_t caller_pid)
-     internal_function;
+     private_function;
 
 #endif /* gai_misc.h */
diff --git a/resolv/gai_sigqueue.c b/resolv/gai_sigqueue.c
index ebc1e5e..ddec42c 100644
--- a/resolv/gai_sigqueue.c
+++ b/resolv/gai_sigqueue.c
@@ -22,7 +22,7 @@
 #include <gai_misc.h>
 
 int
-internal_function
+private_function
 __gai_sigqueue (int sig, const union sigval val, pid_t caller_pid)
 {
   __set_errno (ENOSYS);
diff --git a/stdlib/strtod_nan_main.c b/stdlib/strtod_nan_main.c
index 96b788c..f002abe 100644
--- a/stdlib/strtod_nan_main.c
+++ b/stdlib/strtod_nan_main.c
@@ -29,7 +29,7 @@
    return a default NAN.  If ENDPTR is not NULL, set *ENDPTR to point
    to the character after the initial n-char-sequence.  */
 
-internal_function
+private_function
 FLOAT
 STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc)
 {
diff --git a/sunrpc/pm_getport.c b/sunrpc/pm_getport.c
index 54d2e43..0883abc 100644
--- a/sunrpc/pm_getport.c
+++ b/sunrpc/pm_getport.c
@@ -82,7 +82,7 @@ __get_socket (struct sockaddr_in *saddr)
  * Returns 0 if no map exists.
  */
 u_short
-internal_function
+private_function
 __libc_rpc_getport (struct sockaddr_in *address, u_long program,
 		    u_long version, u_int protocol, time_t timeout_sec,
 		    time_t tottimeout_sec)
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 4508365..3c7ebd1 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -377,7 +377,7 @@ struct rtld_global
   /* If loading a shared object requires that we make the stack executable
      when it was not, we do it by calling this function.
      It returns an errno code or zero on success.  */
-  EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function;
+  EXTERN int (*_dl_make_stack_executable_hook) (void **) private_function;
 
   /* Prevailing state of the stack, PF_X indicating it's executable.  */
   EXTERN ElfW(Word) _dl_stack_flags;
@@ -632,7 +632,7 @@ extern size_t _dl_phnum;
 
 /* This is the initial value of GL(dl_make_stack_executable_hook).
    A threads library can change it.  */
-extern int _dl_make_stack_executable (void **stack_endp) internal_function;
+extern int _dl_make_stack_executable (void **stack_endp) private_function;
 rtld_hidden_proto (_dl_make_stack_executable)
 
 /* Variable pointing to the end of the stack (or close to it).  This value
@@ -739,7 +739,7 @@ _dl_dprintf (int fd, const char *fmt, ...)
    problem.  */
 extern void _dl_signal_error (int errcode, const char *object,
 			      const char *occurred, const char *errstring)
-     internal_function __attribute__ ((__noreturn__));
+     private_function __attribute__ ((__noreturn__));
 libc_hidden_proto (_dl_signal_error)
 
 /* Like _dl_signal_error, but may return when called in the context of
@@ -779,7 +779,7 @@ extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *),
 extern int _dl_catch_error (const char **objname, const char **errstring,
 			    bool *mallocedp, void (*operate) (void *),
 			    void *args)
-     internal_function;
+     private_function;
 libc_hidden_proto (_dl_catch_error)
 
 /* Open the shared object NAME and map in its segments.
@@ -813,7 +813,7 @@ extern void _dl_setup_hash (struct link_map *map)
    bytes to be used in filling in the result.  */
 extern void _dl_rtld_di_serinfo (struct link_map *loader,
 				 Dl_serinfo *si, bool counting)
-     internal_function;
+     private_function;
 
 
 /* Search loaded objects' symbol tables for a definition of the symbol
@@ -1012,12 +1012,12 @@ void __pthread_initialize_minimal (void) weak_function;
 #endif
 
 /* Allocate memory for static TLS block (unless MEM is nonzero) and dtv.  */
-extern void *_dl_allocate_tls (void *mem) internal_function;
+extern void *_dl_allocate_tls (void *mem) private_function;
 rtld_hidden_proto (_dl_allocate_tls)
 
 /* Get size and alignment requirements of the static TLS block.  */
 extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp)
-     internal_function;
+     private_function;
 
 extern void _dl_allocate_static_tls (struct link_map *map)
      internal_function attribute_hidden;
@@ -1026,11 +1026,11 @@ extern void _dl_allocate_static_tls (struct link_map *map)
    only used within rtld.c itself at startup time.  */
 extern void *_dl_allocate_tls_storage (void)
      internal_function attribute_hidden;
-extern void *_dl_allocate_tls_init (void *) internal_function;
+extern void *_dl_allocate_tls_init (void *) private_function;
 rtld_hidden_proto (_dl_allocate_tls_init)
 
 /* Deallocate memory allocated with _dl_allocate_tls.  */
-extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb) internal_function;
+extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb) private_function;
 rtld_hidden_proto (_dl_deallocate_tls)
 
 extern void _dl_nothread_init_static_tls (struct link_map *) attribute_hidden;
@@ -1081,7 +1081,7 @@ extern void _dl_show_scope (struct link_map *new, int from)
      attribute_hidden;
 
 extern struct link_map *_dl_find_dso_for_object (const ElfW(Addr) addr)
-     internal_function;
+     private_function;
 rtld_hidden_proto (_dl_find_dso_for_object)
 
 /* Initialization which is normally done by the dynamic linker.  */
diff --git a/sysdeps/i386/configure b/sysdeps/i386/configure
index 5b55c5a..bd45aa6 100644
--- a/sysdeps/i386/configure
+++ b/sysdeps/i386/configure
@@ -26,7 +26,7 @@ libc_compiler_builtin_inlined=no
 cat > conftest.c <<EOF
 int _start (void) { int a, b, c; __sync_val_compare_and_swap (&a, b, c); return 0; }
 EOF
-if ! { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+if ! { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
 		     -O0 -nostdlib -nostartfiles
 		     -S conftest.c -o - | fgrep "__sync_val_compare_and_swap"
 		     1>&5'
@@ -77,7 +77,15 @@ if test $libc_cv_asm_mpx = yes; then
 
 fi
 
-$as_echo "#define USE_REGPARMS 1" >>confdefs.h
+# On i386, we can make internal function calls (i.e., calls of functions
+# within the same shared object) or private function calls (i.e., calls
+# of functions between different shared objects of glibc) a bit faster
+# by passing function parameters in registers.  We can only pass 2
+# parameters in registers for private function calls since one register
+# is used by _dl_runtime_resolve as scratch register.
+$as_echo "#define internal_function __attribute__ ((regparm (3), stdcall))" >>confdefs.h
+
+$as_echo "#define private_function __attribute__ ((regparm (2), stdcall))" >>confdefs.h
 
 
 $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
diff --git a/sysdeps/i386/configure.ac b/sysdeps/i386/configure.ac
index 19ef33f..738935a 100644
--- a/sysdeps/i386/configure.ac
+++ b/sysdeps/i386/configure.ac
@@ -45,7 +45,14 @@ if test $libc_cv_asm_mpx = yes; then
   AC_DEFINE(HAVE_MPX_SUPPORT)
 fi
 
-AC_DEFINE(USE_REGPARMS)
+# On i386, we can make internal function calls (i.e., calls of functions
+# within the same shared object) or private function calls (i.e., calls
+# of functions between different shared objects of glibc) a bit faster
+# by passing function parameters in registers.  We can only pass 2
+# parameters in registers for private function calls since one register
+# is used by _dl_runtime_resolve as scratch register.
+AC_DEFINE(internal_function, __attribute__ ((regparm (3), stdcall)))
+AC_DEFINE(private_function, __attribute__ ((regparm (2), stdcall)))
 
 dnl It is always possible to access static and hidden symbols in an
 dnl position independent way.
diff --git a/sysdeps/unix/sysv/linux/dl-execstack.c b/sysdeps/unix/sysv/linux/dl-execstack.c
index 3c4de1c..913af76 100644
--- a/sysdeps/unix/sysv/linux/dl-execstack.c
+++ b/sysdeps/unix/sysv/linux/dl-execstack.c
@@ -30,7 +30,7 @@ extern int __stack_prot attribute_relro attribute_hidden;
 
 
 int
-internal_function
+private_function
 _dl_make_stack_executable (void **stack_endp)
 {
   /* This gives us the highest/lowest page that needs to be changed.  */
diff --git a/sysdeps/unix/sysv/linux/gai_sigqueue.c b/sysdeps/unix/sysv/linux/gai_sigqueue.c
index 0f7b459..04c8d50 100644
--- a/sysdeps/unix/sysv/linux/gai_sigqueue.c
+++ b/sysdeps/unix/sysv/linux/gai_sigqueue.c
@@ -30,7 +30,7 @@
 
 /* Return any pending signal or wait for one for the given time.  */
 int
-internal_function
+private_function
 __gai_sigqueue (int sig, const union sigval val, pid_t caller_pid)
 {
   siginfo_t info;
diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c
index d60eb15..963c879 100644
--- a/sysdeps/unix/sysv/linux/netlink_assert_response.c
+++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c
@@ -39,7 +39,7 @@ get_address_family (int fd)
 }
 
 void
-internal_function
+private_function
 __netlink_assert_response (int fd, ssize_t result)
 {
   if (result < 0)
diff --git a/sysdeps/unix/sysv/linux/netlinkaccess.h b/sysdeps/unix/sysv/linux/netlinkaccess.h
index 6cffb65..bcbcc23 100644
--- a/sysdeps/unix/sysv/linux/netlinkaccess.h
+++ b/sysdeps/unix/sysv/linux/netlinkaccess.h
@@ -52,7 +52,7 @@ extern int __netlink_request (struct netlink_handle *h, int type);
 /* Terminate the process if RESULT is an invalid recvmsg result for
    the netlink socket FD.  */
 void __netlink_assert_response (int fd, ssize_t result)
-  internal_function;
+  private_function;
 libc_hidden_proto (__netlink_assert_response)
 
 #endif /* netlinkaccess.h */

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


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


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