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.26-104-g470805f


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  470805fcfae63d8627a7b444afba6e54b2cb32fd (commit)

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

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

    i386: Add _dl_runtime_resolve_shstk/_dl_runtime_profile_shstk [BZ #21598]
    
    Add SHSTK compatible symbol resolvers 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
    
    Replace _dl_runtime_resolve and _dl_runtime_profile with
    _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk, respectively if
    SHSTK is enabled.
    
    	 [BZ #21598]
    	 * sysdeps/i386/dl-trampoline.S (_dl_runtime_resolve_shstk): New.
    	 (_dl_runtime_profile_shstk): Likewise.
    	 * 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..89cba6f 100644
--- a/sysdeps/i386/dl-trampoline.S
+++ b/sysdeps/i386/dl-trampoline.S
@@ -50,8 +50,76 @@ _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
+# The SHSTK compatible version.
+	.globl _dl_runtime_profile_shstk
+	.type _dl_runtime_profile_shstk, @function
+	cfi_startproc
+	.align 16
+_dl_runtime_profile_shstk:
+	cfi_adjust_cfa_offset (8)
+	pushl %esp
+	cfi_adjust_cfa_offset (4)
+	addl $8, (%esp)		# Account for the pushed PLT data
+	pushl %ebp
+	cfi_adjust_cfa_offset (4)
+	pushl %eax		# Preserve registers otherwise clobbered.
+	cfi_adjust_cfa_offset (4)
+	pushl %ecx
+	cfi_adjust_cfa_offset (4)
+	pushl %edx
+	cfi_adjust_cfa_offset (4)
+	movl %esp, %ecx
+	subl $8, %esp
+	cfi_adjust_cfa_offset (8)
+	movl $-1, 4(%esp)
+	leal 4(%esp), %edx
+	movl %edx, (%esp)
+	pushl %ecx		# Address of the register structure
+	cfi_adjust_cfa_offset (4)
+	movl 40(%esp), %ecx	# Load return address
+	movl 36(%esp), %edx	# Copy args pushed by PLT in register.  Note
+	movl 32(%esp), %eax	# that `fixup' takes its parameters in regs.
+	call _dl_profile_fixup	# Call resolver.
+	cfi_adjust_cfa_offset (-8)
+	movl (%esp), %edx
+	testl %edx, %edx
+	jns 1f
+	movl 4(%esp), %edx	# Get register content back.
+	movl %eax, %ecx		# Store the function address.
+	movl 12(%esp), %eax	# Get register content back.
+	# Adjust stack: PLT1 + PLT2 + %esp + %ebp + %eax + %ecx + %edx
+	# + free.
+	addl $32, %esp
+	cfi_adjust_cfa_offset (-32)
+	jmp *%ecx		# Jump to function address.
+	cfi_endproc
+	.size _dl_runtime_profile_shstk, .-_dl_runtime_profile_shstk
+
 	.globl _dl_runtime_profile
 	.type _dl_runtime_profile, @function
 	cfi_startproc
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..11d9010
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/dl-cet.c
@@ -0,0 +1,66 @@
+/* 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
+_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 and _dl_runtime_profile with
+         _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk,
+	 respectively if SHSTK is enabled.  */
+      extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden;
+      extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden;
+      extern void _dl_runtime_profile (Elf32_Word) attribute_hidden;
+      extern void _dl_runtime_profile_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;
+	  else if (got[2] == (Elf32_Addr) &_dl_runtime_profile)
+	    got[2] = (Elf32_Addr) &_dl_runtime_profile_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;
+	      else if (got[2] == (Elf32_Addr) &_dl_runtime_profile)
+		got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk;
+	    }
+	}
+    }
+}
+#endif

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

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

    x86: Support IBT and SHSTK in 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 CET-enabled compiler, CET is enabled by
    default, 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.
    
    <cet.h> from CET-enabled GCC is automatically included by assembly codes
    to add GNU_PROPERTY_X86_FEATURE_1_IBT and GNU_PROPERTY_X86_FEATURE_1_SHSTK
    to GNU program property.
    
    	* 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_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.
    	(CFLAGS-.o): Add -finstrument-control-flow -mcet if CET is enabled.
    	(CFLAGS-.os): Likewise.
    	(CFLAGS-.op): Likewise.
    	(CFLAGS-.oS): Likewise.
    	(asm-CPPFLAGS): Add -finstrument-control-flow -mcet -include 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 014fb4e..87ebc3e 100644
