X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fscore-tdep.c;h=9cd50380e8e7d0f2a911c473478f09b284476520;hb=558e5469679897ee57ad6706074f55ff4952cf43;hp=c224189d16b76a5f95ef346a64b17939d1ba8b5b;hpb=8fea322418c158d096d930c0d0057c684f1fc7ca;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/score-tdep.c b/gdb/score-tdep.c index c224189d16..9cd50380e8 100644 --- a/gdb/score-tdep.c +++ b/gdb/score-tdep.c @@ -1,7 +1,7 @@ /* Target-dependent code for the S+core architecture, for GDB, the GNU Debugger. - Copyright (C) 2006-2014 Free Software Foundation, Inc. + Copyright (C) 2006-2015 Free Software Foundation, Inc. Contributed by Qinwei (qinwei@sunnorth.com.cn) Contributed by Ching-Peng Lin (cplin@sunplus.com) @@ -22,7 +22,6 @@ along with this program. If not, see . */ #include "defs.h" -#include "gdb_assert.h" #include "inferior.h" #include "symtab.h" #include "objfiles.h" @@ -1398,75 +1397,64 @@ score_prologue_frame_base_sniffer (struct frame_info *this_frame) return &score_prologue_frame_base; } -/* Core file support (dirty hack) - - The core file MUST be generated by GNU/Linux on S+core. */ +/* Core file support. */ + +static const struct regcache_map_entry score7_linux_gregmap[] = + { + /* FIXME: According to the current Linux kernel, r0 is preceded by + 9 rather than 7 words. */ + { 7, REGCACHE_MAP_SKIP, 4 }, + { 32, 0, 4 }, /* r0 ... r31 */ + { 1, 55, 4 }, /* CEL */ + { 1, 54, 4 }, /* CEH */ + { 1, 53, 4 }, /* sr0, i.e. cnt or COUNTER */ + { 1, 52, 4 }, /* sr1, i.e. lcr or LDCR */ + { 1, 51, 4 }, /* sr2, i.e. scr or STCR */ + { 1, 49, 4 }, /* PC (same slot as EPC) */ + { 1, 38, 4 }, /* EMA */ + { 1, 32, 4 }, /* PSR */ + { 1, 34, 4 }, /* ECR */ + { 1, 33, 4 }, /* COND */ + { 0 } + }; + +#define SCORE7_LINUX_EPC_OFFSET (44 * 4) +#define SCORE7_LINUX_SIZEOF_GREGSET (49 * 4) static void score7_linux_supply_gregset(const struct regset *regset, - struct regcache *regcache, - int regnum, const void *gregs_buf, size_t len) + struct regcache *regcache, + int regnum, const void *buf, + size_t size) { - int regno; - elf_gregset_t *gregs; - - gdb_assert (regset != NULL); - gdb_assert ((regcache != NULL) && (gregs_buf != NULL)); - - gregs = (elf_gregset_t *) gregs_buf; - - for (regno = 0; regno < 32; regno++) - if (regnum == -1 || regnum == regno) - regcache_raw_supply (regcache, regno, gregs->regs + regno); - - { - struct sreg { - int regnum; - void *buf; - } sregs [] = { - { 55, &(gregs->cel) }, /* CEL */ - { 54, &(gregs->ceh) }, /* CEH */ - { 53, &(gregs->sr0) }, /* sr0, i.e. cnt or COUNTER */ - { 52, &(gregs->sr1) }, /* sr1, i.e. lcr or LDCR */ - { 51, &(gregs->sr1) }, /* sr2, i.e. scr or STCR */ - - /* Exception occured at this address, exactly the PC we want */ - { 49, &(gregs->cp0_epc) }, /* PC */ - - { 38, &(gregs->cp0_ema) }, /* EMA */ - { 37, &(gregs->cp0_epc) }, /* EPC */ - { 34, &(gregs->cp0_ecr) }, /* ECR */ - { 33, &(gregs->cp0_condition) }, /* COND */ - { 32, &(gregs->cp0_psr) }, /* PSR */ - }; - - for (regno = 0; regno < sizeof(sregs)/sizeof(sregs[0]); regno++) - if (regnum == -1 || regnum == sregs[regno].regnum) - regcache_raw_supply (regcache, - sregs[regno].regnum, sregs[regno].buf); - } + regcache_supply_regset (regset, regcache, regnum, buf, size); + + /* Supply the EPC from the same slot as the PC. Note that the + collect function will store the PC in that slot. */ + if ((regnum == -1 || regnum == SCORE_EPC_REGNUM) + && size >= SCORE7_LINUX_EPC_OFFSET + 4) + regcache_raw_supply (regcache, SCORE_EPC_REGNUM, + (const gdb_byte *) buf + + SCORE7_LINUX_EPC_OFFSET); } static const struct regset score7_linux_gregset = { - NULL, - score7_linux_supply_gregset, NULL + score7_linux_gregmap, + score7_linux_supply_gregset, + regcache_collect_regset }; -/* Return the appropriate register set from the core section identified - by SECT_NAME and SECT_SIZE. */ +/* Iterate over core file register note sections. */ -static const struct regset * -score7_linux_regset_from_core_section(struct gdbarch *gdbarch, - const char *sect_name, size_t sect_size) +static void +score7_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, + iterate_over_regset_sections_cb *cb, + void *cb_data, + const struct regcache *regcache) { - gdb_assert (gdbarch != NULL); - gdb_assert (sect_name != NULL); - - if (strcmp(sect_name, ".reg") == 0 && sect_size == sizeof(elf_gregset_t)) - return &score7_linux_gregset; - - return NULL; + cb (".reg", SCORE7_LINUX_SIZEOF_GREGSET, &score7_linux_gregset, + NULL, cb_data); } static struct gdbarch * @@ -1511,8 +1499,8 @@ score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_name (gdbarch, score7_register_name); set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS); /* Core file support. */ - set_gdbarch_regset_from_core_section (gdbarch, - score7_linux_regset_from_core_section); + set_gdbarch_iterate_over_regset_sections + (gdbarch, score7_linux_iterate_over_regset_sections); break; case bfd_mach_score3: