local-ldso-disable-hwcap
authorGNU Libc Maintainers <debian-glibc@lists.debian.org>
Tue, 4 Feb 2020 19:37:26 +0000 (19:37 +0000)
committerAurelien Jarno <aurel32@debian.org>
Tue, 4 Feb 2020 19:37:26 +0000 (19:37 +0000)
# DP: Allow hwcap's to be disabled with the existence of a file. This
# DP: makes it easier to do upgrades with optimized (hwcap) library
# DP: packages.
# DP: Author: Rewritten by Daniel Jacobowitz <dan@debian.org>
# DP: Upstream status: Debian-Specific
# DP: Status Details: This isn't going to be acceptable upstream, we
# DP:                 only need it because we support in-place upgrades.
# DP: Date: 2003-10-28, (Updated 2005-01-02 gotom, 2007-05-20 aurel32)

# DP: Allow hwcap's to be disabled with the existence of a file. This
# DP: makes it easier to do upgrades with optimized (hwcap) library
# DP: packages.
# DP: Author: Rewritten by Daniel Jacobowitz <dan@debian.org>
# DP: Upstream status: Debian-Specific
# DP: Status Details: This isn't going to be acceptable upstream, we
# DP:                 only need it because we support in-place upgrades.
# DP: Date: 2003-10-28, (Updated 2005-01-02 gotom, 2007-05-20 aurel32)

Gbp-Pq: Topic any
Gbp-Pq: Name local-ldso-disable-hwcap.diff

elf/dl-cache.c
elf/dl-hwcaps.c
sysdeps/alpha/ldsodefs.h
sysdeps/i386/ldsodefs.h [new file with mode: 0644]

index d8d1e2344e612d98689cf7d7ad965822d0ab6ed1..2ade100bba54a269e3c7bb60b84081c9d7bd95cc 100644 (file)
@@ -25,6 +25,9 @@
 #include <stdint.h>
 #include <_itoa.h>
 #include <dl-hwcaps.h>
+#include <fcntl.h>
+#include <sysdep.h>
+#include <not-errno.h>
 
 #ifndef _DL_PLATFORMS_COUNT
 # define _DL_PLATFORMS_COUNT 0
@@ -249,6 +252,7 @@ _dl_load_cache_lookup (const char *name)
   if (cache_new != (void *) -1)
     {
       uint64_t platform;
+      int disable_hwcap = 0;
 
       /* This is where the strings start.  */
       cache_data = (const char *) cache_new;
@@ -262,6 +266,11 @@ _dl_load_cache_lookup (const char *name)
 
       uint64_t hwcap_mask = GET_HWCAP_MASK();
 
+#ifdef NEED_LD_SO_NOHWCAP
+      if (__access_noerrno ("/etc/ld.so.nohwcap", F_OK) == 0)
+       disable_hwcap = 1;
+#endif
+
 #define _DL_HWCAP_TLS_MASK (1LL << 63)
       uint64_t hwcap_exclude = ~((GLRO(dl_hwcap) & hwcap_mask)
                                 | _DL_HWCAP_PLATFORM | _DL_HWCAP_TLS_MASK);
@@ -272,6 +281,8 @@ _dl_load_cache_lookup (const char *name)
        continue;                                                             \
       if (GLRO(dl_osversion) && lib->osversion > GLRO(dl_osversion))         \
        continue;                                                             \
+      if (disable_hwcap && lib->hwcap != 0)                                  \
+       continue;                                                             \
       if (_DL_PLATFORMS_COUNT                                                \
          && (lib->hwcap & _DL_HWCAP_PLATFORM) != 0                           \
          && (lib->hwcap & _DL_HWCAP_PLATFORM) != platform)                   \
index b1f7dc776f7fc470bd8074e199b04621d0958c2a..ddfde462baba8a1aae7356302c7883e7d569972d 100644 (file)
@@ -22,6 +22,9 @@
 #include <libintl.h>
 #include <unistd.h>
 #include <ldsodefs.h>
+#include <fcntl.h>
+#include <sysdep.h>
+#include <not-errno.h>
 
 #include <dl-procinfo.h>
 #include <dl-hwcaps.h>
@@ -43,6 +46,7 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
   size_t cnt = platform != NULL;
   size_t n, m;
   size_t total;
+  struct r_strlenpair *temp;
   struct r_strlenpair *result;
   struct r_strlenpair *rp;
   char *cp;
@@ -124,8 +128,24 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
   /* For TLS enabled builds always add 'tls'.  */
   ++cnt;
 
+#ifdef NEED_LD_SO_NOHWCAP
+  if (__access_noerrno ("/etc/ld.so.nohwcap", F_OK) == 0)
+    {
+      /* If hwcap is disabled, we only have the base directory to search.  */
+      result = (struct r_strlenpair *) malloc (sizeof (*result));
+      if (result == NULL)
+       goto no_memory;
+
+      result[0].str = (char *) result;  /* Does not really matter.  */
+      result[0].len = 0;
+
+      *sz = 1;
+      return result;
+    }
+#endif
+
   /* Create temporary data structure to generate result table.  */
-  struct r_strlenpair temp[cnt];
+  temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
   m = 0;
 #ifdef NEED_DL_SYSINFO_DSO
   if (dsocaps != NULL)
@@ -210,8 +230,13 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
   *sz = 1 << cnt;
   result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total);
   if (result == NULL)
-    _dl_signal_error (ENOMEM, NULL, NULL,
-                     N_("cannot create capability list"));
+    {
+#ifdef NEED_LD_SO_NOHWCAP
+    no_memory:
+#endif
+      _dl_signal_error (ENOMEM, NULL, NULL,
+                       N_("cannot create capability list"));
+    }
 
   if (cnt == 1)
     {
index daac9832664f58e2b515501070c55b8e70cde198..1daab12e2f03e1129afc22b4cc7f9be8c6b91705 100644 (file)
@@ -37,6 +37,8 @@ struct La_alpha_retval;
                                      struct La_alpha_retval *,         \
                                      const char *);
 
+#define NEED_LD_SO_NOHWCAP
+
 #include_next <ldsodefs.h>
 
 #endif
diff --git a/sysdeps/i386/ldsodefs.h b/sysdeps/i386/ldsodefs.h
new file mode 100644 (file)
index 0000000..b0a7573
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __LDSODEFS_H
+
+#define NEED_LD_SO_NOHWCAP
+
+#include_next <ldsodefs.h>
+
+#endif