gdbserver: Add linux_get_hwcap
authorAlan Hayward <alan.hayward@arm.com>
Mon, 25 Mar 2019 10:44:11 +0000 (10:44 +0000)
committerAlan Hayward <alan.hayward@arm.com>
Tue, 26 Mar 2019 16:27:43 +0000 (16:27 +0000)
In gdbserver, Tidy up calls to read HWCAP (and HWCAP2) by adding common
functions, removing the Arm, AArch64, PPC and S390 specific versions.

No functionality differences.

gdb/gdbserver/ChangeLog:

* linux-aarch64-low.c (aarch64_get_hwcap): Remove function.
(aarch64_arch_setup): Call linux_get_hwcap.
* linux-arm-low.c (arm_get_hwcap): Remove function.
(arm_read_description): Call linux_get_hwcap.
* linux-low.c (linux_get_auxv): New function.
(linux_get_hwcap): Likewise.
(linux_get_hwcap2): Likewise.
* linux-low.h (linux_get_hwcap): New declaration.
(linux_get_hwcap2): Likewise.
* linux-ppc-low.c (ppc_get_auxv): Remove function.
(ppc_arch_setup): Call linux_get_hwcap.
* linux-s390-low.c (s390_get_hwcap): Remove function.
(s390_arch_setup): Call linux_get_hwcap.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-aarch64-low.c
gdb/gdbserver/linux-arm-low.c
gdb/gdbserver/linux-low.c
gdb/gdbserver/linux-low.h
gdb/gdbserver/linux-ppc-low.c
gdb/gdbserver/linux-s390-low.c

index 21c286d5ef3e710f1c5a849dcb82de205974c7f6..8716ab5b43e389ae42b5b0f242f4d53a0aa2d7d0 100644 (file)
@@ -1,3 +1,19 @@
+2019-03-26  Alan Hayward  <alan.hayward@arm.com>
+
+       * linux-aarch64-low.c (aarch64_get_hwcap): Remove function.
+       (aarch64_arch_setup): Call linux_get_hwcap.
+       * linux-arm-low.c (arm_get_hwcap): Remove function.
+       (arm_read_description): Call linux_get_hwcap.
+       * linux-low.c (linux_get_auxv): New function.
+       (linux_get_hwcap): Likewise.
+       (linux_get_hwcap2): Likewise.
+       * linux-low.h (linux_get_hwcap): New declaration.
+       (linux_get_hwcap2): Likewise.
+       * linux-ppc-low.c (ppc_get_auxv): Remove function.
+       (ppc_arch_setup): Call linux_get_hwcap.
+       * linux-s390-low.c (s390_get_hwcap): Remove function.
+       (s390_arch_setup): Call linux_get_hwcap.
+
 2019-03-22  Alan Hayward  <alan.hayward@arm.com>
            Jiong Wang  <jiong.wang@arm.com>
 
index 20c75493b07c03c044258055219326c05e606128..dc4ee81d2a24ead4f97fad653aa547f97f30faf0 100644 (file)
@@ -505,30 +505,6 @@ aarch64_linux_new_fork (struct process_info *parent,
 /* Matches HWCAP_PACA in kernel header arch/arm64/include/uapi/asm/hwcap.h.  */
 #define AARCH64_HWCAP_PACA (1 << 30)
 
-/* Fetch the AT_HWCAP entry from the auxv vector.  */
-
-static bool
-aarch64_get_hwcap (unsigned long *valp)
-{
-  unsigned char *data = (unsigned char *) alloca (16);
-  int offset = 0;
-
-  while ((*the_target->read_auxv) (offset, data, 16) == 16)
-    {
-      unsigned long *data_p = (unsigned long *)data;
-      if (data_p[0] == AT_HWCAP)
-       {
-         *valp = data_p[1];
-         return true;
-       }
-
-      offset += 16;
-    }
-
-  *valp = 0;
-  return false;
-}
-
 /* Implementation of linux_target_ops method "arch_setup".  */
 
 static void
@@ -545,8 +521,8 @@ aarch64_arch_setup (void)
   if (is_elf64)
     {
       uint64_t vq = aarch64_sve_get_vq (tid);
-      unsigned long hwcap = 0;
-      bool pauth_p = aarch64_get_hwcap (&hwcap) && (hwcap & AARCH64_HWCAP_PACA);
+      unsigned long hwcap = linux_get_hwcap (8);
+      bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
 
       current_process ()->tdesc = aarch64_linux_read_description (vq, pauth_p);
     }
index 8cad5c5fd4a99b352cef8a53f223b1bd89f0ec34..ff72a489cba98f1562337dcaa26936b29f68e5ea 100644 (file)
@@ -847,40 +847,15 @@ get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self)
   return next_pc;
 }
 
