M32R Linux: Fill 'collect_regset' in regset structure.
authorAndreas Arnez <arnez@linux.vnet.ibm.com>
Tue, 1 Apr 2014 07:06:59 +0000 (07:06 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Thu, 7 Aug 2014 15:31:49 +0000 (17:31 +0200)
gdb/ChangeLog
gdb/m32r-linux-tdep.c

index d4a51a2fbe80a75da30c568ccdfaa200d053741f..ad32672110a684db0bdf5ac38a07867faf0de83f 100644 (file)
@@ -1,3 +1,10 @@
+2014-08-07  Andreas Arnez  <arnez@linux.vnet.ibm.com>
+
+       * m32r-linux-tdep.c (m32r_linux_supply_gregset): Make
+       platform-independent and don't write to read-only input buffer.
+       (m32r_linux_collect_gregset): New function.
+       (m32r_linux_gregset): Add collect method.
+
 2014-08-07  Andreas Arnez  <arnez@linux.vnet.ibm.com>
 
        * hppa-linux-tdep.c (greg_map): Rename to...
index cf98f69d47cb5cfde228c3768f72ee94c5050742..5499902a022948e047b6ead5fcd2649c422a178b 100644 (file)
@@ -349,14 +349,19 @@ m32r_linux_supply_gregset (const struct regset *regset,
                           struct regcache *regcache, int regnum,
                           const void *gregs, size_t size)
 {
-  const char *regs = gregs;
-  unsigned long psw, bbpsw;
+  const gdb_byte *regs = gregs;
+  enum bfd_endian byte_order =
+    gdbarch_byte_order (get_regcache_arch (regcache));
+  ULONGEST psw, bbpsw;
+  gdb_byte buf[4];
+  const gdb_byte *p;
   int i;
 
-  psw = *((unsigned long *) (regs + PSW_OFFSET));
-  bbpsw = *((unsigned long *) (regs + BBPSW_OFFSET));
+  psw = extract_unsigned_integer (regs + PSW_OFFSET, 4, byte_order);
+  bbpsw = extract_unsigned_integer (regs + BBPSW_OFFSET, 4, byte_order);
+  psw = ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8);
 
-  for (i = 0; i < sizeof (m32r_pt_regs_offset) / 4; i++)
+  for (i = 0; i < ARRAY_SIZE (m32r_pt_regs_offset); i++)
     {
       if (regnum != -1 && regnum != i)
        continue;
@@ -364,30 +369,68 @@ m32r_linux_supply_gregset (const struct regset *regset,
       switch (i)
        {
        case PSW_REGNUM:
-         *((unsigned long *) (regs + m32r_pt_regs_offset[i])) =
-           ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8);
+         store_unsigned_integer (buf, 4, byte_order, psw);
+         p = buf;
          break;
        case CBR_REGNUM:
-         *((unsigned long *) (regs + m32r_pt_regs_offset[i])) =
-           ((psw >> 8) & 1);
+         store_unsigned_integer (buf, 4, byte_order, psw & 1);
+         p = buf;
          break;
        case M32R_SP_REGNUM:
-         if (psw & 0x8000)
-           *((unsigned long *) (regs + m32r_pt_regs_offset[i])) =
-             *((unsigned long *) (regs + SPU_OFFSET));
-         else
-           *((unsigned long *) (regs + m32r_pt_regs_offset[i])) =
-             *((unsigned long *) (regs + SPI_OFFSET));
+         p = regs + ((psw & 0x80) ? SPU_OFFSET : SPI_OFFSET);
          break;
+       default:
+         p = regs + m32r_pt_regs_offset[i];
        }
 
-      regcache_raw_supply (regcache, i,
-                          regs + m32r_pt_regs_offset[i]);
+      regcache_raw_supply (regcache, i, p);
+    }
+}
+
+static void
+m32r_linux_collect_gregset (const struct regset *regset,
+                           const struct regcache *regcache,
+                           int regnum, void *gregs, size_t size)
+{
+  gdb_byte *regs = gregs;
+  int i;
+  enum bfd_endian byte_order =
+    gdbarch_byte_order (get_regcache_arch (regcache));
+  ULONGEST psw;
+  gdb_byte buf[4];
+
+  regcache_raw_collect (regcache, PSW_REGNUM, buf);
+  psw = extract_unsigned_integer (buf, 4, byte_order);
+
+  for (i = 0; i < ARRAY_SIZE (m32r_pt_regs_offset); i++)
+    {
+      if (regnum != -1 && regnum != i)
+       continue;
+
+      switch (i)
+       {
+       case PSW_REGNUM:
+         store_unsigned_integer (regs + PSW_OFFSET, 4, byte_order,
+                                 (psw & 0xc1) << 8);
+         store_unsigned_integer (regs + BBPSW_OFFSET, 4, byte_order,
+                                 (psw >> 8) & 0xc1);
+         break;
+       case CBR_REGNUM:
+         break;
+       case M32R_SP_REGNUM:
+         regcache_raw_collect (regcache, i, regs
+                               + ((psw & 0x80) ? SPU_OFFSET : SPI_OFFSET));
+         break;
+       default:
+         regcache_raw_collect (regcache, i,
+                               regs + m32r_pt_regs_offset[i]);
+       }
     }
 }
 
 static const struct regset m32r_linux_gregset = {
-  NULL, m32r_linux_supply_gregset
+  NULL,
+  m32r_linux_supply_gregset, m32r_linux_collect_gregset
 };
 
 static const struct regset *