M32R Linux: Fill 'collect_regset' in regset structure.

This commit is contained in:
Andreas Arnez 2014-04-01 07:06:59 +00:00 committed by Ulrich Weigand
parent 0006a9dadf
commit ba199d7d3b
2 changed files with 68 additions and 18 deletions

View 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> 2014-08-07 Andreas Arnez <arnez@linux.vnet.ibm.com>
* hppa-linux-tdep.c (greg_map): Rename to... * hppa-linux-tdep.c (greg_map): Rename to...

View file

@ -349,14 +349,19 @@ m32r_linux_supply_gregset (const struct regset *regset,
struct regcache *regcache, int regnum, struct regcache *regcache, int regnum,
const void *gregs, size_t size) const void *gregs, size_t size)
{ {
const char *regs = gregs; const gdb_byte *regs = gregs;
unsigned long psw, bbpsw; 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; int i;
psw = *((unsigned long *) (regs + PSW_OFFSET)); psw = extract_unsigned_integer (regs + PSW_OFFSET, 4, byte_order);
bbpsw = *((unsigned long *) (regs + BBPSW_OFFSET)); 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) if (regnum != -1 && regnum != i)
continue; continue;
@ -364,30 +369,68 @@ m32r_linux_supply_gregset (const struct regset *regset,
switch (i) switch (i)
{ {
case PSW_REGNUM: case PSW_REGNUM:
*((unsigned long *) (regs + m32r_pt_regs_offset[i])) = store_unsigned_integer (buf, 4, byte_order, psw);
((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8); p = buf;
break; break;
case CBR_REGNUM: case CBR_REGNUM:
*((unsigned long *) (regs + m32r_pt_regs_offset[i])) = store_unsigned_integer (buf, 4, byte_order, psw & 1);
((psw >> 8) & 1); p = buf;
break; break;
case M32R_SP_REGNUM: case M32R_SP_REGNUM:
if (psw & 0x8000) p = regs + ((psw & 0x80) ? SPU_OFFSET : SPI_OFFSET);
*((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));
break; break;
default:
p = regs + m32r_pt_regs_offset[i];
} }
regcache_raw_supply (regcache, i, regcache_raw_supply (regcache, i, p);
regs + m32r_pt_regs_offset[i]); }
}
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 = { 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 * static const struct regset *