This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][aarch64] Fix hpwcap argument passed to ifunc resolvers


I submitted a patch to gcc to use IFUNCs in libatomic.

https://gcc.gnu.org/ml/gcc-patches/2017-08/msg00545.html

While addressing some of the comments to that patch I
realized I needed some changes to glibc in order to
enable the functionality correctly.  This patch has
those changes.  In elf_ifunc_invoke I changed the
argument type passed to the ifunc resolver function
from 'unsigned long int' to 'uint64_t'.  This doesn't
matter until we do ILP32 but I would like to change
it now so that I can check in the gcc patch with a 
matching type and not have to change it later.  The
other change here is to use hwcap_mask to mask out
the hwcap value passed to the resolver function.  This
means that ifunc resolvers that use the hwcap argument
to check for hardware capabilities will be affected
by LD_HWCAP_MASK in the same way that glibc resolver
functions are.

Finally, I updated HWCAP_IMPORTANT to be all the
known HWCAP_* values or'ed together so that nothing
was masked out by default.  This was set to just
HWCAP_CPUID before and if you did not set LD_HWCAP_MASK
but tried to check HWCAP_ATOMICS in a ifunc resolver
you would get 0 because the default value of hwcap_mask
would not have that bit set and it would get masked out by
the AND operation I added to elf_ifunc_invoke.  I don't
think we want any of the hardware capabilities masked out
by default, but only if the user sets LD_HWCAP_MASK.

Tested on aarch64 with a modified GCC libatomic patch
and with the glibc testsuite.

Steve Ellcey
sellcey@cavium.com


2017-08-30  Steve Ellcey  <sellcey@cavium.com>

	* sysdeps/aarch64/dl-irel.h: Include elf/dl-hwcaps.h
	for GET_HWCAP_MASK.
	(elf_ifunc_invoke): Change argument type and use
	GET_HWCAP_MASK to mask out bits in dl_hwcap.
	* sysdeps/unix/sysv/linux/aarch64/dl-procinfo.h (HWCAP_IMPORTANT):
	Use bitwise or of all defined HWCAP values as default value.

diff --git a/sysdeps/aarch64/dl-irel.h b/sysdeps/aarch64/dl-irel.h
index 4a80275..3ef8497 100644
--- a/sysdeps/aarch64/dl-irel.h
+++ b/sysdeps/aarch64/dl-irel.h
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <ldsodefs.h>
 #include <sysdep.h>
+#include <elf/dl-hwcaps.h>
 
 #define ELF_MACHINE_IRELA	1
 
@@ -31,7 +32,8 @@ static inline ElfW(Addr)
 __attribute ((always_inline))
 elf_ifunc_invoke (ElfW(Addr) addr)
 {
-  return ((ElfW(Addr) (*) (unsigned long int)) (addr)) (GLRO(dl_hwcap));
+  return ((ElfW(Addr) (*) (uint64_t)) (addr))
+	   (GLRO(dl_hwcap) & GET_HWCAP_MASK());
 }
 
 static inline void
diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.h b/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.h
index 0333a18..19637f6 100644
--- a/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.h
+++ b/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.h
@@ -33,9 +33,15 @@
 /* Offset of the last bit allocated in HWCAP.  */
 #define _DL_HWCAP_LAST 15
 
-/* HWCAP_CPUID should be available by default to influence IFUNC as well as
-   library search.  */
-#define HWCAP_IMPORTANT HWCAP_CPUID
+/* HWCAP_IMPORTANT is used to set the default value of hwcap_mask, we do not
+   want to mask out any HWCAP values because then we could not use them in
+   an IFUNC selector.  */
+#define HWCAP_IMPORTANT (HWCAP_FP | HWCAP_ASIMD | HWCAP_EVTSTRM | HWCAP_AES \
+			 | HWCAP_PMULL | HWCAP_SHA1 | HWCAP_SHA2 | HWCAP_CRC32 \
+			 | HWCAP_ATOMICS | HWCAP_FPHP | HWCAP_ASIMDHP \
+		         | HWCAP_CPUID | HWCAP_ASIMDRDM | HWCAP_JSCVT \
+			 | HWCAP_FCMA | HWCAP_LRCPC)
+
 
 static inline const char *
 __attribute__ ((unused))

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]