-static int
-arm_get_hwcap (unsigned long *valp)
-{
-  unsigned char *data = (unsigned char *) alloca (8);
-  int offset = 0;
-
-  while ((*the_target->read_auxv) (offset, data, 8) == 8)
-    {
-      unsigned int *data_p = (unsigned int *)data;
-      if (data_p[0] == AT_HWCAP)
-       {
-         *valp = data_p[1];
-         return 1;
-       }
-
-      offset += 8;
-    }
-
-  *valp = 0;
-  return 0;
-}
-
 static const struct target_desc *
 arm_read_description (void)
 {
   int pid = lwpid_of (current_thread);
-  unsigned long arm_hwcap = 0;
+  unsigned long arm_hwcap = linux_get_hwcap (4);
 
   /* Query hardware watchpoint/breakpoint capabilities.  */
   arm_linux_init_hwbp_cap (pid);
 
-  if (arm_get_hwcap (&arm_hwcap) == 0)
-    return tdesc_arm;
-
   if (arm_hwcap & HWCAP_IWMMXT)
     return tdesc_arm_with_iwmmxt;
 
index 6f703f589fe931c86c27bf750cf6ee144062befd..7158a6798c91f42670a232343b252d5f835da999 100644 (file)
@@ -7423,6 +7423,53 @@ linux_get_pc_64bit (struct regcache *regcache)
   return pc;
 }
 
+/* Fetch the entry MATCH from the auxv vector, where entries are length
+   WORDSIZE.  If no entry was found, return zero.  */
+
+static CORE_ADDR
+linux_get_auxv (int wordsize, CORE_ADDR match)
+{
+  gdb_byte *data = (gdb_byte *) alloca (2 * wordsize);
+  int offset = 0;
+
+  gdb_assert (wordsize == 4 || wordsize == 8);
+
+  while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
+    {
+      if (wordsize == 4)
+       {
+         uint32_t *data_p = (uint32_t *)data;
+         if (data_p[0] == match)
+           return data_p[1];
+       }
+      else
+       {
+         uint64_t *data_p = (uint64_t *)data;
+         if (data_p[0] == match)
+           return data_p[1];
+       }
+
+      offset += 2 * wordsize;
+    }
+
+  return 0;
+}
+
+/* See linux-low.h.  */
+
+CORE_ADDR
+linux_get_hwcap (int wordsize)
+{
+  return linux_get_auxv (wordsize, AT_HWCAP);
+}
+
+/* See linux-low.h.  */
+
+CORE_ADDR
+linux_get_hwcap2 (int wordsize)
+{
+  return linux_get_auxv (wordsize, AT_HWCAP2);
+}
 
 static struct target_ops linux_target_ops = {
   linux_create_inferior,
index 1ade35d64850f86168c0a0043165bc681c20721f..d825184835d9965a629a1ad0294a8c5d3389a893 100644 (file)
@@ -435,4 +435,14 @@ bool thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len);
 
 extern int have_ptrace_getregset;
 
