From 9b098f24af69b10358b2254bd1a71f070d3e2514 Mon Sep 17 00:00:00 2001 From: Kazuhiro Inaoka Date: Fri, 12 Nov 2004 01:00:41 +0000 Subject: [PATCH] 2004-11-12 Kei Sakamoto * Makefile.in (m32r-linux-tdep.o): Update dependencies. * m32r-linux-tdep.c (m32r_linux_init_abi): Call set_gdbarch_regset_from_core_section for core file support. (m32r_linux_supply_gregset, m32r_linux_regset_from_core_section): New functions. --- gdb/ChangeLog | 8 ++++ gdb/Makefile.in | 2 +- gdb/m32r-linux-tdep.c | 96 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index dcd83bfd1f7..23f8a6134fd 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2004-11-12 Kei Sakamoto + + * Makefile.in (m32r-linux-tdep.o): Update dependencies. + * m32r-linux-tdep.c (m32r_linux_init_abi): Call + set_gdbarch_regset_from_core_section for core file support. + (m32r_linux_supply_gregset, m32r_linux_regset_from_core_section): + New functions. + 2004-11-11 Randolph Chung * hppa-tdep.c (skip_prologue_hard_way): Make static, add diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 42da792e8c7..0f93ca834ef 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -2157,7 +2157,7 @@ m32r-linux-nat.o: m32r-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \ m32r-linux-tdep.o: m32r-linux-tdep.c $(defs_h) $(gdbcore_h) $(frame_h) \ $(value_h) $(regcache_h) $(inferior_h) $(osabi_h) $(reggroups_h) \ $(gdb_string_h) $(glibc_tdep_h) $(solib_svr4_h) $(trad_frame_h) \ - $(frame_unwind_h) $(m32r_tdep_h) + $(frame_unwind_h) $(regset_h) $(m32r_tdep_h) m32r-rom.o: m32r-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \ $(serial_h) $(symtab_h) $(command_h) $(gdbcmd_h) $(symfile_h) \ $(gdb_string_h) $(objfiles_h) $(inferior_h) $(regcache_h) diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c index d2ca1a928f4..d60d8fa977f 100644 --- a/gdb/m32r-linux-tdep.c +++ b/gdb/m32r-linux-tdep.c @@ -27,6 +27,7 @@ #include "inferior.h" #include "osabi.h" #include "reggroups.h" +#include "regset.h" #include "gdb_string.h" @@ -309,6 +310,97 @@ m32r_linux_sigtramp_frame_sniffer (struct frame_info *next_frame) return NULL; } +/* Mapping between the registers in `struct pt_regs' + format and GDB's register array layout. */ + +static int m32r_pt_regs_offset[] = { + 4 * 4, /* r0 */ + 4 * 5, /* r1 */ + 4 * 6, /* r2 */ + 4 * 7, /* r3 */ + 4 * 0, /* r4 */ + 4 * 1, /* r5 */ + 4 * 2, /* r6 */ + 4 * 8, /* r7 */ + 4 * 9, /* r8 */ + 4 * 10, /* r9 */ + 4 * 11, /* r10 */ + 4 * 12, /* r11 */ + 4 * 13, /* r12 */ + 4 * 24, /* fp */ + 4 * 25, /* lr */ + 4 * 23, /* sp */ + 4 * 19, /* psw */ + 4 * 19, /* cbr */ + 4 * 26, /* spi */ + 4 * 23, /* spu */ + 4 * 22, /* bpc */ + 4 * 20, /* pc */ + 4 * 16, /* accl */ + 4 * 15 /* acch */ +}; + +#define PSW_OFFSET (4 * 19) +#define BBPSW_OFFSET (4 * 21) +#define SPU_OFFSET (4 * 23) +#define SPI_OFFSET (4 * 26) + +static void +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; + int i; + + psw = *((unsigned long *) (regs + PSW_OFFSET)); + bbpsw = *((unsigned long *) (regs + BBPSW_OFFSET)); + + for (i = 0; i < sizeof (m32r_pt_regs_offset) / 4; i++) + { + if (regnum != -1 && regnum != i) + continue; + + switch (i) + { + case PSW_REGNUM: + *((unsigned long *) (regs + m32r_pt_regs_offset[i])) = + ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8); + break; + case CBR_REGNUM: + *((unsigned long *) (regs + m32r_pt_regs_offset[i])) = + ((psw >> 8) & 1); + 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)); + break; + } + + regcache_raw_supply (current_regcache, i, + regs + m32r_pt_regs_offset[i]); + } +} + +static struct regset m32r_linux_gregset = { + NULL, m32r_linux_supply_gregset +}; + +static const struct regset * +m32r_linux_regset_from_core_section (struct gdbarch *core_arch, + const char *sect_name, size_t sect_size) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (core_arch); + if (strcmp (sect_name, ".reg") == 0) + return &m32r_linux_gregset; + return NULL; +} + static void m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -323,6 +415,10 @@ m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* GNU/Linux uses SVR4-style shared libraries. */ set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_ilp32_fetch_link_map_offsets); + + /* Core file support. */ + set_gdbarch_regset_from_core_section + (gdbarch, m32r_linux_regset_from_core_section); } /* Provide a prototype to silence -Wmissing-prototypes. */ -- 2.30.2