aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/m32r-linux-tdep.c79
2 files changed, 68 insertions, 18 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d4a51a2..ad32672 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
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...
(hppa_linux_gregmap): ... this. Also convert to
regcache_map_entry format.
diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c
index cf98f69..5499902 100644
--- a/gdb/m32r-linux-tdep.c
+++ b/gdb/m32r-linux-tdep.c
@@ -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 *