This is the mail archive of the libc-alpha@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]

[PATCH rsa/hwcap2_v3] Implement AT_HWCAP2 version 3


Per the suggestions in my previous patch I've removed the stdint.h
inclusions into another patch.  I've also left out the ifunc resolver
implications for future discussion.

Per the following discussion, AT_HWCAP2 support is on the road to
inclusion into the kernel:

https://patchwork.kernel.org/patch/2457411/

My patch is located in rsa/hwcap2_v3.

I've verified that the patch identifies AT_HWCAP2 on a system with an
architected kernel.  I also performed a test build where I unit tested
the _dl_procinfo changes for powerpc to show fabricated values in the
AT_HWCAP2 entry.

I haven't tested or built the non-powerpc changes and would appreciate
some feedback.  I simply stubbed a 'return 0' in the case of AT_HWCAP2
for all systems that implement _dl_procinfo.

Specification of PowerPC features bits in AT_HWCAP2 will follow in a
later patch.

Ryan S. Arnold
IBM Linux Technology Center

commit 1da1702d0c3996db36d44f007d7deebb7e637c08
Author: Ryan S. Arnold <rsa@linux.vnet.ibm.com>
Date:   Fri May 3 14:14:40 2013 -0500

    Add support for AT_HWCAP2.

2013-05-03  Ryan S. Arnold  <rsa@linux.vnet.ibm.com>

	* elf/dl-support.c (_dl_aux_init): Add support for AT_HWCAP2.
	* elf/dl-sysdep.c (_dl_sysdep_start, _dl_show_auxv): Likewise.
	* misc/getauxval.c (__getauxval): Likewise.
	* sysdeps/powerpc/dl-procinfo.h (_dl_procinfo): Add support for
	displaying AT_HWCAP2 strings.
	* elf/elf.h [AT_HWCAP2]: Add a new a_type entry.
	* sysdeps/s390/dl-procinfo.h (_dl_procinfo): Add 'type' parameter for
	AT_HWCAP2 support.
	* sysdeps/i386/dl-procinfo.h: Likewise.
	* sysdeps/generic/dl-procinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/s390/dl-procinfo.h: (_dl_procinfo): Add
	nop support for AT_HWCAP2.
	* sysdeps/unix/sysv/linux/i386/dl-procinfo.h: Likewise.
	* sysdeps/sparc/dl-procinfo.h: Likewise.

[ChangeLog.alpha]
2013-05-03  Ryan S. Arnold  <rsa@linux.vnet.ibm.com>

	* sysdeps/alpha/dl-procinfo.h (_dl_procinfo): Add 'type' parameter for
	AT_HWCAP2 support.

[ChangeLog.arm]
2013-05-03  Ryan S. Arnold  <rsa@linux.vnet.ibm.com>

	* sysdeps/unix/sysv/linux/arm/dl-procinfo.h (_dl_procinfo): Add
	nop support for AT_HWCAP2.

[ChangeLog.mips]
2013-05-03  Ryan S. Arnold  <rsa@linux.vnet.ibm.com>

	* sysdeps/mips/dl-procinfo.h (_dl_procinfo): Add 'type' parameter for
	AT_HWCAP2 support.

[ChangeLog.powerpc]
2013-05-03  Ryan S. Arnold  <rsa@linux.vnet.ibm.com>

	* sysdeps/powerpc/dl-procinfo.h (_dl_procinfo): Add support for
	displaying AT_HWCAP2 strings.

diff --git a/elf/dl-support.c b/elf/dl-support.c
index 7a55b82..a8cebc2 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -193,6 +193,10 @@ _dl_aux_init (ElfW(auxv_t) *av)
   uid_t uid = 0;
   gid_t gid = 0;
 
+  /* Don't rely on a specific order of AT_HWCAP and AT_HWCAP2.  Collate into a
+     zeroed temp and assign to _dl_hwcap after the auxv has been parsed.  */
+  uint64_t hwcap = 0;
+
   _dl_auxv = av;
   for (; av->a_type != AT_NULL; ++av)
     switch (av->a_type)
@@ -211,8 +215,12 @@ _dl_aux_init (ElfW(auxv_t) *av)
 	GL(dl_phnum) = av->a_un.a_val;
 	break;
       case AT_HWCAP:
-	GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
+	hwcap |= (unsigned long int) av->a_un.a_val;
+	break;
+      case AT_HWCAP2:
+	hwcap |= ((uint64_t) av->a_un.a_val) << 32;
 	break;
+
 #ifdef NEED_DL_SYSINFO
       case AT_SYSINFO:
 	GL(dl_sysinfo) = av->a_un.a_val;
@@ -251,6 +259,9 @@ _dl_aux_init (ElfW(auxv_t) *av)
       DL_PLATFORM_AUXV
 # endif
       }
