[03/20] libcpu-rt-c/x86: Add cpu-rt-tunables.c

Message ID 20180612221939.19545-4-hjl.tools@gmail.com
State New, archived
Headers

Commit Message

H.J. Lu June 12, 2018, 10:19 p.m. UTC
  Add cpu-rt-tunables.c to support GLIBC_TUNABLES in libcpu-rt-c.

	* cpu-rt-c/cpu-rt-misc.c: New file.
	* cpu-rt-c/cpu-rt-support.h: Likewise.
	* cpu-rt-c/cpu-rt-tunables.c: Likewise.
	* cpu-rt-c/dl-tunables.h: Likewise.
	* sysdeps/x86/cpu-rt-misc.c: Likewise.
	* sysdeps/x86/cpu-rt-support.h: Likewise.
	* elf/dl-misc.c (_dl_sysdep_read_whole_file): Make it libc only.
	(_dl_debug_vdprintf): Likewise.
	(_dl_debug_printf): Likewise.
	(_dl_debug_printf_c): Likewise.
	(_dl_dprintf): Likewise.
	(_dl_name_match_p): Likewise.
	(_dl_higher_prime_number): Likewise.
	* sysdeps/i386/dl-procinfo.c: Support libcpu-rt-c.
	* sysdeps/unix/sysv/linux/i386/dl-procinfo.h: Likewise.
	* sysdeps/x86/dl-procinfo.c: Likewise.
	* sysdeps/x86/dl-procinfo.h: Likewise.
	* sysdeps/x86/ldsodefs.h: Likewise.
	* sysdeps/x86/Makefile (libcpu-rt-c-sysdep_routines): Add
	cpu-rt-misc and cpu-rt-tunables.
	(tunables-type): New.
	(CPPFLAGS-cpu-rt-tunables.c): Likewise.
	(CFLAGS-cpu-rt-tunables.c): Likewise.
	* sysdeps/x86/cpu-features.c: Don't include <dl-hwcap.h> nor
	<elf/dl-tunables.h> in libcpu-rt-c.
	Include <cpu-rt-c/dl-tunables.h> in libcpu-rt-c.
	(init_cpu_features_tunables): New.  Extracted from ...
	(init_cpu_features): This.  Call init_cpu_features_tunables if
	not in libcpu-rt-c.  Don't access dl_platform, dl_hwcap nor
	dl_hwcap_mask in libcpu-rt-c.
	* sysdeps/x86/cpu-features.h (__cpu_rt_x86_init_cpu_features):
	New hidden prototype in libcpu-rt-c.
	(INIT_ARCH): Defined to __cpu_rt_x86_init_cpu_features in
	libcpu-rt-c.
	* sysdeps/x86/cpu-tunables.c: Include <cpu-rt-c/dl-tunables.h>,
	instead of <elf/dl-tunables.h>, in libcpu-rt-c.
---
 cpu-rt-c/cpu-rt-misc.c                     | 22 ++++++++
 cpu-rt-c/cpu-rt-support.h                  | 38 +++++++++++++
 cpu-rt-c/cpu-rt-tunables.c                 | 28 ++++++++++
 cpu-rt-c/dl-tunables.h                     | 57 +++++++++++++++++++
 elf/dl-misc.c                              |  2 +
 elf/dl-tunables.c                          |  2 +-
 sysdeps/i386/dl-procinfo.c                 | 16 +++---
 sysdeps/unix/sysv/linux/i386/dl-procinfo.h |  4 +-
 sysdeps/x86/Makefile                       | 11 +++-
 sysdeps/x86/cpu-features.c                 | 46 ++++++++++-----
 sysdeps/x86/cpu-features.h                 | 12 +++-
 sysdeps/x86/cpu-rt-misc.c                  | 65 ++++++++++++++++++++++
 sysdeps/x86/cpu-rt-support.h               | 21 +++++++
 sysdeps/x86/cpu-tunables.c                 |  6 +-
 sysdeps/x86/dl-procinfo.c                  | 41 ++++++++------
 sysdeps/x86/dl-procinfo.h                  | 15 +++--
 sysdeps/x86/ldsodefs.h                     | 17 +++++-
 17 files changed, 349 insertions(+), 54 deletions(-)
 create mode 100644 cpu-rt-c/cpu-rt-misc.c
 create mode 100644 cpu-rt-c/cpu-rt-support.h
 create mode 100644 cpu-rt-c/cpu-rt-tunables.c
 create mode 100644 cpu-rt-c/dl-tunables.h
 create mode 100644 sysdeps/x86/cpu-rt-misc.c
 create mode 100644 sysdeps/x86/cpu-rt-support.h
  