--- a/config.h.in
+++ b/config.h.in
@@ -129,6 +129,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 e6a54d7..39e2f4c 100755
--- a/configure
+++ b/configure
@@ -791,6 +791,7 @@ enable_nscd
 enable_pt_chown
 enable_tunables
 enable_mathvec
+enable_cet
 with_cpu
 '
       ac_precious_vars='build_alias
@@ -1468,6 +1469,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]
@@ -3768,6 +3771,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 2c63088..aeff26a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -467,6 +467,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 c1b6d4b..0cb6703 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 48340f7..0eefd74 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 d8e75c0..a3af3bf 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 49e673d..e9940ce 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 2e17eba..77a2049 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.  */
@@ -194,7 +198,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..52a9da5 100644
--- a/sysdeps/unix/sysv/linux/x86/Makefile
+++ b/sysdeps/unix/sysv/linux/x86/Makefile
@@ -22,3 +22,19 @@ 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
+
+# Add -finstrument-control-flow -mcet to CFLAGS when CET is enabled.
+CFLAGS-.o += -finstrument-control-flow -mcet
+CFLAGS-.os += -finstrument-control-flow -mcet
+CFLAGS-.op += -finstrument-control-flow -mcet
+CFLAGS-.oS += -finstrument-control-flow -mcet
+
+# Compile assembly codes with <cet.h> when CET is enabled.
+asm-CPPFLAGS += -finstrument-control-flow -mcet -include 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..8e184ff
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/configure
@@ -0,0 +1,72 @@
+# 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
+  # Check if CET can be enabled.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CET can be enabled" >&5
+$as_echo_n "checking whether CET can be enabled... " >&6; }
+if ${libc_cv_x86_cet_available+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.c <<EOF
+#if !defined __IBT__ || !defined __SHSTK__
+# error CET isn't available.
+#endif
+EOF
+		 if { ac_try='${CC-cc} -c $CFLAGS -finstrument-control-flow -mcet -include cet.h conftest.c 1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+		   libc_cv_x86_cet_available=yes
+		 else
+		   libc_cv_x86_cet_available=no
+		 fi
+		 rm -rf conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_cet_available" >&5
+$as_echo "$libc_cv_x86_cet_available" >&6; }
+  if test $libc_cv_x86_cet_available = yes; then
+    enable_cet=yes
+  else
+    if test x"$enable_cet" = xdefault; then
+      enable_cet=no
+    else
+      as_fn_error $? "$CC doesn't support 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..f53e624
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/configure.ac
@@ -0,0 +1,48 @@
+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
+  # Check if CET can be enabled.
+  AC_CACHE_CHECK(whether CET can be enabled,
+		 libc_cv_x86_cet_available, [dnl
+cat > conftest.c <<EOF
+#if !defined __IBT__ || !defined __SHSTK__
+# error CET isn't available.
+#endif
+EOF
+		 if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS -finstrument-control-flow -mcet -include cet.h conftest.c 1>&AS_MESSAGE_LOG_FD); then
+		   libc_cv_x86_cet_available=yes
+		 else
+		   libc_cv_x86_cet_available=no
+		 fi
+		 rm -rf conftest*])
+  if test $libc_cv_x86_cet_available = yes; then
+    enable_cet=yes
+  else
+    if test x"$enable_cet" = xdefault; then
+      enable_cet=no
+    else
+      AC_MSG_ERROR([$CC doesn't support 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..b0ef634
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/dl-cet-nonshared.c
@@ -0,0 +1,103 @@
+/* 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
+_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..bba54d5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/dl-cet.c
@@ -0,0 +1,86 @@
+/* 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
+_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..46806cb
--- /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 **)
+    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/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 9733e6e..147972a 100644
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -177,6 +177,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))
+    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=962178c23ae719543109f2494c390eb957c3918f

commit 962178c23ae719543109f2494c390eb957c3918f
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

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


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]