+
+  GLRO(dl_hwcap) = hwcap;
+
   if (seen == 0xf)
     {
       __libc_enable_secure = uid != 0 || gid != 0;
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index d8f3dd2..832a57b 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -107,6 +107,10 @@ _dl_sysdep_start (void **start_argptr,
   uintptr_t new_sysinfo = 0;
 #endif
 
+  /* Don't rely on a specific order of AT_HWCAP and AT_HWCAP2.  Collate into a
+     zeroed temp and assign to _dl_hwcap after the auxv has been parsed.  */
+  uint64_t hwcap = 0;
+
   __libc_stack_end = DL_STACK_END (start_argptr);
   DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, INTUSE(_dl_argv), _environ,
 			  GLRO(dl_auxv));
@@ -154,7 +158,10 @@ _dl_sysdep_start (void **start_argptr,
 	GLRO(dl_platform) = (void *) av->a_un.a_val;
 	break;
       case AT_HWCAP:
-	GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
+	hwcap |= (unsigned long int) av->a_un.a_val;
+	break;
+      case AT_HWCAP2:
+	hwcap |= ((uint64_t) av->a_un.a_val) << 32;
 	break;
       case AT_CLKTCK:
 	GLRO(dl_clktck) = av->a_un.a_val;
@@ -180,6 +187,8 @@ _dl_sysdep_start (void **start_argptr,
 #endif
       }
 
+  GLRO(dl_hwcap) = hwcap;
+
 #ifndef HAVE_AUX_SECURE
   if (seen != -1)
     {
@@ -298,6 +307,7 @@ _dl_show_auxv (void)
 	  [AT_SYSINFO - 2] =		{ "SYSINFO:      0x", hex },
 	  [AT_SYSINFO_EHDR - 2] =	{ "SYSINFO_EHDR: 0x", hex },
 	  [AT_RANDOM - 2] =		{ "RANDOM:       0x", hex },
+	  [AT_HWCAP2 - 2] =		{ "HWCAP2:       ", hex },
 	};
       unsigned int idx = (unsigned int) (av->a_type - 2);
 
@@ -309,10 +319,12 @@ _dl_show_auxv (void)
       assert (AT_NULL == 0);
       assert (AT_IGNORE == 1);
 
-      if (av->a_type == AT_HWCAP)
+      if (av->a_type == AT_HWCAP || av->a_type == AT_HWCAP2)
 	{
-	  /* This is handled special.  */
-	  if (_dl_procinfo (av->a_un.a_val) == 0)
+	  /* HWCAP bits are translated into representative strings, per
+	     platform.  */
+	  if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0)
+
 	    continue;
 	}
 
diff --git a/elf/elf.h b/elf/elf.h
index 4ad4f39..b473a0e 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -1015,6 +1015,9 @@ typedef struct
 
 #define AT_RANDOM	25		/* Address of 16 random bytes.  */
 
+#define AT_HWCAP2	26		/* Extended machine dependent hints
+					   about processor capabilities.  */
+
 #define AT_EXECFN	31		/* Filename of executable.  */
 
 /* Pointer to the global system page used for system calls and other
diff --git a/misc/getauxval.c b/misc/getauxval.c
index 4321e37..0d69922 100644
--- a/misc/getauxval.c
+++ b/misc/getauxval.c
@@ -26,6 +26,8 @@ __getauxval (unsigned long int type)
 
   if (type == AT_HWCAP)
     return GLRO(dl_hwcap);
+  else if (type == AT_HWCAP2)
+    return GLRO(dl_hwcap) >> 32;
 
   for (p = GLRO(dl_auxv); p->a_type != AT_NULL; p++)
     if (p->a_type == type)
diff --git a/ports/sysdeps/alpha/dl-procinfo.h b/ports/sysdeps/alpha/dl-procinfo.h
index 523d966..0344dbc 100644
--- a/ports/sysdeps/alpha/dl-procinfo.h
+++ b/ports/sysdeps/alpha/dl-procinfo.h
@@ -51,7 +51,7 @@ _dl_string_platform (const char *str)
 };
 
 /* We cannot provide a general printing function.  */
-#define _dl_procinfo(word) -1
+#define _dl_procinfo(type, word) -1
 
 /* There are no hardware capabilities defined.  */
 #define _dl_hwcap_string(idx) ""
diff --git a/ports/sysdeps/mips/dl-procinfo.h b/ports/sysdeps/mips/dl-procinfo.h
index 5cc9a44..e96550c 100644
--- a/ports/sysdeps/mips/dl-procinfo.h
+++ b/ports/sysdeps/mips/dl-procinfo.h
@@ -51,7 +51,7 @@ _dl_string_platform (const char *str)
 };
 
 /* We cannot provide a general printing function.  */