Patch

diff --git a/cpu-rt-c/cpu-rt-misc.c b/cpu-rt-c/cpu-rt-misc.c
new file mode 100644
index 0000000000..6ec8ca8bea
--- /dev/null
+++ b/cpu-rt-c/cpu-rt-misc.c
@@ -0,0 +1,22 @@ 
+/* Miscellaneous support functions for the CPU run-time library.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#if HAVE_TUNABLES
+# define CPU_RT_MISC
+# include <elf/dl-misc.c>
+#endif
diff --git a/cpu-rt-c/cpu-rt-support.h b/cpu-rt-c/cpu-rt-support.h
new file mode 100644
index 0000000000..5cb65e22d6
--- /dev/null
+++ b/cpu-rt-c/cpu-rt-support.h
@@ -0,0 +1,38 @@ 
+/* Support header file for the CPU run-time library.
+   This file is part of the GNU C Library.
+   Copyright (C) 2018 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	_CPU_RT_SUPPORT_H
+#define	_CPU_RT_SUPPORT_H 1
+
+/* It is safe to use the CPU run-time library with AT_SECURE and SUID
+   binaries.  */
+#define __libc_enable_secure __redirect___libc_enable_secure
+#include <stdint.h>
+#include <unistd.h>
+#undef __libc_enable_secure
+#define __libc_enable_secure 0
+
+#ifdef CPU_RT_MISC
+# define _dl_strtoul __cpu_rt_strtoul
+#else
+extern uint64_t __cpu_rt_strtoul (const char *, char **)
+  attribute_hidden;
+# define _dl_strtoul(nptr, endptr) __cpu_rt_strtoul ((nptr), (endptr))
+#endif
+
+#endif
diff --git a/cpu-rt-c/cpu-rt-tunables.c b/cpu-rt-c/cpu-rt-tunables.c
new file mode 100644
index 0000000000..2a27054aa7
--- /dev/null
+++ b/cpu-rt-c/cpu-rt-tunables.c
@@ -0,0 +1,28 @@ 
+/* The tunable framework for the CPU run-time library.
+   This file is part of the GNU C Library.
+   Copyright (C) 2018 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/>.  */
+
+#if HAVE_TUNABLES
+# define CPU_RT_TUNABLES
+# include <cpu-rt-support.h>
+
+/* Make tunable_list writable.  */
+# undef attribute_relro
+# define attribute_relro
+
+# include <elf/dl-tunables.c>
+#endif
diff --git a/cpu-rt-c/dl-tunables.h b/cpu-rt-c/dl-tunables.h
new file mode 100644
index 0000000000..051f7b3c17
--- /dev/null
+++ b/cpu-rt-c/dl-tunables.h
@@ -0,0 +1,57 @@ 
+/* The tunable framework for the CPU run-time library.
+   This file is part of the GNU C Library.
+   Copyright (C) 2018 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	_CPU_RT_TUNABLES_H
+#define	_CPU_RT_TUNABLES_H 1
+
+#ifdef CPU_RT_TUNABLES
+# define __tunables_init	__cpu_rt_tunables_init
+# define __tunable_get_val	__cpu_rt_tunable_get_val
+# define __tunable_set_val	__cpu_rt_tunable_set_val
+#else
+# define __tunables_init	__redirect___tunables_init
+# define __tunable_get_val	__redirect___tunable_get_val
+# define __tunable_set_val	__redirect___tunable_set_val
+#endif
+
+#include <elf/dl-tunables.h>
+
+#ifdef CPU_RT_TUNABLES
+extern void __cpu_rt_tunables_init (char **) attribute_hidden;
+extern void __cpu_rt_tunable_get_val (tunable_id_t, void *,
+				      tunable_callback_t)
+  attribute_hidden;
+extern void __cpu_rt_tunable_set_val (tunable_id_t, void *)
+  attribute_hidden;
+#else
+# undef __tunables_init
+# define __tunables_init	__cpu_rt_tunables_init
+# undef __tunable_get_val
+# define __tunable_get_val	__cpu_rt_tunable_get_val
+# undef __tunable_set_val
+# define __tunable_set_val	__cpu_rt_tunable_set_val
+
+extern __typeof (__redirect___tunables_init) __cpu_rt_tunables_init
+  attribute_hidden;
+extern __typeof (__redirect___tunable_get_val) __cpu_rt_tunable_get_val
+  attribute_hidden;
+extern __typeof (__redirect___tunable_set_val) __cpu_rt_tunable_set_val
+  attribute_hidden;
+#endif
+
+#endif
diff --git a/elf/dl-misc.c b/elf/dl-misc.c
index 2eb81eeb02..336bc7d61a 100644
--- a/elf/dl-misc.c
+++ b/elf/dl-misc.c
@@ -35,6 +35,7 @@ 
 #include <dl-writev.h>
 #include <not-cancel.h>
 
+#if !IS_IN (libcpu_rt_c)
 /* Read the whole contents of FILE into new mmap'd space with given
    protections.  *SIZEP gets the size of the file.  On error MAP_FAILED
    is returned.  */