+/* Fetch the AT_HWCAP entry from the auxv vector, where entries are length
+   WORDSIZE.  If no entry was found, return zero.  */
+
+CORE_ADDR linux_get_hwcap (int wordsize);
+
+/* Fetch the AT_HWCAP2 entry from the auxv vector, where entries are length
+   WORDSIZE.  If no entry was found, return zero.  */
+
+CORE_ADDR linux_get_hwcap2 (int wordsize);
+
 #endif /* GDBSERVER_LINUX_LOW_H */
index 1b695e53fe9ba3eb857fbdea5bba9f5aaa80bbd0..8deb0ce068b2c75d56f8bf69eea815053af3071b 100644 (file)
@@ -323,43 +323,6 @@ ppc_set_pc (struct regcache *regcache, CORE_ADDR pc)
     }
 }
 
-
-static int
-ppc_get_auxv (unsigned long type, unsigned long *valp)
-{
-  const struct target_desc *tdesc = current_process ()->tdesc;
-  int wordsize = register_size (tdesc, 0);
-  unsigned char *data = (unsigned char *) alloca (2 * wordsize);
-  int offset = 0;
-
-  while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
-    {
-      if (wordsize == 4)
-       {
-         unsigned int *data_p = (unsigned int *)data;
-         if (data_p[0] == type)
-           {
-             *valp = data_p[1];
-             return 1;
-           }
-       }
-      else
-       {
-         unsigned long *data_p = (unsigned long *)data;
-         if (data_p[0] == type)
-           {
-             *valp = data_p[1];
-             return 1;
-           }
-       }
-
-      offset += 2 * wordsize;
-    }
-
-  *valp = 0;
-  return 0;
-}
-
 #ifndef __powerpc64__
 static int ppc_regmap_adjusted;
 #endif
@@ -944,8 +907,8 @@ ppc_arch_setup (void)
 
   /* The value of current_process ()->tdesc needs to be set for this
      call.  */
-  ppc_get_auxv (AT_HWCAP, &ppc_hwcap);
-  ppc_get_auxv (AT_HWCAP2, &ppc_hwcap2);
+  ppc_hwcap = linux_get_hwcap (features.wordsize);
+  ppc_hwcap2 = linux_get_hwcap2 (features.wordsize);
 
   features.isa205 = ppc_linux_has_isa205 (ppc_hwcap);
 
index edbef77fe90d2af34896c408991ef9ebac9e86cd..f65a1ec38efd0faef3b0a5c7a52a725d54161e5c 100644 (file)
@@ -467,36 +467,6 @@ s390_set_pc (struct regcache *regcache, CORE_ADDR newpc)
     }
 }
 
-/* Get HWCAP from AUXV, using the given WORDSIZE.  Return the HWCAP, or
-   zero if not found.  */
-
-static unsigned long
-s390_get_hwcap (int wordsize)
-{
-  gdb_byte *data = (gdb_byte *) alloca (2 * wordsize);
-  int offset = 0;
-
-  while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
-    {
-      if (wordsize == 4)
-        {
-          unsigned int *data_p = (unsigned int *)data;
-          if (data_p[0] == AT_HWCAP)
-           return data_p[1];
-        }
-      else
-        {
-          unsigned long *data_p = (unsigned long *)data;
-          if (data_p[0] == AT_HWCAP)
-           return data_p[1];
-        }
-
-      offset += 2 * wordsize;
-    }
-
-  return 0;
-}
-
 /* Determine the word size for the given PID, in bytes.  */
 
 #ifdef __s390x__
@@ -548,7 +518,7 @@ s390_arch_setup (void)
   /* Determine word size and HWCAP.  */
   int pid = pid_of (current_thread);
   int wordsize = s390_get_wordsize (pid);
-  unsigned long hwcap = s390_get_hwcap (wordsize);
+  unsigned long hwcap = linux_get_hwcap (wordsize);
 
   /* Check whether the kernel supports extra register sets.  */
   int have_regset_last_break