2003-03-02 Andrew Cagney * gdbarch.sh (UNWIND_SENTINEL_ID, UNWIND_SENTINEL_PC): New multi-arch methods with predicate. * gdbarch.h, gdbarch.c: Regenerate. * d10v-tdep.c (d10v_unwind_sentinel_id): New function. (d10v_unwind_sentinel_pc): New function. (d10v_gdbarch_init): Set unwind_sentinel_id and unwind_sentinel_pc. * sentinel-frame.c (struct frame_unwind_cache): Add field cache. (sentinel_frame_pc_unwind): Use gdbarch_unwind_sentinel_pc. (sentinel_frame_id_unwind): Use gdbarch_unwind_sentinel_id. Index: d10v-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/d10v-tdep.c,v retrieving revision 1.79 diff -u -r1.79 d10v-tdep.c --- d10v-tdep.c 1 Mar 2003 17:59:12 -0000 1.79 +++ d10v-tdep.c 2 Mar 2003 20:11:11 -0000 @@ -920,6 +920,15 @@ return retval; } +static CORE_ADDR +d10v_unwind_sentinel_pc (struct gdbarch *gdbarch, struct regcache *regcache, + void **cache) +{ + ULONGEST tmp; + regcache_cooked_read_unsigned (regcache, PC_REGNUM, &tmp); + return d10v_make_iaddr (tmp); +} + static void d10v_write_pc (CORE_ADDR val, ptid_t ptid) { @@ -949,6 +958,19 @@ return (d10v_make_daddr (read_register (FP_REGNUM))); } +static struct frame_id +d10v_unwind_sentinel_id (struct gdbarch *gdbarch, struct regcache *regcache, + void **cache) +{ + ULONGEST tmp; + struct frame_id id; + regcache_cooked_read_unsigned (regcache, FP_REGNUM, &tmp); + id.base = d10v_make_daddr (tmp); + regcache_cooked_read_unsigned (regcache, PC_REGNUM, &tmp); + id.pc = d10v_make_iaddr (tmp); + return id; +} + /* Function: push_return_address (pc) Set up the return address for the inferior function call. Needed for targets where we don't actually execute a JSR/BSR instruction */ @@ -1639,6 +1661,9 @@ set_gdbarch_read_fp (gdbarch, d10v_read_fp); set_gdbarch_read_sp (gdbarch, d10v_read_sp); set_gdbarch_write_sp (gdbarch, d10v_write_sp); + + set_gdbarch_unwind_sentinel_id (gdbarch, d10v_unwind_sentinel_id); + set_gdbarch_unwind_sentinel_pc (gdbarch, d10v_unwind_sentinel_pc); set_gdbarch_num_regs (gdbarch, d10v_num_regs); set_gdbarch_sp_regnum (gdbarch, 15); Index: gdbarch.sh =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.sh,v retrieving revision 1.198 diff -u -r1.198 gdbarch.sh --- gdbarch.sh 2 Mar 2003 04:02:23 -0000 1.198 +++ gdbarch.sh 2 Mar 2003 20:11:38 -0000 @@ -431,6 +431,10 @@ f:2:TARGET_READ_FP:CORE_ADDR:read_fp:void:::0:generic_target_read_fp::0 f:2:TARGET_READ_SP:CORE_ADDR:read_sp:void:::0:generic_target_read_sp::0 f:2:TARGET_WRITE_SP:void:write_sp:CORE_ADDR val:val::0:generic_target_write_sp::0 +# Unwind the sentinel frame's ID/PC returning the PC/ID of the inner +# most frame. +M::UNWIND_SENTINEL_ID:struct frame_id:unwind_sentinel_id:struct regcache *regcache, void **cache:regcache, cache::0:0 +M::UNWIND_SENTINEL_PC:CORE_ADDR:unwind_sentinel_pc:struct regcache *regcache, void **cache:regcache, cache::0:0 # Function for getting target's idea of a frame pointer. FIXME: GDB's # whole scheme for dealing with "frames" and "frame pointers" needs a # serious shakedown. Index: sentinel-frame.c =================================================================== RCS file: /cvs/src/src/gdb/sentinel-frame.c,v retrieving revision 1.2 diff -u -r1.2 sentinel-frame.c --- sentinel-frame.c 27 Jan 2003 21:41:41 -0000 1.2 +++ sentinel-frame.c 2 Mar 2003 20:11:40 -0000 @@ -31,6 +31,7 @@ struct frame_unwind_cache { struct regcache *regcache; + void *cache; }; void * @@ -72,26 +73,44 @@ CORE_ADDR sentinel_frame_pc_unwind (struct frame_info *frame, - void **cache) + void **unwind_cache) { - /* FIXME: cagney/2003-01-08: This should be using a per-architecture - method that doesn't suffer from DECR_PC_AFTER_BREAK problems. - Such a method would take unwind_cache, regcache and stop reason - parameters. */ - return read_pc (); + struct frame_unwind_cache *cache = *unwind_cache; + if (gdbarch_unwind_sentinel_pc_p (current_gdbarch)) + { + return gdbarch_unwind_sentinel_pc (current_gdbarch, cache->regcache, + &cache->cache); + } + else + { + /* FIXME: cagney/2003-01-08: This should be using a + per-architecture method that doesn't suffer from + DECR_PC_AFTER_BREAK problems. Such a method would take + unwind_cache, regcache and stop reason parameters. */ + return read_pc (); + } } void sentinel_frame_id_unwind (struct frame_info *frame, - void **cache, + void **unwind_cache, struct frame_id *id) { - /* FIXME: cagney/2003-01-08: This should be using a per-architecture - method that doesn't suffer from DECR_PC_AFTER_BREAK problems. - Such a method would take unwind_cache, regcache and stop reason - parameters. */ - id->base = read_fp (); - id->pc = read_pc (); + struct frame_unwind_cache *cache = *unwind_cache; + if (gdbarch_unwind_sentinel_id_p (current_gdbarch)) + { + (*id) = gdbarch_unwind_sentinel_id (current_gdbarch, cache->regcache, + &cache->cache); + } + else + { + /* FIXME: cagney/2003-01-08: This should be using a + per-architecture method that doesn't suffer from + DECR_PC_AFTER_BREAK problems. Such a method would take + unwind_cache, regcache and stop reason parameters. */ + id->base = read_fp (); + id->pc = read_pc (); + } } static void