@@ -357,6 +358,7 @@  _dl_higher_prime_number (unsigned long int n)
 
   return *low;
 }
+#endif
 
 /* A stripped down strtoul-like implementation for very early use.  It
    does not set errno if the result is outside bounds because it may get
diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index 4c9d36e398..6d3957ddb8 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -28,7 +28,7 @@ 
 #include <ldsodefs.h>
 
 #define TUNABLES_INTERNAL 1
-#include "dl-tunables.h"
+#include <dl-tunables.h>
 
 #include <not-errno.h>
 
diff --git a/sysdeps/i386/dl-procinfo.c b/sysdeps/i386/dl-procinfo.c
index cd779e3078..954b214cac 100644
--- a/sysdeps/i386/dl-procinfo.c
+++ b/sysdeps/i386/dl-procinfo.c
@@ -42,23 +42,25 @@ 
 
 #include <sysdeps/x86/dl-procinfo.c>
 
-#if !defined PROCINFO_DECL && defined SHARED
+#if !IS_IN (libcpu_rt_c)
+# if !defined PROCINFO_DECL && defined SHARED
   ._dl_x86_cap_flags
-#else
+# else
 PROCINFO_CLASS const char _dl_x86_cap_flags[32][8]
-#endif
-#ifndef PROCINFO_DECL
+# endif
+# ifndef PROCINFO_DECL
 = {
     "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
     "cx8", "apic", "10", "sep", "mtrr", "pge", "mca", "cmov",
     "pat", "pse36", "pn", "clflush", "20", "dts", "acpi", "mmx",
     "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe"
   }
-#endif
-#if !defined SHARED || defined PROCINFO_DECL
+# endif
+# if !defined SHARED || defined PROCINFO_DECL
 ;
-#else
+# else
 ,
+# endif
 #endif
 
 #undef PROCINFO_DECL
diff --git a/sysdeps/unix/sysv/linux/i386/dl-procinfo.h b/sysdeps/unix/sysv/linux/i386/dl-procinfo.h
index b454367b72..3f931891e2 100644
--- a/sysdeps/unix/sysv/linux/i386/dl-procinfo.h
+++ b/sysdeps/unix/sysv/linux/i386/dl-procinfo.h
@@ -21,7 +21,8 @@ 
 #define _DL_I386_PROCINFO_H	1
 #include <sysdeps/x86/dl-procinfo.h>
 
-#undef _dl_procinfo
+#if !IS_IN (libcpu_rt_c)
+# undef _dl_procinfo
 static inline int
 __attribute__ ((unused))
 _dl_procinfo (unsigned int type, unsigned long int word)
@@ -44,4 +45,5 @@  _dl_procinfo (unsigned int type, unsigned long int word)
 
   return 0;
 }
+# endif
 #endif
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
index 63ddaf03da..40fd14bd47 100644
--- a/sysdeps/x86/Makefile
+++ b/sysdeps/x86/Makefile
@@ -1,5 +1,14 @@ 
 ifeq ($(subdir),cpu-rt-c)
-libcpu-rt-c-sysdep_routines += cacheinfo
+libcpu-rt-c-sysdep_routines += cacheinfo cpu-rt-misc cpu-rt-tunables
+
+tunables-type = $(addprefix TUNABLES_FRONTEND_,$(have-tunables))
+CPPFLAGS-cpu-rt-tunables.c += -DTUNABLES_FRONTEND=$(tunables-type)
+
+# Make sure that the compiler does not insert any library calls in tunables
+# code paths.
+ifeq (yes,$(have-loop-to-function))
+CFLAGS-cpu-rt-tunables.c += -fno-tree-loop-distribute-patterns
+endif
 endif
 
 ifeq ($(subdir),csu)
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index 0fc3674c4b..bd57dfab95 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -18,13 +18,19 @@ 
 
 #include <cpuid.h>
 #include <cpu-features.h>
-#include <dl-hwcap.h>
+#if !IS_IN (libcpu_rt_c)
+# include <dl-hwcap.h>
+#endif
 #include <libc-pointer-arith.h>
 
 #if HAVE_TUNABLES
 # define TUNABLE_NAMESPACE tune
 # include <unistd.h>		/* Get STDOUT_FILENO for _dl_printf.  */
