aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--elf/dl-hwcaps.c14
-rw-r--r--elf/ldconfig.c6
3 files changed, 25 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index b3edb8e0ed..4e2212c412 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2013-05-13 Carlos O'Donell <carlos@redhat.com>
+
+ * elf/dl-hwcaps.c (_dl_important_hwcaps): Comment vDSO hwcap loading.
+ * elf/ldconfig.c (is_hwcap_platform): Comment each hwcap check.
+ (main): Comment "tls" pseudo-hwcap.
+
2013-05-13 Joseph Myers <joseph@codesourcery.com>
* math/libm-test.inc (struct test_fl_f_data): New type.
diff --git a/elf/dl-hwcaps.c b/elf/dl-hwcaps.c
index 8d49383d76..1b7fe52a6a 100644
--- a/elf/dl-hwcaps.c
+++ b/elf/dl-hwcaps.c
@@ -66,6 +66,11 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
{
const ElfW(Addr) start = (phdr[i].p_vaddr
+ GLRO(dl_sysinfo_map)->l_addr);
+ /* The standard ELF note layout is exactly as the anonymous struct.
+ The next element is a variable length vendor name of length
+ VENDORLEN (with a real length rounded to ElfW(Addr)), followed
+ by the data of length DATALEN (with a real length rounded to
+ ElfW(Addr)). */
const struct
{
ElfW(Word) vendorlen;
@@ -75,6 +80,11 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
{
#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
+ /* The layout of the type 2, vendor "GNU" note is as follows:
+ .long <Number of capabilities enabled by this note>
+ .long <Capabilities mask> (as mask >> _DL_FIRST_EXTRA).
+ .byte <The bit number for the next capability>
+ .asciz <The name of the capability>. */
if (note->type == NT_GNU_HWCAP
&& note->vendorlen == sizeof "GNU"
&& !memcmp ((note + 1), "GNU", sizeof "GNU")
@@ -84,7 +94,7 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
+ ROUND (sizeof "GNU"));
cnt += *p++;
++p; /* Skip mask word. */
- dsocaps = (const char *) p;
+ dsocaps = (const char *) p; /* Pseudo-string "<b>name" */
dsocapslen = note->datalen - sizeof *p * 2;
break;
}
@@ -107,6 +117,8 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
#ifdef NEED_DL_SYSINFO_DSO
if (dsocaps != NULL)
{
+ /* dsocaps points to the .asciz string, and -1 points to the mask
+ .long just before the string. */
const ElfW(Word) mask = ((const ElfW(Word) *) dsocaps)[-1];
GLRO(dl_hwcap) |= (uint64_t) mask << _DL_FIRST_EXTRA;
/* Note that we add the dsocaps to the set already chosen by the
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index 57c6a6f04d..340c132a83 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -173,13 +173,17 @@ is_hwcap_platform (const char *name)
{
int hwcap_idx = _dl_string_hwcap (name);
+ /* Is this a normal hwcap for the machine e.g. fpu? */
if (hwcap_idx != -1 && ((1 << hwcap_idx) & hwcap_mask))
return 1;
+ /* ... Or is it a platform pseudo-hwcap e.g. i686? */
hwcap_idx = _dl_string_platform (name);
if (hwcap_idx != -1)
return 1;
+ /* ... Or is this one of the extra pseudo-hwcaps that we map beyond
+ _DL_FIRST_EXTRA e.g. tls, or nosegneg? */
for (hwcap_idx = _DL_FIRST_EXTRA; hwcap_idx < 64; ++hwcap_idx)
if (hwcap_extra[hwcap_idx - _DL_FIRST_EXTRA] != NULL
&& !strcmp (name, hwcap_extra[hwcap_idx - _DL_FIRST_EXTRA]))
@@ -1265,6 +1269,8 @@ main (int argc, char **argv)
add_dir (argv[i]);
}
+ /* The last entry in hwcap_extra is reserved for the "tls"
+ pseudo-hwcap which indicates support for TLS. */
hwcap_extra[63 - _DL_FIRST_EXTRA] = "tls";
set_hwcap ();