b1dca6
commit dcbc6b83eff5b9238170bdfed834ba934150895f
b1dca6
Author: Florian Weimer <fweimer@redhat.com>
b1dca6
Date:   Thu May 28 10:20:56 2020 +0200
b1dca6
b1dca6
    elf: Do not read hwcaps from the vDSO in ld.so
b1dca6
    
b1dca6
    This was only ever used for the "nosegneg" flag.  This approach for
b1dca6
    passing hardware capability information creates a subtle dependency
b1dca6
    between the kernel and userspace, and ld.so.cache contents.  It seems
b1dca6
    inappropriate for toady, where people expect to be able to run
b1dca6
    system images which very different kernel versions.
b1dca6
    
b1dca6
    Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
b1dca6
b1dca6
diff --git a/elf/dl-hwcaps.c b/elf/dl-hwcaps.c
b1dca6
index ecf00b457760e517..ae2e4ca7fe91d407 100644
b1dca6
--- a/elf/dl-hwcaps.c
b1dca6
+++ b/elf/dl-hwcaps.c
b1dca6
@@ -26,12 +26,6 @@
b1dca6
 #include <dl-procinfo.h>
b1dca6
 #include <dl-hwcaps.h>
b1dca6
 
b1dca6
-#ifdef _DL_FIRST_PLATFORM
b1dca6
-# define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
b1dca6
-#else
b1dca6
-# define _DL_FIRST_EXTRA _DL_HWCAP_COUNT
b1dca6
-#endif
b1dca6
-
b1dca6
 /* Return an array of useful/necessary hardware capability names.  */
b1dca6
 const struct r_strlenpair *
b1dca6
 _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
b1dca6
@@ -52,116 +46,12 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
b1dca6
     if ((masked & (1ULL << n)) != 0)
b1dca6
       ++cnt;
b1dca6
 
b1dca6
-#ifdef NEED_DL_SYSINFO_DSO
b1dca6
-  /* The system-supplied DSO can contain a note of type 2, vendor "GNU".
b1dca6
-     This gives us a list of names to treat as fake hwcap bits.  */
b1dca6
-
b1dca6
-  const char *dsocaps = NULL;
b1dca6
-  size_t dsocapslen = 0;
b1dca6
-  if (GLRO(dl_sysinfo_map) != NULL)
b1dca6
-    {
b1dca6
-      const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr;
b1dca6
-      const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum;
b1dca6
-      for (uint_fast16_t i = 0; i < phnum; ++i)
b1dca6
-	if (phdr[i].p_type == PT_NOTE)
b1dca6
-	  {
b1dca6
-	    const ElfW(Addr) start = (phdr[i].p_vaddr
b1dca6
-				      + GLRO(dl_sysinfo_map)->l_addr);
b1dca6
-	    /* NB: Some PT_NOTE segment may have alignment value of 0
b1dca6
-	       or 1.  gABI specifies that PT_NOTE segments should be
b1dca6
-	       aligned to 4 bytes in 32-bit objects and to 8 bytes in
b1dca6
-	       64-bit objects.  As a Linux extension, we also support
b1dca6
-	       4 byte alignment in 64-bit objects.  If p_align is less
b1dca6
-	       than 4, we treate alignment as 4 bytes since some note
b1dca6
-	       segments have 0 or 1 byte alignment.   */
b1dca6
-	    ElfW(Addr) align = phdr[i].p_align;
b1dca6
-	    if (align < 4)
b1dca6
-	      align = 4;
b1dca6
-	    else if (align != 4 && align != 8)
b1dca6
-	      continue;
b1dca6
-	    /* The standard ELF note layout is exactly as the anonymous struct.
b1dca6
-	       The next element is a variable length vendor name of length
b1dca6
-	       VENDORLEN (with a real length rounded to ElfW(Word)), followed
b1dca6
-	       by the data of length DATALEN (with a real length rounded to
b1dca6
-	       ElfW(Word)).  */
b1dca6
-	    const struct
b1dca6
-	    {
b1dca6
-	      ElfW(Word) vendorlen;
b1dca6
-	      ElfW(Word) datalen;
b1dca6
-	      ElfW(Word) type;
b1dca6
-	    } *note = (const void *) start;
b1dca6
-	    while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
b1dca6
-	      {
b1dca6
-		/* The layout of the type 2, vendor "GNU" note is as follows:
b1dca6
-		   .long <Number of capabilities enabled by this note>
b1dca6
-		   .long <Capabilities mask> (as mask >> _DL_FIRST_EXTRA).
b1dca6
-		   .byte <The bit number for the next capability>
b1dca6
-		   .asciz <The name of the capability>.  */
b1dca6
-		if (note->type == NT_GNU_HWCAP
b1dca6
-		    && note->vendorlen == sizeof "GNU"
b1dca6
-		    && !memcmp ((note + 1), "GNU", sizeof "GNU")
b1dca6
-		    && note->datalen > 2 * sizeof (ElfW(Word)) + 2)
b1dca6
-		  {
b1dca6
-		    const ElfW(Word) *p
b1dca6
-		      = ((const void *) note
b1dca6
-			 + ELF_NOTE_DESC_OFFSET (sizeof "GNU", align));
b1dca6
-		    cnt += *p++;
b1dca6
-		    ++p;	/* Skip mask word.  */
b1dca6
-		    dsocaps = (const char *) p; /* Pseudo-string "name"  */
b1dca6
-		    dsocapslen = note->datalen - sizeof *p * 2;
b1dca6
-		    break;
b1dca6
-		  }
b1dca6
-		note = ((const void *) note
b1dca6
-			+ ELF_NOTE_NEXT_OFFSET (note->vendorlen,
b1dca6
-						note->datalen, align));
b1dca6
-	      }
b1dca6
-	    if (dsocaps != NULL)
b1dca6
-	      break;
b1dca6
-	  }
b1dca6
-    }
b1dca6
-#endif
b1dca6
-
b1dca6
   /* For TLS enabled builds always add 'tls'.  */
