From ba199d7d3b21c201d73cdbf108b41f62c9b18ab0 Mon Sep 17 00:00:00 2001 From: Andreas Arnez Date: Tue, 1 Apr 2014 07:06:59 +0000 Subject: [PATCH] M32R Linux: Fill 'collect_regset' in regset structure. --- gdb/ChangeLog | 7 ++++ gdb/m32r-linux-tdep.c | 79 +++++++++++++++++++++++++++++++++---------- 2 files changed, 68 insertions(+), 18 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d4a51a2fbe..ad32672110 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2014-08-07 Andreas Arnez + + * 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 * hppa-linux-tdep.c (greg_map): Rename to... diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c index cf98f69d47..5499902a02 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 * -- 2.34.1