From 7ce16bd4c4d5e6f6a48ca7fcf532720fec0406bf Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Thu, 17 Apr 2014 14:09:49 +0200 Subject: [PATCH] Enable DWARF unwinders for SPU MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patch enables use of DWARF unwinders for the SPU target. In addition to appending the DWARF unwinders, we also need to install a spu_dwarf_reg_to_regnum that maps the raw stack pointer register to the cooked version (to avoid mismatches with gdbarch_sp_regnum). This also causes confusion with the AX collect handling, so we also install ax_pseudo_register routines to handle the cooked SP. gdb/ 2014-04-17 Ulrich Weigand  * spu-tdep.c: Include "dwarf2-frame.h" and "ax.h". (spu_ax_pseudo_register_collect): New function. (spu_ax_pseudo_register_push_stack): Likewise. (spu_dwarf_reg_to_regnum): Likewise. (spu_gdbarch_init): Install them. Append DWARF unwinders. --- gdb/ChangeLog | 8 ++++++++ gdb/spu-tdep.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f0a77be..b00cca9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 2014-04-17 Ulrich Weigand  + * spu-tdep.c: Include "dwarf2-frame.h" and "ax.h". + (spu_ax_pseudo_register_collect): New function. + (spu_ax_pseudo_register_push_stack): Likewise. + (spu_dwarf_reg_to_regnum): Likewise. + (spu_gdbarch_init): Install them. Append DWARF unwinders. + +2014-04-17 Ulrich Weigand  + * gdbarch.sh (value_from_register): Make class "m" instead of "f". Replace FRAME argument with FRAME_ID. * gdbarch.c, gdbarch.h: Regenerate. diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c index 0f23b0f..4fc3ca5 100644 --- a/gdb/spu-tdep.c +++ b/gdb/spu-tdep.c @@ -44,6 +44,8 @@ #include "observer.h" #include "infcall.h" #include "dwarf2.h" +#include "dwarf2-frame.h" +#include "ax.h" #include "exceptions.h" #include "spu-tdep.h" @@ -311,6 +313,51 @@ spu_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, } } +static int +spu_ax_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, int regnum) +{ + switch (regnum) + { + case SPU_SP_REGNUM: + ax_reg_mask (ax, SPU_RAW_SP_REGNUM); + return 0; + + case SPU_FPSCR_REGNUM: + case SPU_SRR0_REGNUM: + case SPU_LSLR_REGNUM: + case SPU_DECR_REGNUM: + case SPU_DECR_STATUS_REGNUM: + return -1; + + default: + internal_error (__FILE__, __LINE__, _("invalid regnum")); + } +} + +static int +spu_ax_pseudo_register_push_stack (struct gdbarch *gdbarch, + struct agent_expr *ax, int regnum) +{ + switch (regnum) + { + case SPU_SP_REGNUM: + ax_reg (ax, SPU_RAW_SP_REGNUM); + return 0; + + case SPU_FPSCR_REGNUM: + case SPU_SRR0_REGNUM: + case SPU_LSLR_REGNUM: + case SPU_DECR_REGNUM: + case SPU_DECR_STATUS_REGNUM: + return -1; + + default: + internal_error (__FILE__, __LINE__, _("invalid regnum")); + } +} + + /* Value conversion -- access scalar values at the preferred slot. */ static struct value * @@ -352,6 +399,15 @@ spu_register_reggroup_p (struct gdbarch *gdbarch, int regnum, return default_register_reggroup_p (gdbarch, regnum, group); } +/* DWARF-2 register numbers. */ + +static int +spu_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) +{ + /* Use cooked instead of raw SP. */ + return (reg == SPU_RAW_SP_REGNUM)? SPU_SP_REGNUM : reg; +} + /* Address handling. */ @@ -2680,6 +2736,11 @@ spu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pseudo_register_write (gdbarch, spu_pseudo_register_write); set_gdbarch_value_from_register (gdbarch, spu_value_from_register); set_gdbarch_register_reggroup_p (gdbarch, spu_register_reggroup_p); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, spu_dwarf_reg_to_regnum); + set_gdbarch_ax_pseudo_register_collect + (gdbarch, spu_ax_pseudo_register_collect); + set_gdbarch_ax_pseudo_register_push_stack + (gdbarch, spu_ax_pseudo_register_push_stack); /* Data types. */ set_gdbarch_char_signed (gdbarch, 0); @@ -2718,6 +2779,7 @@ spu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Frame handling. */ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + dwarf2_append_unwinders (gdbarch); frame_unwind_append_unwinder (gdbarch, &spu_frame_unwind); frame_base_set_default (gdbarch, &spu_frame_base); set_gdbarch_unwind_pc (gdbarch, spu_unwind_pc); -- 2.7.4