summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-hwcaps.c14
-rw-r--r--elf/ldconfig.c6
2 files changed, 19 insertions, 1 deletions
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 ();