-# include <elf/dl-tunables.h>
+# if IS_IN (libcpu_rt_c)
+#  include <cpu-rt-c/dl-tunables.h>
+# else
+#  include <elf/dl-tunables.h>
+# endif
 
 extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *)
   attribute_hidden;
@@ -177,6 +183,20 @@  get_common_indeces (struct cpu_features *cpu_features,
     }
 }
 
+#if HAVE_TUNABLES
+static inline void
+init_cpu_features_tunables (struct cpu_features *cpu_features)
+{
+  TUNABLE_GET (hwcaps, tunable_val_t *, TUNABLE_CALLBACK (set_hwcaps));
+  cpu_features->non_temporal_threshold
+    = TUNABLE_GET (x86_non_temporal_threshold, long int, NULL);
+  cpu_features->data_cache_size
+    = TUNABLE_GET (x86_data_cache_size, long int, NULL);
+  cpu_features->shared_cache_size
+    = TUNABLE_GET (x86_shared_cache_size, long int, NULL);
+}
+#endif
+
 static inline void
 init_cpu_features (struct cpu_features *cpu_features)
 {
@@ -378,24 +398,19 @@  no_cpuid:
   cpu_features->model = model;
   cpu_features->kind = kind;
 
-#if HAVE_TUNABLES
-  TUNABLE_GET (hwcaps, tunable_val_t *, TUNABLE_CALLBACK (set_hwcaps));
-  cpu_features->non_temporal_threshold
-    = TUNABLE_GET (x86_non_temporal_threshold, long int, NULL);
-  cpu_features->data_cache_size
-    = TUNABLE_GET (x86_data_cache_size, long int, NULL);
-  cpu_features->shared_cache_size
-    = TUNABLE_GET (x86_shared_cache_size, long int, NULL);
-#endif
+#if !IS_IN (libcpu_rt_c)
+# if HAVE_TUNABLES
+  init_cpu_features_tunables (cpu_features);
+# endif
 
   /* Reuse dl_platform, dl_hwcap and dl_hwcap_mask for x86.  */
-#if !HAVE_TUNABLES && defined SHARED
+# if !HAVE_TUNABLES && defined SHARED
   /* The glibc.tune.hwcap_mask tunable is initialized already, so no need to do
      this.  */
   GLRO(dl_hwcap_mask) = HWCAP_IMPORTANT;
-#endif
+# endif
 
-#ifdef __x86_64__
+# ifdef __x86_64__
   GLRO(dl_hwcap) = HWCAP_X86_64;
   if (cpu_features->kind == arch_kind_intel)
     {
@@ -431,7 +446,7 @@  no_cpuid:
       if (platform != NULL)
 	GLRO(dl_platform) = platform;
     }
-#else
+# else
   GLRO(dl_hwcap) = 0;
   if (CPU_FEATURES_CPU_P (cpu_features, SSE2))
     GLRO(dl_hwcap) |= HWCAP_X86_SSE2;
@@ -440,5 +455,6 @@  no_cpuid:
     GLRO(dl_platform) = "i686";
   else if (CPU_FEATURES_ARCH_P (cpu_features, I586))
     GLRO(dl_platform) = "i586";
+# endif
 #endif
 }
diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h
index 624e681e96..a043f5d17d 100644
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -161,8 +161,16 @@  extern const struct cpu_features *__get_cpu_features (void)
      __attribute__ ((const));
 
 # if defined (_LIBC) && !IS_IN (nonlib)
-/* Unused for x86.  */
-#  define INIT_ARCH()
+/* Call _cpu_rt_x86_init_cpu_features to support LD_PRELOAD of the CPU
+   run-time library on non-lazy binding shared objects.  */
+#  if IS_IN (libcpu_rt_c)
+extern void __cpu_rt_x86_init_cpu_features (void)
+  __attribute__ ((visibility ("hidden")));
+#   define INIT_ARCH()		__cpu_rt_x86_init_cpu_features ()
+#  else
+/* Unused for x86 when not in the CPU run-time library.  */
+#   define INIT_ARCH()
+#  endif
 #  define __get_cpu_features()	(&GLRO(dl_x86_cpu_features))
 # endif
 
diff --git a/sysdeps/x86/cpu-rt-misc.c b/sysdeps/x86/cpu-rt-misc.c
new file mode 100644
index 0000000000..83a95b51ad
--- /dev/null
+++ b/sysdeps/x86/cpu-rt-misc.c
@@ -0,0 +1,65 @@ 
+/* Miscellaneous support functions for the CPU run-time library.  X86
+   version.
+   This file is part of the GNU C Library.
+   Copyright (C) 2018 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/>.  */
+
+#if HAVE_TUNABLES
+# include <cpu-rt-c/cpu-rt-misc.c>
+# include <cpu-tunables.c>
+#else
+# include <ldsodefs.h>
+#endif
+#include <cpu-features.c>
+#include <dl-procinfo.c>
+
+void
+__cpu_rt_x86_init_cpu_features (void)
+{
+  /* Since IFUNC selector in the CPU run-time library may be called before
+     dl_x86_cpu_features is initialized by DT_INIT_ARRAY with LD_PRELOAD
+     on non-lazy binding shared objects, __cpu_rt_x86_init_cpu_features
+     must be called from all IFUNC selectors.  Since dl_x86_cpu_features
+     is hidden in the CPU run-time library, it can be accessed without
+     dynamic relocations and we can skip calling init_cpu_features if
+     not needed.  */
+  if (GLRO(dl_x86_cpu_features).kind == arch_kind_unknown)
+    init_cpu_features (&GLRO(dl_x86_cpu_features));
+}
+
+#if HAVE_TUNABLES
+static void
+cpu_rt_init (int argc __attribute__ ((unused)),
+	     char **argv  __attribute__ ((unused)),
+	     char **environ)
+{
+  __cpu_rt_x86_init_cpu_features ();
+  __tunables_init (environ);
+  init_cpu_features_tunables (&GLRO(dl_x86_cpu_features));
+}
+
+# ifdef SHARED
+#  define INIT_SECTION ".init_array"
+# else
+#  define INIT_SECTION ".preinit_array"
+# endif
+
+static void (*const cpu_rt_init_array []) (int, char **, char **)
+  __attribute__ ((used, section (INIT_SECTION), aligned (sizeof (void *)))) =
+{
+  &cpu_rt_init
+};
+#endif
diff --git a/sysdeps/x86/cpu-rt-support.h b/sysdeps/x86/cpu-rt-support.h
new file mode 100644
index 0000000000..77d1111050
--- /dev/null
+++ b/sysdeps/x86/cpu-rt-support.h
@@ -0,0 +1,21 @@ 
+/* Support header file for the CPU run-time library.  X86 version.
+   This file is part of the GNU C Library.
+   Copyright (C) 2018 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/>.  */
+
+#include <cpu-rt-c/cpu-rt-support.h>
+
+#define HWCAP_IMPORTANT	0
diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c
index af761dcbbc..3d1c26577f 100644
--- a/sysdeps/x86/cpu-tunables.c
+++ b/sysdeps/x86/cpu-tunables.c
@@ -21,7 +21,11 @@ 
 # include <stdbool.h>
 # include <stdint.h>
 # include <unistd.h>		/* Get STDOUT_FILENO for _dl_printf.  */
