summaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorRyan S. Arnold <rsa@linux.vnet.ibm.com>2013-05-03 14:14:40 -0500
committerRyan S. Arnold <rsa@linux.vnet.ibm.com>2013-05-03 14:14:40 -0500
commit1da1702d0c3996db36d44f007d7deebb7e637c08 (patch)
tree8787e734b612d9400f7553ce6612bd7d42912b7e /elf
parent1324e37f2e36fb641b82ad7b353fa28d5d57e44b (diff)
downloadglibc-1da1702d0c3996db36d44f007d7deebb7e637c08.tar.gz
Add support for AT_HWCAP2.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-support.c13
-rw-r--r--elf/dl-sysdep.c20
-rw-r--r--elf/elf.h3
3 files changed, 31 insertions, 5 deletions
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 7a55b82e34..a8cebc24f3 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 d8f3dd2fb9..832a57b6d6 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 4ad4f39999..b473a0ebd5 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