b1dca6
commit 31563b68410ff8e9490c5aafca31ec71b38f87a5
b1dca6
Author: Florian Weimer <fweimer@redhat.com>
b1dca6
Date:   Thu May 28 10:21:17 2020 +0200
b1dca6
b1dca6
    elf: Remove extra hwcap mechanism from ldconfig
b1dca6
    
b1dca6
    Historically, this mechanism was used to process "nosegneg"
b1dca6
    subdirectories, and it is still used to include the "tls"
b1dca6
    subdirectories.  With nosegneg support gone from ld.so, this is part
b1dca6
    no longer useful.
b1dca6
    
b1dca6
    The entire mechanism is not well-designed because it causes the
b1dca6
    meaning of hwcap bits in ld.so.cache to depend on the kernel version
b1dca6
    that was used to generate the cache, which makes it difficult to use
b1dca6
    this mechanism for anything else in the future.
b1dca6
    
b1dca6
    Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
b1dca6
b1dca6
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
b1dca6
index f31e10817dd5d665..7c8fd29387463a8a 100644
b1dca6
--- a/elf/ldconfig.c
b1dca6
+++ b/elf/ldconfig.c
b1dca6
@@ -44,11 +44,15 @@
b1dca6
 
b1dca6
 #include <dl-procinfo.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
+/* This subpath in search path entries is always supported and
b1dca6
+   included in the cache for backwards compatibility.  */
b1dca6
+#define TLS_SUBPATH "tls"
b1dca6
+
b1dca6
+/* The MSB of the hwcap field is set for objects in TLS_SUBPATH
b1dca6
+   directories.  There is always TLS support in glibc, so the dynamic
b1dca6
+   loader does not check the bit directly.  But more hwcap bits make a
b1dca6
+   an object more preferred, so the bit still has meaning.  */
b1dca6
+#define TLS_HWCAP_BIT 63
b1dca6
 
b1dca6
 #ifndef LD_SO_CONF
b1dca6
 # define LD_SO_CONF SYSCONFDIR "/ld.so.conf"
b1dca6
@@ -127,9 +131,6 @@ static const char *config_file;
b1dca6
 /* Mask to use for important hardware capabilities.  */
b1dca6
 static unsigned long int hwcap_mask = HWCAP_IMPORTANT;
b1dca6
 
b1dca6
-/* Configuration-defined capabilities defined in kernel vDSOs.  */
b1dca6
-static const char *hwcap_extra[64 - _DL_FIRST_EXTRA];
b1dca6
-
b1dca6
 /* Name and version of program.  */
b1dca6
 static void print_version (FILE *stream, struct argp_state *state);
b1dca6
 void (*argp_program_version_hook) (FILE *, struct argp_state *)
b1dca6
@@ -186,12 +187,9 @@ is_hwcap_platform (const char *name)
b1dca6
   if (hwcap_idx != -1)
b1dca6
     return 1;
b1dca6
 
b1dca6
-  /* Is this one of the extra pseudo-hwcaps that we map beyond
b1dca6
-     _DL_FIRST_EXTRA like "tls", or "nosegneg?"  */
b1dca6
-  for (hwcap_idx = _DL_FIRST_EXTRA; hwcap_idx < 64; ++hwcap_idx)
b1dca6
-    if (hwcap_extra[hwcap_idx - _DL_FIRST_EXTRA] != NULL
b1dca6
-	&& !strcmp (name, hwcap_extra[hwcap_idx - _DL_FIRST_EXTRA]))
b1dca6
-      return 1;
b1dca6
+  /* Backwards-compatibility for the "tls" subdirectory.  */
b1dca6
+  if (strcmp (name, TLS_SUBPATH) == 0)
b1dca6
+    return 1;
b1dca6
 
b1dca6
   return 0;
b1dca6
 }
b1dca6
@@ -226,11 +224,9 @@ path_hwcap (const char *path)
b1dca6
 	  h = _dl_string_platform (ptr + 1);
b1dca6
 	  if (h == (uint64_t) -1)