-#define _dl_procinfo(word) -1
+#define _dl_procinfo(type, word) -1
 
 /* There are no hardware capabilities defined.  */
 #define _dl_hwcap_string(idx) ""
diff --git a/ports/sysdeps/powerpc/dl-procinfo.h b/ports/sysdeps/powerpc/dl-procinfo.h
index b45465c..a9d98d3 100644
--- a/ports/sysdeps/powerpc/dl-procinfo.h
+++ b/ports/sysdeps/powerpc/dl-procinfo.h
@@ -19,6 +19,7 @@
 #ifndef _DL_PROCINFO_H
 #define _DL_PROCINFO_H 1
 
+#include <stdint.h>
 #include <ldsodefs.h>
 #include <sysdep.h>            /* This defines the PPC_FEATURE_* macros.  */
 
@@ -153,19 +154,40 @@ _dl_string_platform (const char *str)
 }
 
 #ifdef IS_IN_rtld
+
 static inline int
 __attribute__ ((unused))
-_dl_procinfo (int word)
+_dl_procinfo (unsigned int type, int word)
 {
-  _dl_printf ("AT_HWCAP:       ");
+  unsigned int first, count, str_offset;
 
-  for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i)
+  switch(type)
+    {
+    case AT_HWCAP:
+      _dl_printf ("AT_HWCAP:       ");
+      first = _DL_HWCAP_FIRST;
+      count = MIN(_DL_HWCAP_COUNT,_DL_HWCAP2_FIRST);
+      str_offset = 0;
+      break;
+    case AT_HWCAP2:
+      _dl_printf ("AT_HWCAP2:      ");
+      first = 0;
+      count = _DL_HWCAP_COUNT - _DL_HWCAP2_FIRST;
+      str_offset = _DL_HWCAP2_FIRST;
+      break;
+    default:
+      /* This should not happen.  */
+      return -1;
+    }
+
+  for (int i = first; i < count; ++i)
     if (word & (1 << i))
-      _dl_printf (" %s", _dl_hwcap_string (i));
+      _dl_printf (" %s", _dl_hwcap_string (str_offset + i));
 
   _dl_printf ("\n");
 
   return 0;
+
 }
 #endif
 
diff --git a/ports/sysdeps/unix/sysv/linux/arm/dl-procinfo.h b/ports/sysdeps/unix/sysv/linux/arm/dl-procinfo.h
index 161e86c..1f3a8ce 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/dl-procinfo.h
+++ b/ports/sysdeps/unix/sysv/linux/arm/dl-procinfo.h
@@ -31,10 +31,14 @@
 
 static inline int
 __attribute__ ((unused))
-_dl_procinfo (int word)
+_dl_procinfo (unsigned int type, int word)
 {
   int i;
 
+  /* Unused for now.  */
+  if (type == AT_HWCAP2)
+    return 0;
+
   _dl_printf ("AT_HWCAP:   ");
 
   for (i = 0; i < _DL_HWCAP_COUNT; ++i)
diff --git a/sysdeps/generic/dl-procinfo.h b/sysdeps/generic/dl-procinfo.h
index 90c87d9..a184a59 100644
--- a/sysdeps/generic/dl-procinfo.h
+++ b/sysdeps/generic/dl-procinfo.h
@@ -21,7 +21,7 @@
 #define _DL_PROCINFO_H	1
 
 /* We cannot provide a general printing function.  */
-#define _dl_procinfo(word) -1
+#define _dl_procinfo(type, word) -1
 
 /* There are no hardware capabilities defined.  */
 #define _dl_hwcap_string(idx) ""
diff --git a/sysdeps/i386/dl-procinfo.h b/sysdeps/i386/dl-procinfo.h
index 883fa7f..233a325 100644
--- a/sysdeps/i386/dl-procinfo.h
+++ b/sysdeps/i386/dl-procinfo.h
@@ -61,7 +61,7 @@ enum
 };
 
 /* We cannot provide a general printing function.  */
-#define _dl_procinfo(word) -1
+#define _dl_procinfo(type, word) -1
 
 static inline const char *
 __attribute__ ((unused))
diff --git a/sysdeps/powerpc/dl-procinfo.h b/sysdeps/powerpc/dl-procinfo.h
index 19aa93b..ca20732 100644
--- a/sysdeps/powerpc/dl-procinfo.h
+++ b/sysdeps/powerpc/dl-procinfo.h
@@ -22,8 +22,9 @@
 #include <ldsodefs.h>
 #include <sysdep.h>		/* This defines the PPC_FEATURE_* macros.  */
 
