[PowerPC] Disable regsets using zero sizes in gdbserver
authorPedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com>
Tue, 22 May 2018 14:09:05 +0000 (11:09 -0300)
committerPedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com>
Tue, 22 May 2018 14:52:02 +0000 (11:52 -0300)
Currently the linux-ppc-low.c fill/store functions for extended
regsets check whether they should execute by using the global hwcap
variable.

This patch explicitly sets the regset sizes to zero when needed to
disable them instead, so that the fill/store functions are not called
in the first place by regsets_fetch_inferior_registers in linux-low.c.

gdb/gdbserver/ChangeLog:
2018-05-22  Pedro Franco de Carvalho  <pedromfc@linux.vnet.ibm.com>

* linux-ppc-low.c (ppc_fill_vsxregset): Remove ppc_hwcap check.
(ppc_store_vsxregset): Likewise.
(ppc_fill_vrregset): Likewise.
(ppc_store_vrregset): Likewise.
(ppc_fill_evrregset): Likewise.
(ppc_store_evrregset): Likewise.
(ppc_regsets): Set VSX/VR/EVR regset sizes to 0.
(ppc_arch_setup): Iterate through ppc_regsets and set sizes when
needed.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-ppc-low.c

index 7d8b704592915a6df6806fc043f5acdaf3a46400..9149c2faa322d1287f21040c69547c8e80469506 100644 (file)
@@ -1,3 +1,15 @@
+2018-05-22  Pedro Franco de Carvalho  <pedromfc@linux.vnet.ibm.com>
+
+       * linux-ppc-low.c (ppc_fill_vsxregset): Remove ppc_hwcap check.
+       (ppc_store_vsxregset): Likewise.
+       (ppc_fill_vrregset): Likewise.
+       (ppc_store_vrregset): Likewise.
+       (ppc_fill_evrregset): Likewise.
+       (ppc_store_evrregset): Likewise.
+       (ppc_regsets): Set VSX/VR/EVR regset sizes to 0.
+       (ppc_arch_setup): Iterate through ppc_regsets and set sizes when
+       needed.
+
 2018-05-22  Pedro Franco de Carvalho  <pedromfc@linux.vnet.ibm.com>
 
        * linux-ppc-low.c (ppc_arch_setup): Remove code for getting the
index 30fcd4115ab86f9e74704ba449348e2ba00ee980..b440b0e0a7339a1da368678a0702d4d535fbad7a 100644 (file)
@@ -467,9 +467,6 @@ ppc_fill_vsxregset (struct regcache *regcache, void *buf)
   int i, base;
   char *regset = (char *) buf;
 
-  if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX))
-    return;
-
   base = find_regno (regcache->tdesc, "vs0h");
   for (i = 0; i < 32; i++)
     collect_register (regcache, base + i, &regset[i * 8]);
@@ -481,9 +478,6 @@ ppc_store_vsxregset (struct regcache *regcache, const void *buf)
   int i, base;
   const char *regset = (const char *) buf;
 
-  if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX))
-    return;
-
   base = find_regno (regcache->tdesc, "vs0h");
   for (i = 0; i < 32; i++)
     supply_register (regcache, base + i, &regset[i * 8]);
@@ -497,9 +491,6 @@ ppc_fill_vrregset (struct regcache *regcache, void *buf)
   int i, base;
   char *regset = (char *) buf;
 
-  if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
-    return;
-
   base = find_regno (regcache->tdesc, "vr0");
   for (i = 0; i < 32; i++)
     collect_register (regcache, base + i, &regset[i * 16]);
@@ -514,9 +505,6 @@ ppc_store_vrregset (struct regcache *regcache, const void *buf)
   int i, base;
   const char *regset = (const char *) buf;
 
-  if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
-    return;
-
   base = find_regno (regcache->tdesc, "vr0");
   for (i = 0; i < 32; i++)
     supply_register (regcache, base + i, &regset[i * 16]);
@@ -538,9 +526,6 @@ ppc_fill_evrregset (struct regcache *regcache, void *buf)
   int i, ev0;
   struct gdb_evrregset_t *regset = (struct gdb_evrregset_t *) buf;
 
-  if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
-    return;
-
   ev0 = find_regno (regcache->tdesc, "ev0h");
   for (i = 0; i < 32; i++)
     collect_register (regcache, ev0 + i, &regset->evr[i]);
@@ -555,9 +540,6 @@ ppc_store_evrregset (struct regcache *regcache, const void *buf)
   int i, ev0;
   const struct gdb_evrregset_t *regset = (const struct gdb_evrregset_t *) buf;
 
-  if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
-    return;
-
   ev0 = find_regno (regcache->tdesc, "ev0h");
   for (i = 0; i < 32; i++)
     supply_register (regcache, ev0 + i, &regset->evr[i]);
@@ -579,11 +561,11 @@ static struct regset_info ppc_regsets[] = {
      fetch them every time, but still fall back to PTRACE_PEEKUSER for the
      general registers.  Some kernels support these, but not the newer
      PPC_PTRACE_GETREGS.  */
-  { PTRACE_GETVSXREGS, PTRACE_SETVSXREGS, 0, SIZEOF_VSXREGS, EXTENDED_REGS,
+  { PTRACE_GETVSXREGS, PTRACE_SETVSXREGS, 0, 0, EXTENDED_REGS,
   ppc_fill_vsxregset, ppc_store_vsxregset },
-  { PTRACE_GETVRREGS, PTRACE_SETVRREGS, 0, SIZEOF_VRREGS, EXTENDED_REGS,
+  { PTRACE_GETVRREGS, PTRACE_SETVRREGS, 0, 0, EXTENDED_REGS,
     ppc_fill_vrregset, ppc_store_vrregset },
-  { PTRACE_GETEVRREGS, PTRACE_SETEVRREGS, 0, 32 * 4 + 8 + 4, EXTENDED_REGS,
+  { PTRACE_GETEVRREGS, PTRACE_SETEVRREGS, 0, 0, EXTENDED_REGS,
     ppc_fill_evrregset, ppc_store_evrregset },
   { 0, 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL },
   NULL_REGSET
@@ -619,7 +601,9 @@ static void
 ppc_arch_setup (void)
 {
   const struct target_desc *tdesc;
+  struct regset_info *regset;
   struct ppc_linux_features features = ppc_linux_no_features;
+
   int tid = lwpid_of (current_thread);
 
   features.wordsize = ppc_linux_target_wordsize (tid);
@@ -671,6 +655,25 @@ ppc_arch_setup (void)
 #endif
 
   current_process ()->tdesc = tdesc;
+
+  for (regset = ppc_regsets; regset->size >= 0; regset++)
+    switch (regset->get_request)
+      {
+      case PTRACE_GETVRREGS:
+       regset->size = features.altivec ? SIZEOF_VRREGS : 0;
+       break;
+      case PTRACE_GETVSXREGS:
+       regset->size = features.vsx ? SIZEOF_VSXREGS : 0;
+       break;
+      case PTRACE_GETEVRREGS:
+       if (ppc_hwcap & PPC_FEATURE_HAS_SPE)
+         regset->size = 32 * 4 + 8 + 4;
+       else
+         regset->size = 0;
+       break;
+      default:
+       break;
+      }
 }
 
 /* Implementation of linux_target_ops method "supports_tracepoints".  */