b1dca6
 	    {
b1dca6
-	      for (h = _DL_FIRST_EXTRA; h < 64; ++h)
b1dca6
-		if (hwcap_extra[h - _DL_FIRST_EXTRA] != NULL
b1dca6
-		    && !strcmp (ptr + 1, hwcap_extra[h - _DL_FIRST_EXTRA]))
b1dca6
-		  break;
b1dca6
-	      if (h == 64)
b1dca6
+	      if (strcmp (ptr + 1, TLS_SUBPATH) == 0)
b1dca6
+		h = TLS_HWCAP_BIT;
b1dca6
+	      else
b1dca6
 		break;
b1dca6
 	    }
b1dca6
 	}
b1dca6
@@ -1145,52 +1141,7 @@ Warning: ignoring configuration file that cannot be opened: %s"),
b1dca6
 	      parse_conf_include (filename, lineno, do_chroot, dir);
b1dca6
 	}
b1dca6
       else if (!strncasecmp (cp, "hwcap", 5) && isblank (cp[5]))
b1dca6
-	{
b1dca6
-	  cp += 6;
b1dca6
-	  char *p, *name = NULL;
b1dca6
-	  unsigned long int n = strtoul (cp, &cp, 0);
b1dca6
-	  if (cp != NULL && isblank (*cp))
b1dca6
-	    while ((p = strsep (&cp, " \t")) != NULL)
b1dca6
-	      if (p[0] != '\0')
b1dca6
-		{
b1dca6
-		  if (name == NULL)
b1dca6
-		    name = p;
b1dca6
-		  else
b1dca6
-		    {
b1dca6
-		      name = NULL;
b1dca6
-		      break;
b1dca6
-		    }
b1dca6
-		}
b1dca6
-	  if (name == NULL)
b1dca6
-	    {
b1dca6
-	      error (EXIT_FAILURE, 0, _("%s:%u: bad syntax in hwcap line"),
b1dca6
-		     filename, lineno);
b1dca6
-	      break;
b1dca6
-	    }
b1dca6
-	  if (n >= (64 - _DL_FIRST_EXTRA))
b1dca6
-	    error (EXIT_FAILURE, 0,
b1dca6
-		   _("%s:%u: hwcap index %lu above maximum %u"),
b1dca6
-		   filename, lineno, n, 64 - _DL_FIRST_EXTRA - 1);
b1dca6
-	  if (hwcap_extra[n] == NULL)
b1dca6
-	    {
b1dca6
-	      for (unsigned long int h = 0; h < (64 - _DL_FIRST_EXTRA); ++h)
b1dca6
-		if (hwcap_extra[h] != NULL && !strcmp (name, hwcap_extra[h]))
b1dca6
-		  error (EXIT_FAILURE, 0,
b1dca6
-			 _("%s:%u: hwcap index %lu already defined as %s"),
b1dca6
-			 filename, lineno, h, name);
b1dca6
-	      hwcap_extra[n] = xstrdup (name);
b1dca6
-	    }
b1dca6
-	  else
b1dca6
-	    {
b1dca6
-	      if (strcmp (name, hwcap_extra[n]))
b1dca6
-		error (EXIT_FAILURE, 0,
b1dca6
-		       _("%s:%u: hwcap index %lu already defined as %s"),
b1dca6
-		       filename, lineno, n, hwcap_extra[n]);
b1dca6
-	      if (opt_verbose)
b1dca6
-		error (0, 0, _("%s:%u: duplicate hwcap %lu %s"),
b1dca6
-		       filename, lineno, n, name);
b1dca6
-	    }
b1dca6
-	}
b1dca6
+	error (0, 0, _("%s:%u: hwcap directive ignored"), filename, lineno);
b1dca6
       else
b1dca6
 	add_dir_1 (cp, filename, lineno);
b1dca6
     }
b1dca6
@@ -1303,12 +1254,6 @@ main (int argc, char **argv)
b1dca6
 	  add_dir_1 (argv[i], "<cmdline>", 0);
b1dca6
     }
b1dca6
 
b1dca6
-  /* The last entry in hwcap_extra is reserved for the "tls" pseudo-hwcap which
b1dca6
-     indicates support for TLS.  This pseudo-hwcap is only used by old versions
b1dca6
-     under which TLS support was optional.  The entry is no longer needed, but
b1dca6
-     must remain for compatibility.  */
b1dca6
-  hwcap_extra[63 - _DL_FIRST_EXTRA] = "tls";
b1dca6
-
b1dca6
   set_hwcap ();
b1dca6
 
b1dca6
   if (opt_chroot)