diff options
author | Wei-cheng Wang <cole945@gmail.com> | 2015-03-31 00:30:31 +0800 |
---|---|---|
committer | Marcin KoĆcielnicki <koriakin@0x04.net> | 2016-02-24 04:16:46 +0100 |
commit | 50ae56ec464580492a5f987f658acc6ad82131b6 (patch) | |
tree | 1e1948e7c4b5b50c41ee75a2871e6aec14089803 /gdb/rs6000-tdep.c | |
parent | d79587bd21361b152621f0db6e20c19adb075158 (diff) | |
download | binutils-gdb-50ae56ec464580492a5f987f658acc6ad82131b6.tar.gz |
Build unavailable-stack frames for tracepoint.
gdb/ChangeLog:
2016-02-24 Wei-cheng Wang <cole945@gmail.com>
* rs6000-tdep.c (rs6000_frame_cache, rs6000_frame_this_id): Handle
unavailable PC/SP to build unavailable frame.
Diffstat (limited to 'gdb/rs6000-tdep.c')
-rw-r--r-- | gdb/rs6000-tdep.c | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 599b0768a9a..a56b8b638d2 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -3191,6 +3191,13 @@ struct rs6000_frame_cache CORE_ADDR base; CORE_ADDR initial_sp; struct trad_frame_saved_reg *saved_regs; + + /* Set BASE_P to true if this frame cache is properly initialized. + Otherwise set to false because some registers or memory cannot + collected. */ + int base_p; + /* Cache PC for building unavailable frame. */ + CORE_ADDR pc; }; static struct rs6000_frame_cache * @@ -3208,21 +3215,33 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) return (struct rs6000_frame_cache *) (*this_cache); cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache); (*this_cache) = cache; + cache->pc = 0; cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); - func = get_frame_func (this_frame); - pc = get_frame_pc (this_frame); - skip_prologue (gdbarch, func, pc, &fdata); - - /* Figure out the parent's stack pointer. */ - - /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most - address of the current frame. Things might be easier if the - ->frame pointed to the outer-most address of the frame. In - the mean time, the address of the prev frame is used as the - base address of this frame. */ - cache->base = get_frame_register_unsigned - (this_frame, gdbarch_sp_regnum (gdbarch)); + TRY + { + func = get_frame_func (this_frame); + cache->pc = func; + pc = get_frame_pc (this_frame); + skip_prologue (gdbarch, func, pc, &fdata); + + /* Figure out the parent's stack pointer. */ + + /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most + address of the current frame. Things might be easier if the + ->frame pointed to the outer-most address of the frame. In + the mean time, the address of the prev frame is used as the + base address of this frame. */ + cache->base = get_frame_register_unsigned + (this_frame, gdbarch_sp_regnum (gdbarch)); + } + CATCH (ex, RETURN_MASK_ERROR) + { + if (ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); + return (*this_cache); + } + END_CATCH /* If the function appears to be frameless, check a couple of likely indicators that we have simply failed to find the frame setup. @@ -3371,6 +3390,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) cache->initial_sp = get_frame_register_unsigned (this_frame, fdata.alloca_reg); + cache->base_p = 1; return cache; } @@ -3380,6 +3400,13 @@ rs6000_frame_this_id (struct frame_info *this_frame, void **this_cache, { struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame, this_cache); + + if (!info->base_p) + { + (*this_id) = frame_id_build_unavailable_stack (info->pc); + return; + } + /* This marks the outermost frame. */ if (info->base == 0) return; |