-/* There are 25 bits used, but they are bits 7..31.  */
+/* There are 25 bits used in AT_HWCAP, but they are bits 7..31.  */
 #define _DL_HWCAP_FIRST		7
+#define _DL_HWCAP2_FIRST	32
 #define _DL_HWCAP_COUNT		32
 
 /* These bits influence library search.  */
@@ -133,15 +134,35 @@ _dl_string_platform (const char *str)
 }
 
 #ifdef IS_IN_rtld
+
 static inline int
 __attribute__ ((unused))
-_dl_procinfo (int word)
+_dl_procinfo (unsigned int type, int word)
 {
-  _dl_printf ("AT_HWCAP:       ");
+  unsigned int first, count, str_offset;
 
-  for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i)
+  switch(type)
+    {
+    case AT_HWCAP:
+      _dl_printf ("AT_HWCAP:       ");
+      first = _DL_HWCAP_FIRST;
+      count = MIN(_DL_HWCAP_COUNT,_DL_HWCAP2_FIRST);
+      str_offset = 0;
+      break;
+    case AT_HWCAP2:
+      _dl_printf ("AT_HWCAP2:      ");
+      first = 0;
+      count = _DL_HWCAP_COUNT - _DL_HWCAP2_FIRST;
+      str_offset = _DL_HWCAP2_FIRST;
+      break;
+    default:
+      /* This should not happen.  */
+      return -1;
+    }
+
+  for (int i = first; i < count; ++i)
     if (word & (1 << i))
-      _dl_printf (" %s", _dl_hwcap_string (i));
+      _dl_printf (" %s", _dl_hwcap_string (str_offset + i));
 
   _dl_printf ("\n");
 
diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
index 717f6f9..45e27f1 100644
--- a/sysdeps/s390/dl-procinfo.h
+++ b/sysdeps/s390/dl-procinfo.h
@@ -56,7 +56,7 @@ enum
 			  | HWCAP_S390_EIMM | HWCAP_S390_DFP)
 
 /* We cannot provide a general printing function.  */
-#define _dl_procinfo(word) -1
+#define _dl_procinfo(type, word) -1
 
 static inline const char *
 __attribute__ ((unused))
diff --git a/sysdeps/sparc/dl-procinfo.h b/sysdeps/sparc/dl-procinfo.h
index a18b099..57a250f 100644
--- a/sysdeps/sparc/dl-procinfo.h
+++ b/sysdeps/sparc/dl-procinfo.h
@@ -27,10 +27,14 @@
 
 static inline int
 __attribute__ ((unused))
-_dl_procinfo (int word)
+_dl_procinfo (unsigned int type, int word)
 {
   int i;
 
+  /* Unused for now.  */
+  if (type == AT_HWCAP2)
+    return 0;
+
   _dl_printf ("AT_HWCAP:   ");
 
   for (i = 0; i < _DL_HWCAP_COUNT; ++i)
diff --git a/sysdeps/unix/sysv/linux/i386/dl-procinfo.h b/sysdeps/unix/sysv/linux/i386/dl-procinfo.h
index a82f8f5..745b556 100644
--- a/sysdeps/unix/sysv/linux/i386/dl-procinfo.h
+++ b/sysdeps/unix/sysv/linux/i386/dl-procinfo.h
@@ -24,12 +24,16 @@
 #undef _dl_procinfo
 static inline int
 __attribute__ ((unused))
-_dl_procinfo (int word)
+_dl_procinfo (unsigned int type, int word)
 {
   /* This table should match the information from arch/i386/kernel/setup.c
      in the kernel sources.  */
   int i;
 
+  /* Unused for now.  */
+  if (type == AT_HWCAP2)
+    return 0;
+
   _dl_printf ("AT_HWCAP:   ");
 
   for (i = 0; i < _DL_HWCAP_COUNT; ++i)
diff --git a/sysdeps/unix/sysv/linux/s390/dl-procinfo.h b/sysdeps/unix/sysv/linux/s390/dl-procinfo.h
index 5ca4b76..9e9e3dc 100644
--- a/sysdeps/unix/sysv/linux/s390/dl-procinfo.h
+++ b/sysdeps/unix/sysv/linux/s390/dl-procinfo.h
@@ -24,12 +24,16 @@
 #undef _dl_procinfo
 static inline int
 __attribute__ ((unused))
-_dl_procinfo (int word)
+_dl_procinfo (unsigned int type, int word)
 {
   /* This table should match the information from arch/s390/kernel/setup.c
      in the kernel sources.  */
   int i;
 
+  /* Unused for now.  */
+  if (type == AT_HWCAP2)
+    return 0;
+
   _dl_printf ("AT_HWCAP:   ");
 
   for (i = 0; i < _DL_HWCAP_COUNT; ++i)



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