-# include <elf/dl-tunables.h>
+# if IS_IN (libcpu_rt_c)
+#  include <cpu-rt-c/dl-tunables.h>
+# else
+#  include <elf/dl-tunables.h>
+# endif
 # include <string.h>
 # include <cpu-features.h>
 # include <ldsodefs.h>
diff --git a/sysdeps/x86/dl-procinfo.c b/sysdeps/x86/dl-procinfo.c
index 4b0538ede8..f623404a93 100644
--- a/sysdeps/x86/dl-procinfo.c
+++ b/sysdeps/x86/dl-procinfo.c
@@ -40,49 +40,56 @@ 
   */
 
 #if !IS_IN (ldconfig)
-# if !defined PROCINFO_DECL && defined SHARED
+# if !defined PROCINFO_DECL && defined SHARED && !IS_IN (libcpu_rt_c)
   ._dl_x86_cpu_features
 # else
+#  if IS_IN (libcpu_rt_c)
+PROCINFO_CLASS struct cpu_features __cpu_rt_dl_x86_cpu_features
+  attribute_hidden
+#  else
 PROCINFO_CLASS struct cpu_features _dl_x86_cpu_features
+#  endif
 # endif
 # ifndef PROCINFO_DECL
 = { }
 # endif
-# if !defined SHARED || defined PROCINFO_DECL
+# if !defined SHARED || defined PROCINFO_DECL || IS_IN (libcpu_rt_c)
 ;
 # else
 ,
 # endif
 #endif
 
-#if !defined PROCINFO_DECL && defined SHARED
+#if !IS_IN (libcpu_rt_c)
+# if !defined PROCINFO_DECL && defined SHARED
   ._dl_x86_hwcap_flags
-#else
+# else
 PROCINFO_CLASS const char _dl_x86_hwcap_flags[3][9]
-#endif
-#ifndef PROCINFO_DECL
+# endif
+# ifndef PROCINFO_DECL
 = {
     "sse2", "x86_64", "avx512_1"
   }
-#endif
-#if !defined SHARED || defined PROCINFO_DECL
+# endif
+# if !defined SHARED || defined PROCINFO_DECL
 ;
-#else
+# else
 ,
-#endif
+# endif
 
-#if !defined PROCINFO_DECL && defined SHARED
+# if !defined PROCINFO_DECL && defined SHARED
   ._dl_x86_platforms
-#else
+# else
 PROCINFO_CLASS const char _dl_x86_platforms[4][9]
-#endif
-#ifndef PROCINFO_DECL
+# endif
+# ifndef PROCINFO_DECL
 = {
     "i586", "i686", "haswell", "xeon_phi"
   }
