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