b1dca6
   ++cnt;
b1dca6
 
b1dca6
   /* Create temporary data structure to generate result table.  */
b1dca6
   struct r_strlenpair temp[cnt];
b1dca6
   m = 0;
b1dca6
-#ifdef NEED_DL_SYSINFO_DSO
b1dca6
-  if (dsocaps != NULL)
b1dca6
-    {
b1dca6
-      /* dsocaps points to the .asciz string, and -1 points to the mask
b1dca6
-         .long just before the string.  */
b1dca6
-      const ElfW(Word) mask = ((const ElfW(Word) *) dsocaps)[-1];
b1dca6
-      GLRO(dl_hwcap) |= (uint64_t) mask << _DL_FIRST_EXTRA;
b1dca6
-      /* Note that we add the dsocaps to the set already chosen by the
b1dca6
-	 LD_HWCAP_MASK environment variable (or default HWCAP_IMPORTANT).
b1dca6
-	 So there is no way to request ignoring an OS-supplied dsocap
b1dca6
-	 string and bit like you can ignore an OS-supplied HWCAP bit.  */
b1dca6
-      hwcap_mask |= (uint64_t) mask << _DL_FIRST_EXTRA;
b1dca6
-#if HAVE_TUNABLES
b1dca6
-      TUNABLE_SET (glibc, cpu, hwcap_mask, uint64_t, hwcap_mask);
b1dca6
-#else
b1dca6
-      GLRO(dl_hwcap_mask) = hwcap_mask;
b1dca6
-#endif
b1dca6
-      size_t len;
b1dca6
-      for (const char *p = dsocaps; p < dsocaps + dsocapslen; p += len + 1)
b1dca6
-	{
b1dca6
-	  uint_fast8_t bit = *p++;
b1dca6
-	  len = strlen (p);
b1dca6
-
b1dca6
-	  /* Skip entries that are not enabled in the mask word.  */
b1dca6
-	  if (__glibc_likely (mask & ((ElfW(Word)) 1 << bit)))
b1dca6
-	    {
b1dca6
-	      temp[m].str = p;
b1dca6
-	      temp[m].len = len;
b1dca6
-	      ++m;
b1dca6
-	    }
b1dca6
-	  else
b1dca6
-	    --cnt;
b1dca6
-	}
b1dca6
-    }
b1dca6
-#endif
b1dca6
   for (n = 0; masked != 0; ++n)
b1dca6
     if ((masked & (1ULL << n)) != 0)
b1dca6
       {