This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Make __get_cpu_features hidden
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Fri, 14 Dec 2012 10:40:17 -0800
- Subject: [PATCH] Make __get_cpu_features hidden
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
As shown in
http://www.sourceware.org/bugzilla/show_bug.cgi?id=14955
we can't call the external __get_cpu_features while relocating a DSO.
This patch makes __get_cpu_features hidden and includes it all shared
objects which use it. Currently only libc and libm use __get_cpu_features.
OK for 2.18?
H.J.
---
include/libc-symbols.h | 12 +-----------
sysdeps/i386/i686/fpu/multiarch/Makefile | 1 +
sysdeps/i386/i686/multiarch/Makefile | 3 +++
sysdeps/i386/i686/multiarch/Versions | 5 -----
sysdeps/wordsize-32/symbol-hacks.h | 5 +++--
sysdeps/x86/Makefile | 10 ++++++++++
sysdeps/x86/tst-ifunc-cpu1-main.c | 10 ++++++++++
sysdeps/x86/tst-ifunc-cpu1-mod.c | 24 ++++++++++++++++++++++++
sysdeps/x86_64/fpu/multiarch/Makefile | 1 +
sysdeps/x86_64/multiarch/Makefile | 2 ++
sysdeps/x86_64/multiarch/Versions | 5 -----
sysdeps/x86_64/multiarch/init-arch.c | 14 +++-----------
sysdeps/x86_64/multiarch/init-arch.h | 25 ++++++++++++-------------
14 files changed, 100 insertions(+), 47 deletions(-)
create mode 100644 ChangeLog.bz14955
delete mode 100644 sysdeps/i386/i686/multiarch/Versions
create mode 100644 sysdeps/x86/tst-ifunc-cpu1-main.c
create mode 100644 sysdeps/x86/tst-ifunc-cpu1-mod.c
delete mode 100644 sysdeps/x86_64/multiarch/Versions
2012-12-14 H.J. Lu <hongjiu.lu@intel.com>
[BZ #14955]
* include/libc-symbols.h (libc_ifunc): Remove INIT_ARCH.
(libm_ifunc): Defined to libc_ifunc.
* sysdeps/i386/i686/fpu/multiarch/Makefile (libm-sysdep_routines):
Add init-arch.
* sysdeps/x86_64/fpu/multiarch/Makefile (libm-sysdep_routines):
Likewise.
* sysdeps/i386/i686/multiarch/Makefile (CPPFLAGS-init-arch.c): New
macro. Defined to -Din_init_arch_c.
($(objpfx)test-multiarch): New dependency.
* sysdeps/i386/i686/multiarch/Versions: Removed.
* sysdeps/x86_64/multiarch/Versions: Likewise.
* sysdeps/wordsize-32/symbol-hacks.h: Skip if in_init_arch_c is
defined.
* sysdeps/x86/Makefile (tests): Add tst-ifunc-cpu1-main.
(modules-names): Add tst-ifunc-cpu1-mod.
(tst-ifunc-cpu1-mod.so-no-z-defs): New macro.
($(objpfx)tst-ifunc-cpu1-mod.so): New dependency.
($(objpfx)tst-ifunc-cpu1-main): Likewise.
* sysdeps/x86/tst-ifunc-cpu1-main.c: New file.
* sysdeps/x86/tst-ifunc-cpu1-mod.c: Likewise.
* sysdeps/x86_64/multiarch/Makefile ($(objpfx)test-multiarch): New
dependency.
* sysdeps/x86_64/multiarch/init-arch.c (__always_inline): Defined
to empty.
(__get_cpu_features): Removed.
* sysdeps/x86_64/multiarch/init-arch.h (INIT_ARCH): Removed.
(__get_cpu_features): Defined as an inline function.
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index a626d59..1cecaca 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -751,22 +751,12 @@ for linking")
extern void *name##_ifunc (void) __asm__ (#name); \
void *name##_ifunc (void) \
{ \
- INIT_ARCH (); \
__typeof (name) *res = expr; \
return res; \
} \
__asm__ (".type " #name ", %gnu_indirect_function");
-/* The body of the function is supposed to use __get_cpu_features
- which will, if necessary, initialize the data first. */
-#define libm_ifunc(name, expr) \
- extern void *name##_ifunc (void) __asm__ (#name); \
- void *name##_ifunc (void) \
- { \
- __typeof (name) *res = expr; \
- return res; \
- } \
- __asm__ (".type " #name ", %gnu_indirect_function");
+#define libm_ifunc(name, expr) libc_ifunc (name, (expr))
#ifdef HAVE_ASM_SET_DIRECTIVE
# define libc_ifunc_hidden_def1(local, name) \
diff --git a/sysdeps/i386/i686/fpu/multiarch/Makefile b/sysdeps/i386/i686/fpu/multiarch/Makefile
index 7d90892..92ecb04 100644
--- a/sysdeps/i386/i686/fpu/multiarch/Makefile
+++ b/sysdeps/i386/i686/fpu/multiarch/Makefile
@@ -1,4 +1,5 @@
ifeq ($(subdir),math)
+libm-sysdep_routines += init-arch
libm-sysdep_routines += e_expf-sse2 e_expf-ia32 s_sinf-sse2 s_cosf-sse2 \
s_sincosf-sse2
endif
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 8946bfa..7126e23 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,7 +1,10 @@
ifeq ($(subdir),csu)
aux += init-arch
+CPPFLAGS-init-arch.c = -Din_init_arch_c
tests += test-multiarch
gen-as-const-headers += ifunc-defines.sym
+
+$(objpfx)test-multiarch: $(common-objpfx)csu/init-arch.os
endif
ifeq ($(subdir),string)
diff --git a/sysdeps/i386/i686/multiarch/Versions b/sysdeps/i386/i686/multiarch/Versions
deleted file mode 100644
index 59b185a..0000000
--- a/sysdeps/i386/i686/multiarch/Versions
+++ /dev/null
@@ -1,5 +0,0 @@
-libc {
- GLIBC_PRIVATE {
- __get_cpu_features;
- }
-}
diff --git a/sysdeps/wordsize-32/symbol-hacks.h b/sysdeps/wordsize-32/symbol-hacks.h
index 52a14fc..9814486 100644
--- a/sysdeps/wordsize-32/symbol-hacks.h
+++ b/sysdeps/wordsize-32/symbol-hacks.h
@@ -1,5 +1,5 @@
/* Hacks needed for symbol manipulation.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004-2012 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
@@ -21,7 +21,8 @@
therefore we get PLTs. Unnecessarily so. Changing gcc is a big
task which might not be worth it so we play tricks with the
assembler. */
-#if !defined __ASSEMBLER__ && !defined in_divdi3_c && !defined NOT_IN_libc && defined SHARED
+#if !defined __ASSEMBLER__ && !defined in_divdi3_c \
+ && !defined in_init_arch_c && !defined NOT_IN_libc && defined SHARED
asm ("__divdi3 = __divdi3_internal");
asm ("__udivdi3 = __udivdi3_internal");
asm ("__moddi3 = __moddi3_internal");
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
index 3e87a77..e722a34 100644
--- a/sysdeps/x86/Makefile
+++ b/sysdeps/x86/Makefile
@@ -6,4 +6,14 @@ tests: $(objpfx)tst-xmmymm.out
$(objpfx)tst-xmmymm.out: ../sysdeps/x86/tst-xmmymm.sh $(objpfx)ld.so
@echo "Checking ld.so for SSE register use. This will take a few seconds..."
$(SHELL) $< $(objpfx) '$(NM)' '$(OBJDUMP)' '$(READELF)' > $@
+
+ifeq (yesyes,$(build-shared)$(multi-arch))
+tests += tst-ifunc-cpu1-main
+modules-names += tst-ifunc-cpu1-mod
+
+tst-ifunc-cpu1-mod.so-no-z-defs = yes
+
+$(objpfx)tst-ifunc-cpu1-mod.so: $(common-objpfx)csu/init-arch.os
+$(objpfx)tst-ifunc-cpu1-main: $(objpfx)tst-ifunc-cpu1-mod.so
+endif
endif
diff --git a/sysdeps/x86/tst-ifunc-cpu1-main.c b/sysdeps/x86/tst-ifunc-cpu1-main.c
new file mode 100644
index 0000000..37c16e2
--- /dev/null
+++ b/sysdeps/x86/tst-ifunc-cpu1-main.c
@@ -0,0 +1,10 @@
+/* Test function pointer to local STT_GNU_IFUNC function. */
+
+extern void (*foo_ptr) (void);
+
+int
+main (void)
+{
+ foo_ptr ();
+ return 0;
+}
diff --git a/sysdeps/x86/tst-ifunc-cpu1-mod.c b/sysdeps/x86/tst-ifunc-cpu1-mod.c
new file mode 100644
index 0000000..08ff30f
--- /dev/null
+++ b/sysdeps/x86/tst-ifunc-cpu1-mod.c
@@ -0,0 +1,24 @@
+#include <init-arch.h>
+
+static void
+one (void)
+{
+}
+
+static void
+two (void)
+{
+}
+
+void * foo_ifunc (void) __asm__ ("foo") attribute_hidden;
+__asm__(".type foo, %gnu_indirect_function");
+
+void *
+foo_ifunc (void)
+{
+ const struct cpu_features * cpu = __get_cpu_features ();
+ return cpu->max_cpuid > 1 ? two : one;
+}
+
+extern void foo (void) attribute_hidden;
+void (*foo_ptr) (void) = foo;
diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile
index 12b0526..2cf07bf 100644
--- a/sysdeps/x86_64/fpu/multiarch/Makefile
+++ b/sysdeps/x86_64/fpu/multiarch/Makefile
@@ -1,4 +1,5 @@
ifeq ($(subdir),math)
+libm-sysdep_routines += init-arch
libm-sysdep_routines += s_floor-c s_ceil-c s_floorf-c s_ceilf-c \
s_rint-c s_rintf-c s_nearbyint-c s_nearbyintf-c
diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile
index dd6c27d..948f32f 100644
--- a/sysdeps/x86_64/multiarch/Makefile
+++ b/sysdeps/x86_64/multiarch/Makefile
@@ -2,6 +2,8 @@ ifeq ($(subdir),csu)
aux += init-arch
tests += test-multiarch
gen-as-const-headers += ifunc-defines.sym
+
+$(objpfx)test-multiarch: $(common-objpfx)csu/init-arch.os
endif
ifeq ($(subdir),string)
diff --git a/sysdeps/x86_64/multiarch/Versions b/sysdeps/x86_64/multiarch/Versions
deleted file mode 100644
index 59b185a..0000000
--- a/sysdeps/x86_64/multiarch/Versions
+++ /dev/null
@@ -1,5 +0,0 @@
-libc {
- GLIBC_PRIVATE {
- __get_cpu_features;
- }
-}
diff --git a/sysdeps/x86_64/multiarch/init-arch.c b/sysdeps/x86_64/multiarch/init-arch.c
index fed5ab8..ff2331d 100644
--- a/sysdeps/x86_64/multiarch/init-arch.c
+++ b/sysdeps/x86_64/multiarch/init-arch.c
@@ -19,6 +19,9 @@
#include <atomic.h>
#include <cpuid.h>
+/* Define __get_cpu_features. */
+#undef __always_inline
+#define __always_inline
#include "init-arch.h"
@@ -170,14 +173,3 @@ __init_cpu_features (void)
atomic_write_barrier ();
__cpu_features.kind = kind;
}
-
-#undef __get_cpu_features
-
-const struct cpu_features *
-__get_cpu_features (void)
-{
- if (__cpu_features.kind == arch_kind_unknown)
- __init_cpu_features ();
-
- return &__cpu_features;
-}
diff --git a/sysdeps/x86_64/multiarch/init-arch.h b/sysdeps/x86_64/multiarch/init-arch.h
index f33f1c8..3ed3236 100644
--- a/sysdeps/x86_64/multiarch/init-arch.h
+++ b/sysdeps/x86_64/multiarch/init-arch.h
@@ -103,19 +103,18 @@ extern struct cpu_features
extern void __init_cpu_features (void) attribute_hidden;
-# define INIT_ARCH() \
- do \
- if (__cpu_features.kind == arch_kind_unknown) \
- __init_cpu_features (); \
- while (0)
-
-/* Used from outside libc.so to get access to the CPU features structure. */
-extern const struct cpu_features *__get_cpu_features (void)
- __attribute__ ((const));
-
-# ifndef NOT_IN_libc
-# define __get_cpu_features() (&__cpu_features)
-# endif
+
+/* Implicitly call __init_cpu_features before accessing the CPU features
+ structure. */
+
+extern __always_inline attribute_hidden
+const struct cpu_features *
+__get_cpu_features (void)
+{
+ if (__cpu_features.kind == arch_kind_unknown)
+ __init_cpu_features ();
+ return &__cpu_features;
+}
# define HAS_CPU_FEATURE(idx, reg, bit) \
((__get_cpu_features ()->cpuid[idx].reg & (bit)) != 0)
--
1.7.11.7