-#endif
-#if !defined SHARED || defined PROCINFO_DECL
+# endif
+# if !defined SHARED || defined PROCINFO_DECL
 ;
-#else
+# else
 ,
+# endif
 #endif
diff --git a/sysdeps/x86/dl-procinfo.h b/sysdeps/x86/dl-procinfo.h
index 55cafc26e2..c2e6da9310 100644
--- a/sysdeps/x86/dl-procinfo.h
+++ b/sysdeps/x86/dl-procinfo.h
@@ -18,16 +18,18 @@ 
 
 #ifndef _DL_PROCINFO_H
 #define _DL_PROCINFO_H	1
-#include <ldsodefs.h>
-#include <dl-hwcap.h>
 
-#define _DL_HWCAP_COUNT		HWCAP_COUNT
-#define _DL_PLATFORMS_COUNT	HWCAP_PLATFORMS_COUNT
+#if !IS_IN (libcpu_rt_c)
+# include <ldsodefs.h>
+# include <dl-hwcap.h>
+
+# define _DL_HWCAP_COUNT	HWCAP_COUNT
+# define _DL_PLATFORMS_COUNT	HWCAP_PLATFORMS_COUNT
 
 /* Start at 48 to reserve spaces for hardware capabilities.  */
-#define _DL_FIRST_PLATFORM	48
+# define _DL_FIRST_PLATFORM	48
 /* Mask to filter out platforms.  */
-#define _DL_HWCAP_PLATFORM	(((1ULL << _DL_PLATFORMS_COUNT) - 1) \
+# define _DL_HWCAP_PLATFORM	(((1ULL << _DL_PLATFORMS_COUNT) - 1) \
 				 << _DL_FIRST_PLATFORM)
 
 static inline int
@@ -44,5 +46,6 @@  _dl_string_platform (const char *str)
       }
   return -1;
 };
+#endif /* !IS_IN (libcpu_rt) */
 
 #endif /* dl-procinfo.h */
diff --git a/sysdeps/x86/ldsodefs.h b/sysdeps/x86/ldsodefs.h
index 0616215b7a..f0967f81b2 100644
--- a/sysdeps/x86/ldsodefs.h
+++ b/sysdeps/x86/ldsodefs.h
@@ -23,6 +23,16 @@ 
 #include <elf.h>
 #include <cpu-features.h>
 
+#if IS_IN (libcpu_rt_c)
+# define EXTERN extern
+# define GLRO(name) __cpu_rt_##name
+# define PROCINFO_DECL
+# ifndef PROCINFO_CLASS
+#  define PROCINFO_CLASS EXTERN
+# endif
+# include <dl-procinfo.c>
+# include <cpu-rt-support.h>
+#else
 struct La_i86_regs;
 struct La_i86_retval;
 struct La_x86_64_regs;
@@ -30,7 +40,7 @@  struct La_x86_64_retval;
 struct La_x32_regs;
 struct La_x32_retval;
 
-#define ARCH_PLTENTER_MEMBERS						\
+# define ARCH_PLTENTER_MEMBERS						\
     Elf32_Addr (*i86_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *, \
 				    uintptr_t *, struct La_i86_regs *,	\
 				    unsigned int *, const char *name,	\
@@ -45,7 +55,7 @@  struct La_x32_retval;
 				    unsigned int *, const char *name,	\
 				    long int *framesizep)
 
-#define ARCH_PLTEXIT_MEMBERS						\
+# define ARCH_PLTEXIT_MEMBERS						\
     unsigned int (*i86_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *, \
 				     uintptr_t *, const struct La_i86_regs *, \
 				     struct La_i86_retval *, const char *); \
@@ -61,6 +71,7 @@  struct La_x32_retval;
 				     struct La_x86_64_retval *,		\
 				     const char *)
 
-#include_next <ldsodefs.h>
+# include_next <ldsodefs.h>
+#endif /* !IS_IN (libcpu_rt_c) */
 
 #endif