From 3105c551899a99d848c502ca8959bf9aa3cb34be Mon Sep 17 00:00:00 2001 From: GNU Libc Maintainers Date: Tue, 4 Aug 2020 16:02:38 +0100 Subject: [PATCH] local-ldso-disable-hwcap # 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 # 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 # 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 | 11 +++++++++++ elf/dl-hwcaps.c | 31 ++++++++++++++++++++++++++++--- sysdeps/alpha/ldsodefs.h | 2 ++ sysdeps/i386/ldsodefs.h | 7 +++++++ 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 sysdeps/i386/ldsodefs.h diff --git a/elf/dl-cache.c b/elf/dl-cache.c index 3eedd9afc..9ed21579f 100644 --- a/elf/dl-cache.c +++ b/elf/dl-cache.c @@ -25,6 +25,9 @@ #include #include <_itoa.h> #include +#include +#include +#include #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) \ diff --git a/elf/dl-hwcaps.c b/elf/dl-hwcaps.c index 71aea8670..8792bb7cb 100644 --- a/elf/dl-hwcaps.c +++ b/elf/dl-hwcaps.c @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include #include #include @@ -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) { diff --git a/sysdeps/alpha/ldsodefs.h b/sysdeps/alpha/ldsodefs.h index 795c1127c..448416a41 100644 --- a/sysdeps/alpha/ldsodefs.h +++ b/sysdeps/alpha/ldsodefs.h @@ -37,6 +37,8 @@ struct La_alpha_retval; struct La_alpha_retval *, \ const char *); +#define NEED_LD_SO_NOHWCAP + #include_next #endif diff --git a/sysdeps/i386/ldsodefs.h b/sysdeps/i386/ldsodefs.h new file mode 100644 index 000000000..b0a757303 --- /dev/null +++ b/sysdeps/i386/ldsodefs.h @@ -0,0 +1,7 @@ +#ifndef __LDSODEFS_H + +#define NEED_LD_SO_NOHWCAP + +#include_next + +#endif -- 2.30.2