diff options
author | Pedro Alves <palves@redhat.com> | 2011-03-18 18:52:32 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2011-03-18 18:52:32 +0000 |
commit | 8fbca658f0643a6c3d5b61840351ae70e5bf2db6 (patch) | |
tree | 29aac28e10802153b6d0a1575797c7fc1f4a6146 | |
parent | 8661b11b1820e3cc09a19c9ac0b195d18f2f8638 (diff) | |
download | fsf-binutils-gdb-8fbca658f0643a6c3d5b61840351ae70e5bf2db6.zip fsf-binutils-gdb-8fbca658f0643a6c3d5b61840351ae70e5bf2db6.tar.gz fsf-binutils-gdb-8fbca658f0643a6c3d5b61840351ae70e5bf2db6.tar.bz2 |
gdb/
* frame.c (frame_unwind_register): Throw an error if unwinding the
register failed.
* get_prev_frame_1 (get_prev_frame_1): Ask the unwinder if there's
an unwind stop reason.
(frame_stop_reason_string): Handle UNWIND_UNAVAILABLE.
* frame.h (enum unwind_stop_reason) <UNWIND_OUTERMOST,
UNWIND_UNAVAILABLE>: New.
* inline-frame.c (inline_frame_unwind): Install
default_frame_unwind_stop_reason.
* frame-unwind.c: Include "exceptions.h".
(frame_unwind_find_by_frame): Swallow NOT_AVAILABLE_ERROR errors.
(default_frame_unwind_stop_reason): New.
* frame-unwind.h (frame_unwind_stop_reason_ftype): New typedef.
(default_frame_unwind_stop_reason): Declare.
(struct frame_unwind) <stop_reason>: New function pointer.
* dummy-frame.c: Install default_frame_unwind_stop_reason.
* dwarf2-frame.c: Include exceptions.h.
(struct dwarf2_frame_cache) <unavailable_retaddr>: New field.
(dwarf2_frame_cache): Swallow NOT_AVAILABLE_ERROR errors when
computing the CFA. If such an error was thrown, set
unavailable_retaddr.
(dwarf2_frame_unwind_stop_reason): New.
(dwarf2_frame_this_id): Don't build a frame id if the CFA was
unavailable.
(dwarf2_frame_unwind): Install dwarf2_frame_unwind_stop_reason.
(dwarf2_signal_frame_unwind): Ditto.
* amd64-tdep.c: Include "exceptions.h".
(struct amd64_frame_cache): New field "base_p".
(amd64_init_frame_cache): Clear it.
(amd64_frame_cache_1): New, factored out from amd64_frame_cache.
Avoid reading registers with functions that throw if the register
is not necessary to compute the frame base.
(amd64_frame_cache): Reimplement wrapping amd64_frame_cache_1, and
swallowing NOT_AVAILABLE_ERROR.
(amd64_frame_unwind_stop_reason): New.
(amd64_frame_this_id): Don't build a frame id if the frame base
was unavailable.
(amd64_frame_unwind): Install amd64_frame_unwind_stop_reason.
(amd64_sigtramp_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set
base_p if the frame base was computable.
(amd64_sigtramp_frame_unwind_stop_reason): New.
(amd64_sigtramp_frame_this_id): Don't build a frame id if the
frame base was unavailable.
(amd64_sigtramp_frame_unwind): Install
amd64_sigtramp_frame_unwind_stop_reason.
(amd64_epilogue_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set
base_p if the frame base was computable.
(amd64_epilogue_frame_unwind_stop_reason): New.
(amd64_epilogue_frame_this_id): Don't build a frame id if the
frame base was unavailable.
(amd64_epilogue_frame_unwind): Install
amd64_epilogue_frame_unwind_stop_reason.
* i386-tdep.c: Include "exceptions.h".
(struct i386_frame_cache): New field "base_p".
(i386_init_frame_cache): Clear it.
(i386_frame_cache_1): New, factored out from amd64_frame_cache.
Avoid reading registers with functions that throw if the register
is not necessary to compute the frame base.
(i386_frame_cache): Reimplement wrapping amd64_frame_cache_1, and
swallowing NOT_AVAILABLE_ERROR.
(i386_frame_unwind_stop_reason): New.
(i386_frame_this_id): Don't build a frame id if the frame base was
unavailable.
(i386_frame_prev_register): Handle unavailable SP.
(i386_frame_unwind): Install i386_frame_unwind_stop_reason.
(i386_epilogue_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set
base_p if the frame base was computable.
(i386_epilogue_frame_unwind_stop_reason): New.
(i386_epilogue_frame_this_id): Don't build a frame id if the frame
base was unavailable.
(i386_epilogue_frame_unwind): Install
i386_epilogue_frame_unwind_stop_reason.
(i386_sigtramp_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set
base_p if the frame base was computable.
(i386_sigtramp_frame_unwind_stop_reason): New.
(i386_sigtramp_frame_this_id): Don't build a frame id if the frame
base was unavailable.
(i386_sigtramp_frame_unwind): Install
i386_sigtramp_frame_unwind_stop_reason.
* sentinel-frame.c (sentinel_frame_prev_register): Use the value
type's size, not the register's.
(sentinel_frame_unwind): Install default_frame_unwind_stop_reason.
* alpha-mdebug-tdep.c (alpha_mdebug_frame_unwind): Install
default_frame_unwind_stop_reason.
* alpha-tdep.c (alpha_sigtramp_frame_unwind)
(alpha_heuristic_frame_unwind): Ditto.
* amd64obsd-tdep.c (amd64obsd_trapframe_unwind): Ditto.
* arm-tdep.c (arm_prologue_unwind, arm_stub_unwind): Ditto.
* avr-tdep.c (avr_frame_unwind): Ditto.
* cris-tdep.c (cris_sigtramp_frame_unwind, cris_frame_unwind):
Ditto.
* frv-linux-tdep.c (frv_linux_sigtramp_frame_unwind): Ditto.
* frv-tdep.c (frv_frame_unwind): Ditto.
* h8300-tdep.c (h8300_frame_unwind): Ditto.
* hppa-hpux-tdep.c (hppa_hpux_sigtramp_frame_unwind): Ditto.
* hppa-linux-tdep.c (hppa_linux_sigtramp_frame_unwind): Ditto.
* hppa-tdep.c (hppa_frame_unwind, hppa_fallback_frame_unwind)
(hppa_stub_frame_unwind): Ditto.
* i386obsd-tdep.c (i386obsd_trapframe_unwind): Ditto.
* ia64-tdep.c (ia64_frame_unwind, ia64_sigtramp_frame_unwind)
(ia64_libunwind_frame_unwind)
(ia64_libunwind_sigtramp_frame_unwind): Ditto.
* iq2000-tdep.c (iq2000_frame_unwind): Ditto.
* lm32-tdep.c (lm32_frame_unwind): Ditto.
* m32c-tdep.c (m32c_unwind): Ditto.
* m32r-linux-tdep.c (m32r_linux_sigtramp_frame_unwind): Ditto.
* m32r-tdep.c (m32r_frame_unwind): Ditto.
* m68hc11-tdep.c (m68hc11_frame_unwind): Ditto.
* m68k-tdep.c (m68k_frame_unwind): Ditto.
* m68klinux-tdep.c (m68k_linux_sigtramp_frame_unwind): Ditto.
* m88k-tdep.c (m88k_frame_unwind): Ditto.
* mep-tdep.c (mep_frame_unwind): Ditto.
* microblaze-tdep.c (microblaze_frame_unwind): Ditto.
* mips-tdep.c (mips_insn16_frame_unwind, mips_insn32_frame_unwind)
(mips_stub_frame_unwind): Ditto.
* mn10300-tdep.c (mn10300_frame_unwind): Ditto.
* moxie-tdep.c (moxie_frame_unwind): Ditto.
* mt-tdep.c (mt_frame_unwind): Ditto.
* ppc-linux-tdep.c (ppu2spu_unwind): Ditto.
* ppcobsd-tdep.c (ppcobsd_sigtramp_frame_unwind): Ditto.
* rs6000-tdep.c (rs6000_frame_unwind): Ditto.
* s390-tdep.c (s390_frame_unwind, s390_stub_frame_unwind)
(s390_sigtramp_frame_unwind): Ditto.
* score-tdep.c (score_prologue_unwind): Ditto.
* sh-tdep.c (sh_frame_unwind): Ditto.
* sh64-tdep.c (sh64_frame_unwind): Ditto.
* sparc-sol2-tdep.c (sparc32_sol2_sigtramp_frame_unwind): Ditto.
* sparc-tdep.c (sparc32_frame_unwind): Ditto.
* sparc64-sol2-tdep.c (sparc64_sol2_sigtramp_frame_unwind): Ditto.
* sparc64-tdep.c (sparc64_frame_unwind): Ditto.
* sparc64fbsd-tdep.c (sparc64fbsd_sigtramp_frame_unwind): Ditto.
* sparc64nbsd-tdep.c (sparc64nbsd_sigcontext_frame_unwind): Ditto.
* sparc64obsd-tdep.c (sparc64obsd_frame_unwind)
(sparc64obsd_trapframe_unwind): Ditto.
* sparcnbsd-tdep.c (sparc32nbsd_sigcontext_frame_unwind): Ditto.
* sparcobsd-tdep.c (sparc32obsd_sigtramp_frame_unwind): Ditto.
* spu-tdep.c (spu_frame_unwind, spu2ppu_unwind): Ditto.
* v850-tdep.c (v850_frame_unwind): Ditto.
* vax-tdep.c (vax_frame_unwind): Ditto.
* vaxobsd-tdep.c (vaxobsd_sigtramp_frame_unwind): Ditto.
* xstormy16-tdep.c (frame_unwind xstormy16_frame_unwind): Ditto.
* xtensa-tdep.c (xtensa_unwind): Ditto.
63 files changed, 617 insertions, 109 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0dbc501..64d8391 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,151 @@ +2012-03-18 Pedro Alves <pedro@codesourcery.com> + + * frame.c (frame_unwind_register): Throw an error if unwinding the + register failed. + * get_prev_frame_1 (get_prev_frame_1): Ask the unwinder if there's + an unwind stop reason. + (frame_stop_reason_string): Handle UNWIND_UNAVAILABLE. + * frame.h (enum unwind_stop_reason) <UNWIND_OUTERMOST, + UNWIND_UNAVAILABLE>: New. + * inline-frame.c (inline_frame_unwind): Install + default_frame_unwind_stop_reason. + * frame-unwind.c: Include "exceptions.h". + (frame_unwind_find_by_frame): Swallow NOT_AVAILABLE_ERROR errors. + (default_frame_unwind_stop_reason): New. + * frame-unwind.h (frame_unwind_stop_reason_ftype): New typedef. + (default_frame_unwind_stop_reason): Declare. + (struct frame_unwind) <stop_reason>: New function pointer. + + * dummy-frame.c: Install default_frame_unwind_stop_reason. + * dwarf2-frame.c: Include exceptions.h. + (struct dwarf2_frame_cache) <unavailable_retaddr>: New field. + (dwarf2_frame_cache): Swallow NOT_AVAILABLE_ERROR errors when + computing the CFA. If such an error was thrown, set + unavailable_retaddr. + (dwarf2_frame_unwind_stop_reason): New. + (dwarf2_frame_this_id): Don't build a frame id if the CFA was + unavailable. + (dwarf2_frame_unwind): Install dwarf2_frame_unwind_stop_reason. + (dwarf2_signal_frame_unwind): Ditto. + + * amd64-tdep.c: Include "exceptions.h". + (struct amd64_frame_cache): New field "base_p". + (amd64_init_frame_cache): Clear it. + (amd64_frame_cache_1): New, factored out from amd64_frame_cache. + Avoid reading registers with functions that throw if the register + is not necessary to compute the frame base. + (amd64_frame_cache): Reimplement wrapping amd64_frame_cache_1, and + swallowing NOT_AVAILABLE_ERROR. + (amd64_frame_unwind_stop_reason): New. + (amd64_frame_this_id): Don't build a frame id if the frame base + was unavailable. + (amd64_frame_unwind): Install amd64_frame_unwind_stop_reason. + (amd64_sigtramp_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set + base_p if the frame base was computable. + (amd64_sigtramp_frame_unwind_stop_reason): New. + (amd64_sigtramp_frame_this_id): Don't build a frame id if the + frame base was unavailable. + (amd64_sigtramp_frame_unwind): Install + amd64_sigtramp_frame_unwind_stop_reason. + (amd64_epilogue_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set + base_p if the frame base was computable. + (amd64_epilogue_frame_unwind_stop_reason): New. + (amd64_epilogue_frame_this_id): Don't build a frame id if the + frame base was unavailable. + (amd64_epilogue_frame_unwind): Install + amd64_epilogue_frame_unwind_stop_reason. + * i386-tdep.c: Include "exceptions.h". + (struct i386_frame_cache): New field "base_p". + (i386_init_frame_cache): Clear it. + (i386_frame_cache_1): New, factored out from amd64_frame_cache. + Avoid reading registers with functions that throw if the register + is not necessary to compute the frame base. + (i386_frame_cache): Reimplement wrapping amd64_frame_cache_1, and + swallowing NOT_AVAILABLE_ERROR. + (i386_frame_unwind_stop_reason): New. + (i386_frame_this_id): Don't build a frame id if the frame base was + unavailable. + (i386_frame_prev_register): Handle unavailable SP. + (i386_frame_unwind): Install i386_frame_unwind_stop_reason. + (i386_epilogue_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set + base_p if the frame base was computable. + (i386_epilogue_frame_unwind_stop_reason): New. + (i386_epilogue_frame_this_id): Don't build a frame id if the frame + base was unavailable. + (i386_epilogue_frame_unwind): Install + i386_epilogue_frame_unwind_stop_reason. + (i386_sigtramp_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set + base_p if the frame base was computable. + (i386_sigtramp_frame_unwind_stop_reason): New. + (i386_sigtramp_frame_this_id): Don't build a frame id if the frame + base was unavailable. + (i386_sigtramp_frame_unwind): Install + i386_sigtramp_frame_unwind_stop_reason. + * sentinel-frame.c (sentinel_frame_prev_register): Use the value + type's size, not the register's. + (sentinel_frame_unwind): Install default_frame_unwind_stop_reason. + + * alpha-mdebug-tdep.c (alpha_mdebug_frame_unwind): Install + default_frame_unwind_stop_reason. + * alpha-tdep.c (alpha_sigtramp_frame_unwind) + (alpha_heuristic_frame_unwind): Ditto. + * amd64obsd-tdep.c (amd64obsd_trapframe_unwind): Ditto. + * arm-tdep.c (arm_prologue_unwind, arm_stub_unwind): Ditto. + * avr-tdep.c (avr_frame_unwind): Ditto. + * cris-tdep.c (cris_sigtramp_frame_unwind, cris_frame_unwind): + Ditto. + * frv-linux-tdep.c (frv_linux_sigtramp_frame_unwind): Ditto. + * frv-tdep.c (frv_frame_unwind): Ditto. + * h8300-tdep.c (h8300_frame_unwind): Ditto. + * hppa-hpux-tdep.c (hppa_hpux_sigtramp_frame_unwind): Ditto. + * hppa-linux-tdep.c (hppa_linux_sigtramp_frame_unwind): Ditto. + * hppa-tdep.c (hppa_frame_unwind, hppa_fallback_frame_unwind) + (hppa_stub_frame_unwind): Ditto. + * i386obsd-tdep.c (i386obsd_trapframe_unwind): Ditto. + * ia64-tdep.c (ia64_frame_unwind, ia64_sigtramp_frame_unwind) + (ia64_libunwind_frame_unwind) + (ia64_libunwind_sigtramp_frame_unwind): Ditto. + * iq2000-tdep.c (iq2000_frame_unwind): Ditto. + * lm32-tdep.c (lm32_frame_unwind): Ditto. + * m32c-tdep.c (m32c_unwind): Ditto. + * m32r-linux-tdep.c (m32r_linux_sigtramp_frame_unwind): Ditto. + * m32r-tdep.c (m32r_frame_unwind): Ditto. + * m68hc11-tdep.c (m68hc11_frame_unwind): Ditto. + * m68k-tdep.c (m68k_frame_unwind): Ditto. + * m68klinux-tdep.c (m68k_linux_sigtramp_frame_unwind): Ditto. + * m88k-tdep.c (m88k_frame_unwind): Ditto. + * mep-tdep.c (mep_frame_unwind): Ditto. + * microblaze-tdep.c (microblaze_frame_unwind): Ditto. + * mips-tdep.c (mips_insn16_frame_unwind, mips_insn32_frame_unwind) + (mips_stub_frame_unwind): Ditto. + * mn10300-tdep.c (mn10300_frame_unwind): Ditto. + * moxie-tdep.c (moxie_frame_unwind): Ditto. + * mt-tdep.c (mt_frame_unwind): Ditto. + * ppc-linux-tdep.c (ppu2spu_unwind): Ditto. + * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_unwind): Ditto. + * rs6000-tdep.c (rs6000_frame_unwind): Ditto. + * s390-tdep.c (s390_frame_unwind, s390_stub_frame_unwind) + (s390_sigtramp_frame_unwind): Ditto. + * score-tdep.c (score_prologue_unwind): Ditto. + * sh-tdep.c (sh_frame_unwind): Ditto. + * sh64-tdep.c (sh64_frame_unwind): Ditto. + * sparc-sol2-tdep.c (sparc32_sol2_sigtramp_frame_unwind): Ditto. + * sparc-tdep.c (sparc32_frame_unwind): Ditto. + * sparc64-sol2-tdep.c (sparc64_sol2_sigtramp_frame_unwind): Ditto. + * sparc64-tdep.c (sparc64_frame_unwind): Ditto. + * sparc64fbsd-tdep.c (sparc64fbsd_sigtramp_frame_unwind): Ditto. + * sparc64nbsd-tdep.c (sparc64nbsd_sigcontext_frame_unwind): Ditto. + * sparc64obsd-tdep.c (sparc64obsd_frame_unwind) + (sparc64obsd_trapframe_unwind): Ditto. + * sparcnbsd-tdep.c (sparc32nbsd_sigcontext_frame_unwind): Ditto. + * sparcobsd-tdep.c (sparc32obsd_sigtramp_frame_unwind): Ditto. + * spu-tdep.c (spu_frame_unwind, spu2ppu_unwind): Ditto. + * v850-tdep.c (v850_frame_unwind): Ditto. + * vax-tdep.c (vax_frame_unwind): Ditto. + * vaxobsd-tdep.c (vaxobsd_sigtramp_frame_unwind): Ditto. + * xstormy16-tdep.c (frame_unwind xstormy16_frame_unwind): Ditto. + * xtensa-tdep.c (xtensa_unwind): Ditto. + 2011-03-18 Pedro Alves <pedro@codesourcery.com> * tui/tui-hooks.c (tui_selected_frame_level_changed_hook): Assume diff --git a/gdb/alpha-mdebug-tdep.c b/gdb/alpha-mdebug-tdep.c index 8773437..f48a121 100644 --- a/gdb/alpha-mdebug-tdep.c +++ b/gdb/alpha-mdebug-tdep.c @@ -336,6 +336,7 @@ alpha_mdebug_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind alpha_mdebug_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, alpha_mdebug_frame_this_id, alpha_mdebug_frame_prev_register, NULL, diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 2f309a7..51eb6e4 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -936,6 +936,7 @@ alpha_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind alpha_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, alpha_sigtramp_frame_this_id, alpha_sigtramp_frame_prev_register, NULL, @@ -1351,6 +1352,7 @@ alpha_heuristic_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind alpha_heuristic_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, alpha_heuristic_frame_this_id, alpha_heuristic_frame_prev_register, NULL, diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 54b1723..9b5d5bb 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -38,7 +38,7 @@ #include "symfile.h" #include "disasm.h" #include "gdb_assert.h" - +#include "exceptions.h" #include "amd64-tdep.h" #include "i387-tdep.h" @@ -1635,6 +1635,7 @@ struct amd64_frame_cache { /* Base address. */ CORE_ADDR base; + int base_p; CORE_ADDR sp_offset; CORE_ADDR pc; @@ -1656,6 +1657,7 @@ amd64_init_frame_cache (struct amd64_frame_cache *cache) /* Base address. */ cache->base = 0; + cache->base_p = 0; cache->sp_offset = -8; cache->pc = 0; @@ -1913,33 +1915,20 @@ amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) /* Normal frames. */ -static struct amd64_frame_cache * -amd64_frame_cache (struct frame_info *this_frame, void **this_cache) +static void +amd64_frame_cache_1 (struct frame_info *this_frame, + struct amd64_frame_cache *cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - struct amd64_frame_cache *cache; gdb_byte buf[8]; int i; - if (*this_cache) - return *this_cache; - - cache = amd64_alloc_frame_cache (); - *this_cache = cache; - cache->pc = get_frame_func (this_frame); if (cache->pc != 0) amd64_analyze_prologue (gdbarch, cache->pc, get_frame_pc (this_frame), cache); - if (cache->saved_sp_reg != -1) - { - /* Stack pointer has been saved. */ - get_frame_register (this_frame, cache->saved_sp_reg, buf); - cache->saved_sp = extract_unsigned_integer(buf, 8, byte_order); - } - if (cache->frameless_p) { /* We didn't find a valid frame. If we're at the start of a @@ -1951,6 +1940,10 @@ amd64_frame_cache (struct frame_info *this_frame, void **this_cache) if (cache->saved_sp_reg != -1) { + /* Stack pointer has been saved. */ + get_frame_register (this_frame, cache->saved_sp_reg, buf); + cache->saved_sp = extract_unsigned_integer (buf, 8, byte_order); + /* We're halfway aligning the stack. */ cache->base = ((cache->saved_sp - 8) & 0xfffffffffffffff0LL) - 8; cache->saved_regs[AMD64_RIP_REGNUM] = cache->saved_sp - 8; @@ -1988,9 +1981,48 @@ amd64_frame_cache (struct frame_info *this_frame, void **this_cache) if (cache->saved_regs[i] != -1) cache->saved_regs[i] += cache->base; + cache->base_p = 1; +} + +static struct amd64_frame_cache * +amd64_frame_cache (struct frame_info *this_frame, void **this_cache) +{ + volatile struct gdb_exception ex; + struct amd64_frame_cache *cache; + + if (*this_cache) + return *this_cache; + + cache = amd64_alloc_frame_cache (); + *this_cache = cache; + + TRY_CATCH (ex, RETURN_MASK_ERROR) + { + amd64_frame_cache_1 (this_frame, cache); + } + if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); + return cache; } +static enum unwind_stop_reason +amd64_frame_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache) +{ + struct amd64_frame_cache *cache = + amd64_frame_cache (this_frame, this_cache); + + if (!cache->base_p) + return UNWIND_UNAVAILABLE; + + /* This marks the outermost frame. */ + if (cache->base == 0) + return UNWIND_OUTERMOST; + + return UNWIND_NO_REASON; +} + static void amd64_frame_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) @@ -1998,6 +2030,9 @@ amd64_frame_this_id (struct frame_info *this_frame, void **this_cache, struct amd64_frame_cache *cache = amd64_frame_cache (this_frame, this_cache); + if (!cache->base_p) + return; + /* This marks the outermost frame. */ if (cache->base == 0) return; @@ -2028,6 +2063,7 @@ amd64_frame_prev_register (struct frame_info *this_frame, void **this_cache, static const struct frame_unwind amd64_frame_unwind = { NORMAL_FRAME, + amd64_frame_unwind_stop_reason, amd64_frame_this_id, amd64_frame_prev_register, NULL, @@ -2047,6 +2083,7 @@ amd64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + volatile struct gdb_exception ex; struct amd64_frame_cache *cache; CORE_ADDR addr; gdb_byte buf[8]; @@ -2057,20 +2094,40 @@ amd64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) cache = amd64_alloc_frame_cache (); - get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); - cache->base = extract_unsigned_integer (buf, 8, byte_order) - 8; + TRY_CATCH (ex, RETURN_MASK_ERROR) + { + get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 8, byte_order) - 8; + + addr = tdep->sigcontext_addr (this_frame); + gdb_assert (tdep->sc_reg_offset); + gdb_assert (tdep->sc_num_regs <= AMD64_NUM_SAVED_REGS); + for (i = 0; i < tdep->sc_num_regs; i++) + if (tdep->sc_reg_offset[i] != -1) + cache->saved_regs[i] = addr + tdep->sc_reg_offset[i]; - addr = tdep->sigcontext_addr (this_frame); - gdb_assert (tdep->sc_reg_offset); - gdb_assert (tdep->sc_num_regs <= AMD64_NUM_SAVED_REGS); - for (i = 0; i < tdep->sc_num_regs; i++) - if (tdep->sc_reg_offset[i] != -1) - cache->saved_regs[i] = addr + tdep->sc_reg_offset[i]; + cache->base_p = 1; + } + if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); *this_cache = cache; return cache; } +static enum unwind_stop_reason +amd64_sigtramp_frame_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache) +{ + struct amd64_frame_cache *cache = + amd64_sigtramp_frame_cache (this_frame, this_cache); + + if (!cache->base_p) + return UNWIND_UNAVAILABLE; + + return UNWIND_NO_REASON; +} + static void amd64_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) @@ -2078,6 +2135,9 @@ amd64_sigtramp_frame_this_id (struct frame_info *this_frame, struct amd64_frame_cache *cache = amd64_sigtramp_frame_cache (this_frame, this_cache); + if (!cache->base_p) + return; + (*this_id) = frame_id_build (cache->base + 16, get_frame_pc (this_frame)); } @@ -2124,6 +2184,7 @@ amd64_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind amd64_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + amd64_sigtramp_frame_unwind_stop_reason, amd64_sigtramp_frame_this_id, amd64_sigtramp_frame_prev_register, NULL, @@ -2185,6 +2246,7 @@ amd64_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + volatile struct gdb_exception ex; struct amd64_frame_cache *cache; gdb_byte buf[8]; @@ -2194,23 +2256,43 @@ amd64_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) cache = amd64_alloc_frame_cache (); *this_cache = cache; - /* Cache base will be %esp plus cache->sp_offset (-8). */ - get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); - cache->base = extract_unsigned_integer (buf, 8, - byte_order) + cache->sp_offset; + TRY_CATCH (ex, RETURN_MASK_ERROR) + { + /* Cache base will be %esp plus cache->sp_offset (-8). */ + get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 8, + byte_order) + cache->sp_offset; + + /* Cache pc will be the frame func. */ + cache->pc = get_frame_pc (this_frame); - /* Cache pc will be the frame func. */ - cache->pc = get_frame_pc (this_frame); + /* The saved %esp will be at cache->base plus 16. */ + cache->saved_sp = cache->base + 16; - /* The saved %esp will be at cache->base plus 16. */ - cache->saved_sp = cache->base + 16; + /* The saved %eip will be at cache->base plus 8. */ + cache->saved_regs[AMD64_RIP_REGNUM] = cache->base + 8; - /* The saved %eip will be at cache->base plus 8. */ - cache->saved_regs[AMD64_RIP_REGNUM] = cache->base + 8; + cache->base_p = 1; + } + if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); return cache; } +static enum unwind_stop_reason +amd64_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache) +{ + struct amd64_frame_cache *cache + = amd64_epilogue_frame_cache (this_frame, this_cache); + + if (!cache->base_p) + return UNWIND_UNAVAILABLE; + + return UNWIND_NO_REASON; +} + static void amd64_epilogue_frame_this_id (struct frame_info *this_frame, void **this_cache, @@ -2219,12 +2301,16 @@ amd64_epilogue_frame_this_id (struct frame_info *this_frame, struct amd64_frame_cache *cache = amd64_epilogue_frame_cache (this_frame, this_cache); + if (!cache->base_p) + return; + (*this_id) = frame_id_build (cache->base + 8, cache->pc); } static const struct frame_unwind amd64_epilogue_frame_unwind = { NORMAL_FRAME, + amd64_epilogue_frame_unwind_stop_reason, amd64_epilogue_frame_this_id, amd64_frame_prev_register, NULL, diff --git a/gdb/amd64obsd-tdep.c b/gdb/amd64obsd-tdep.c index f5dd259..2ff5c8f 100644 --- a/gdb/amd64obsd-tdep.c +++ b/gdb/amd64obsd-tdep.c @@ -437,6 +437,7 @@ static const struct frame_unwind amd64obsd_trapframe_unwind = { frame, but SIGTRAMP_FRAME would print <signal handler called>, which really is not what we want here. */ NORMAL_FRAME, + default_frame_unwind_stop_reason, amd64obsd_trapframe_this_id, amd64obsd_trapframe_prev_register, NULL, diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 0020b47..754c431 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -2146,6 +2146,7 @@ arm_prologue_prev_register (struct frame_info *this_frame, struct frame_unwind arm_prologue_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, arm_prologue_this_id, arm_prologue_prev_register, NULL, @@ -2884,6 +2885,7 @@ arm_exidx_unwind_sniffer (const struct frame_unwind *self, struct frame_unwind arm_exidx_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, arm_prologue_this_id, arm_prologue_prev_register, NULL, @@ -2939,6 +2941,7 @@ arm_stub_unwind_sniffer (const struct frame_unwind *self, struct frame_unwind arm_stub_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, arm_stub_this_id, arm_prologue_prev_register, NULL, diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index 31dd7df..20e7fca 100644 --- a/gdb/avr-tdep.c +++ b/gdb/avr-tdep.c @@ -1131,6 +1131,7 @@ avr_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind avr_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, avr_frame_this_id, avr_frame_prev_register, NULL, diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c index 8c0cb5a..8322af5 100644 --- a/gdb/bfin-tdep.c +++ b/gdb/bfin-tdep.c @@ -376,6 +376,7 @@ bfin_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind bfin_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, bfin_frame_this_id, bfin_frame_prev_register, NULL, diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c index f99eabd..f79e84c 100644 --- a/gdb/cris-tdep.c +++ b/gdb/cris-tdep.c @@ -448,6 +448,7 @@ cris_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind cris_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, cris_sigtramp_frame_this_id, cris_sigtramp_frame_prev_register, NULL, @@ -985,6 +986,7 @@ cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function, static const struct frame_unwind cris_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, cris_frame_this_id, cris_frame_prev_register, NULL, diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c index f63659f..709cd68 100644 --- a/gdb/dummy-frame.c +++ b/gdb/dummy-frame.c @@ -278,6 +278,7 @@ dummy_frame_this_id (struct frame_info *this_frame, const struct frame_unwind dummy_frame_unwind = { DUMMY_FRAME, + default_frame_unwind_stop_reason, dummy_frame_this_id, dummy_frame_prev_register, NULL, diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index edd6a9c..e78c328 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -40,6 +40,7 @@ #include "dwarf2-frame.h" #include "ax.h" #include "dwarf2loc.h" +#include "exceptions.h" struct comp_unit; @@ -986,6 +987,10 @@ struct dwarf2_frame_cache /* DWARF Call Frame Address. */ CORE_ADDR cfa; + /* Set if the return address column was marked as unavailable + (required non-collected memory or registers to compute). */ + int unavailable_retaddr; + /* Set if the return address column was marked as undefined. */ int undefined_retaddr; @@ -1013,6 +1018,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) struct dwarf2_frame_cache *cache; struct dwarf2_frame_state *fs; struct dwarf2_fde *fde; + volatile struct gdb_exception ex; if (*this_cache) return *this_cache; @@ -1020,10 +1026,10 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) /* Allocate a new cache. */ cache = FRAME_OBSTACK_ZALLOC (struct dwarf2_frame_cache); cache->reg = FRAME_OBSTACK_CALLOC (num_regs, struct dwarf2_frame_state_reg); + *this_cache = cache; /* Allocate and initialize the frame state. */ - fs = XMALLOC (struct dwarf2_frame_state); - memset (fs, 0, sizeof (struct dwarf2_frame_state)); + fs = XZALLOC (struct dwarf2_frame_state); old_chain = make_cleanup (dwarf2_frame_state_free, fs); /* Unwind the PC. @@ -1068,26 +1074,39 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, get_frame_pc (this_frame), fs); - /* Calculate the CFA. */ - switch (fs->regs.cfa_how) + TRY_CATCH (ex, RETURN_MASK_ERROR) { - case CFA_REG_OFFSET: - cache->cfa = read_reg (this_frame, fs->regs.cfa_reg); - if (fs->armcc_cfa_offsets_reversed) - cache->cfa -= fs->regs.cfa_offset; - else - cache->cfa += fs->regs.cfa_offset; - break; - - case CFA_EXP: - cache->cfa = - execute_stack_op (fs->regs.cfa_exp, fs->regs.cfa_exp_len, - cache->addr_size, cache->text_offset, - this_frame, 0, 0); - break; + /* Calculate the CFA. */ + switch (fs->regs.cfa_how) + { + case CFA_REG_OFFSET: + cache->cfa = read_reg (this_frame, fs->regs.cfa_reg); + if (fs->armcc_cfa_offsets_reversed) + cache->cfa -= fs->regs.cfa_offset; + else + cache->cfa += fs->regs.cfa_offset; + break; + + case CFA_EXP: + cache->cfa = + execute_stack_op (fs->regs.cfa_exp, fs->regs.cfa_exp_len, + cache->addr_size, cache->text_offset, + this_frame, 0, 0); + break; + + default: + internal_error (__FILE__, __LINE__, _("Unknown CFA rule.")); + } + } + if (ex.reason < 0) + { + if (ex.error == NOT_AVAILABLE_ERROR) + { + cache->unavailable_retaddr = 1; + return cache; + } - default: - internal_error (__FILE__, __LINE__, _("Unknown CFA rule.")); + throw_exception (ex); } /* Initialize the register state. */ @@ -1193,10 +1212,25 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"), do_cleanups (old_chain); - *this_cache = cache; return cache; } +static enum unwind_stop_reason +dwarf2_frame_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache) +{ + struct dwarf2_frame_cache *cache + = dwarf2_frame_cache (this_frame, this_cache); + + if (cache->unavailable_retaddr) + return UNWIND_UNAVAILABLE; + + if (cache->undefined_retaddr) + return UNWIND_OUTERMOST; + + return UNWIND_NO_REASON; +} + static void dwarf2_frame_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) @@ -1204,6 +1238,9 @@ dwarf2_frame_this_id (struct frame_info *this_frame, void **this_cache, struct dwarf2_frame_cache *cache = dwarf2_frame_cache (this_frame, this_cache); + if (cache->unavailable_retaddr) + return; + if (cache->undefined_retaddr) return; @@ -1321,6 +1358,7 @@ dwarf2_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind dwarf2_frame_unwind = { NORMAL_FRAME, + dwarf2_frame_unwind_stop_reason, dwarf2_frame_this_id, dwarf2_frame_prev_register, NULL, @@ -1330,6 +1368,7 @@ static const struct frame_unwind dwarf2_frame_unwind = static const struct frame_unwind dwarf2_signal_frame_unwind = { SIGTRAMP_FRAME, + dwarf2_frame_unwind_stop_reason, dwarf2_frame_this_id, dwarf2_frame_prev_register, NULL, diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c index 27a5350..cc04b30 100644 --- a/gdb/frame-unwind.c +++ b/gdb/frame-unwind.c @@ -25,7 +25,7 @@ #include "inline-frame.h" #include "value.h" #include "regcache.h" - +#include "exceptions.h" #include "gdb_assert.h" #include "gdb_obstack.h" @@ -103,14 +103,31 @@ frame_unwind_find_by_frame (struct frame_info *this_frame, void **this_cache) for (entry = table->list; entry != NULL; entry = entry->next) { struct cleanup *old_cleanup; + volatile struct gdb_exception ex; + int res = 0; old_cleanup = frame_prepare_for_sniffer (this_frame, entry->unwinder); - if (entry->unwinder->sniffer (entry->unwinder, this_frame, - this_cache)) + + TRY_CATCH (ex, RETURN_MASK_ERROR) { - discard_cleanups (old_cleanup); - return; + res = entry->unwinder->sniffer (entry->unwinder, this_frame, + this_cache); } + if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR) + { + /* This usually means that not even the PC is available, + thus most unwinders aren't able to determine if they're + the best fit. Keep trying. Fallback prologue unwinders + should always accept the frame. */ + } + else if (ex.reason < 0) + throw_exception (ex); + else if (res) + { + discard_cleanups (old_cleanup); + return; + } + do_cleanups (old_cleanup); } internal_error (__FILE__, __LINE__, _("frame_unwind_find_by_frame failed")); @@ -127,6 +144,16 @@ default_frame_sniffer (const struct frame_unwind *self, return 1; } +/* A default frame unwinder stop_reason callback that always claims + the frame is unwindable. */ + +enum unwind_stop_reason +default_frame_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache) +{ + return UNWIND_NO_REASON; +} + /* Helper functions for value-based register unwinding. These return a (possibly lazy) value of the appropriate type. */ diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h index e449766..5b04a1c 100644 --- a/gdb/frame-unwind.h +++ b/gdb/frame-unwind.h @@ -51,6 +51,9 @@ typedef int (frame_sniffer_ftype) (const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache); +typedef enum unwind_stop_reason (frame_unwind_stop_reason_ftype) + (struct frame_info *this_frame, void **this_prologue_cache); + /* A default frame sniffer which always accepts the frame. Used by fallback prologue unwinders. */ @@ -58,6 +61,13 @@ int default_frame_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache); +/* A default stop_reason callback which always claims the frame is + unwindable. */ + +enum unwind_stop_reason + default_frame_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache); + /* Assuming the frame chain: (outer) prev <-> this <-> next (inner); use THIS frame, and through it the NEXT frame's register unwind method, to determine the frame ID of THIS frame. @@ -136,6 +146,7 @@ struct frame_unwind enum frame_type type; /* Should an attribute indicating the frame's address-in-block go here? */ + frame_unwind_stop_reason_ftype *stop_reason; frame_this_id_ftype *this_id; frame_prev_register_ftype *prev_register; const struct frame_data *unwind_data; diff --git a/gdb/frame.c b/gdb/frame.c index a817e4d..7a35192 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -912,6 +912,12 @@ frame_unwind_register (struct frame_info *frame, int regnum, gdb_byte *buf) frame_register_unwind (frame, regnum, &optimized, &unavailable, &lval, &addr, &realnum, buf); + + if (optimized) + error (_("Register %d was optimized out"), regnum); + if (unavailable) + throw_error (NOT_AVAILABLE_ERROR, + _("Register %d is not available"), regnum); } void @@ -1607,6 +1613,15 @@ get_prev_frame_1 (struct frame_info *this_frame) if (get_frame_type (this_frame) == INLINE_FRAME) return get_prev_frame_raw (this_frame); + /* Check that this frame is unwindable. If it isn't, don't try to + unwind to the prev frame. */ + this_frame->stop_reason + = this_frame->unwind->stop_reason (this_frame, + &this_frame->prologue_cache); + + if (this_frame->stop_reason != UNWIND_NO_REASON) + return NULL; + /* Check that this frame's ID was valid. If it wasn't, don't try to unwind to the prev frame. Be careful to not apply this test to the sentinel frame. */ @@ -2333,6 +2348,9 @@ frame_stop_reason_string (enum unwind_stop_reason reason) case UNWIND_NULL_ID: return _("unwinder did not report frame ID"); + case UNWIND_UNAVAILABLE: + return _("Not enough registers or memory available to unwind further"); + case UNWIND_INNER_ID: return _("previous frame inner to this frame (corrupt stack?)"); diff --git a/gdb/frame.h b/gdb/frame.h index 7bc1148..a2052c0 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -457,12 +457,19 @@ enum unwind_stop_reason error. But that's a project for another day. */ UNWIND_NULL_ID, + /* This frame is the outermost. */ + UNWIND_OUTERMOST, + /* All the conditions after this point are considered errors; abnormal stack termination. If a backtrace stops for one of these reasons, we'll let the user know. This marker is not a valid stop reason. */ UNWIND_FIRST_ERROR, + /* Can't unwind further, because that would require knowing the + values of registers or memory that haven't been collected. */ + UNWIND_UNAVAILABLE, + /* This frame ID looks like it ought to belong to a NEXT frame, but we got it for a PREV frame. Normally, this is a sign of unwinder failure. It could also indicate stack corruption. */ diff --git a/gdb/frv-linux-tdep.c b/gdb/frv-linux-tdep.c index 924a06b..b13554b 100644 --- a/gdb/frv-linux-tdep.c +++ b/gdb/frv-linux-tdep.c @@ -336,6 +336,7 @@ frv_linux_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind frv_linux_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, frv_linux_sigtramp_frame_this_id, frv_linux_sigtramp_frame_prev_register, NULL, diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c index 66c25a8..98e6472 100644 --- a/gdb/frv-tdep.c +++ b/gdb/frv-tdep.c @@ -1494,6 +1494,7 @@ frv_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind frv_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, frv_frame_this_id, frv_frame_prev_register, NULL, diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c index 0b11df3..fa39dee 100644 --- a/gdb/h8300-tdep.c +++ b/gdb/h8300-tdep.c @@ -526,6 +526,7 @@ h8300_frame_prev_register (struct frame_info *this_frame, void **this_cache, static const struct frame_unwind h8300_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, h8300_frame_this_id, h8300_frame_prev_register, NULL, diff --git a/gdb/hppa-hpux-tdep.c b/gdb/hppa-hpux-tdep.c index b9761c3..00ccf70 100644 --- a/gdb/hppa-hpux-tdep.c +++ b/gdb/hppa-hpux-tdep.c @@ -753,6 +753,7 @@ hppa_hpux_sigtramp_unwind_sniffer (const struct frame_unwind *self, static const struct frame_unwind hppa_hpux_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, hppa_hpux_sigtramp_frame_this_id, hppa_hpux_sigtramp_frame_prev_register, NULL, diff --git a/gdb/hppa-linux-tdep.c b/gdb/hppa-linux-tdep.c index 355f8f9..e51fbcc 100644 --- a/gdb/hppa-linux-tdep.c +++ b/gdb/hppa-linux-tdep.c @@ -314,6 +314,7 @@ hppa_linux_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, hppa_linux_sigtramp_frame_this_id, hppa_linux_sigtramp_frame_prev_register, NULL, diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index df21fad..b22e3c0 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -2225,6 +2225,7 @@ hppa_frame_unwind_sniffer (const struct frame_unwind *self, static const struct frame_unwind hppa_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, hppa_frame_this_id, hppa_frame_prev_register, NULL, @@ -2335,6 +2336,7 @@ hppa_fallback_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind hppa_fallback_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, hppa_fallback_frame_this_id, hppa_fallback_frame_prev_register, NULL, @@ -2431,6 +2433,7 @@ hppa_stub_unwind_sniffer (const struct frame_unwind *self, static const struct frame_unwind hppa_stub_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, hppa_stub_frame_this_id, hppa_stub_frame_prev_register, NULL, diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 62df614..c7ad3a6 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -45,7 +45,7 @@ #include "dis-asm.h" #include "disasm.h" #include "remote.h" - +#include "exceptions.h" #include "gdb_assert.h" #include "gdb_string.h" @@ -804,6 +804,7 @@ struct i386_frame_cache { /* Base address. */ CORE_ADDR base; + int base_p; LONGEST sp_offset; CORE_ADDR pc; @@ -828,6 +829,7 @@ i386_alloc_frame_cache (void) cache = FRAME_OBSTACK_ZALLOC (struct i386_frame_cache); /* Base address. */ + cache->base_p = 0; cache->base = 0; cache->sp_offset = -4; cache->pc = 0; @@ -1608,20 +1610,16 @@ i386_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) /* Normal frames. */ -static struct i386_frame_cache * -i386_frame_cache (struct frame_info *this_frame, void **this_cache) +static void +i386_frame_cache_1 (struct frame_info *this_frame, + struct i386_frame_cache *cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - struct i386_frame_cache *cache; gdb_byte buf[4]; int i; - if (*this_cache) - return *this_cache; - - cache = i386_alloc_frame_cache (); - *this_cache = cache; + cache->pc = get_frame_func (this_frame); /* In principle, for normal frames, %ebp holds the frame pointer, which holds the base address for the current stack frame. @@ -1635,23 +1633,15 @@ i386_frame_cache (struct frame_info *this_frame, void **this_cache) get_frame_register (this_frame, I386_EBP_REGNUM, buf); cache->base = extract_unsigned_integer (buf, 4, byte_order); if (cache->base == 0) - return cache; + return; /* For normal frames, %eip is stored at 4(%ebp). */ cache->saved_regs[I386_EIP_REGNUM] = 4; - cache->pc = get_frame_func (this_frame); if (cache->pc != 0) i386_analyze_prologue (gdbarch, cache->pc, get_frame_pc (this_frame), cache); - if (cache->saved_sp_reg != -1) - { - /* Saved stack pointer has been saved. */ - get_frame_register (this_frame, cache->saved_sp_reg, buf); - cache->saved_sp = extract_unsigned_integer (buf, 4, byte_order); - } - if (cache->locals < 0) { /* We didn't find a valid frame, which means that CACHE->base @@ -1664,6 +1654,10 @@ i386_frame_cache (struct frame_info *this_frame, void **this_cache) if (cache->saved_sp_reg != -1) { + /* Saved stack pointer has been saved. */ + get_frame_register (this_frame, cache->saved_sp_reg, buf); + cache->saved_sp = extract_unsigned_integer (buf, 4, byte_order); + /* We're halfway aligning the stack. */ cache->base = ((cache->saved_sp - 4) & 0xfffffff0) - 4; cache->saved_regs[I386_EIP_REGNUM] = cache->saved_sp - 4; @@ -1691,9 +1685,17 @@ i386_frame_cache (struct frame_info *this_frame, void **this_cache) cache->saved_regs[I386_EBP_REGNUM] = 0; } + if (cache->saved_sp_reg != -1) + { + /* Saved stack pointer has been saved (but the SAVED_SP_REG + register may be unavailable). */ + if (cache->saved_sp == 0 + && frame_register_read (this_frame, cache->saved_sp_reg, buf)) + cache->saved_sp = extract_unsigned_integer (buf, 4, byte_order); + } /* Now that we have the base address for the stack frame we can calculate the value of %esp in the calling frame. */ - if (cache->saved_sp == 0) + else if (cache->saved_sp == 0) cache->saved_sp = cache->base + 8; /* Adjust all the saved registers such that they contain addresses @@ -1702,6 +1704,28 @@ i386_frame_cache (struct frame_info *this_frame, void **this_cache) if (cache->saved_regs[i] != -1) cache->saved_regs[i] += cache->base; + cache->base_p = 1; +} + +static struct i386_frame_cache * +i386_frame_cache (struct frame_info *this_frame, void **this_cache) +{ + volatile struct gdb_exception ex; + struct i386_frame_cache *cache; + + if (*this_cache) + return *this_cache; + + cache = i386_alloc_frame_cache (); + *this_cache = cache; + + TRY_CATCH (ex, RETURN_MASK_ERROR) + { + i386_frame_cache_1 (this_frame, cache); + } + if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); + return cache; } @@ -1719,6 +1743,22 @@ i386_frame_this_id (struct frame_info *this_frame, void **this_cache, (*this_id) = frame_id_build (cache->base + 8, cache->pc); } +static enum unwind_stop_reason +i386_frame_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache) +{ + struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache); + + if (!cache->base_p) + return UNWIND_UNAVAILABLE; + + /* This marks the outermost frame. */ + if (cache->base == 0) + return UNWIND_OUTERMOST; + + return UNWIND_NO_REASON; +} + static struct value * i386_frame_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) @@ -1758,8 +1798,18 @@ i386_frame_prev_register (struct frame_info *this_frame, void **this_cache, if (regnum == I386_EIP_REGNUM && cache->pc_in_eax) return frame_unwind_got_register (this_frame, regnum, I386_EAX_REGNUM); - if (regnum == I386_ESP_REGNUM && cache->saved_sp) - return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp); + if (regnum == I386_ESP_REGNUM) + { + /* If the SP has been saved, but we don't know where, then this + means that SAVED_SP_REG register was found unavailable back + when we built the cache. */ + if (cache->saved_sp == 0 && cache->saved_sp_reg != -1) + return frame_unwind_got_register (this_frame, regnum, + cache->saved_sp_reg); + else + return frame_unwind_got_constant (this_frame, regnum, + cache->saved_sp); + } if (regnum < I386_NUM_SAVED_REGS && cache->saved_regs[regnum] != -1) return frame_unwind_got_memory (this_frame, regnum, @@ -1771,6 +1821,7 @@ i386_frame_prev_register (struct frame_info *this_frame, void **this_cache, static const struct frame_unwind i386_frame_unwind = { NORMAL_FRAME, + i386_frame_unwind_stop_reason, i386_frame_this_id, i386_frame_prev_register, NULL, @@ -1814,6 +1865,7 @@ i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + volatile struct gdb_exception ex; struct i386_frame_cache *cache; gdb_byte buf[4]; @@ -1823,23 +1875,43 @@ i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) cache = i386_alloc_frame_cache (); *this_cache = cache; - /* Cache base will be %esp plus cache->sp_offset (-4). */ - get_frame_register (this_frame, I386_ESP_REGNUM, buf); - cache->base = extract_unsigned_integer (buf, 4, - byte_order) + cache->sp_offset; + TRY_CATCH (ex, RETURN_MASK_ERROR) + { + /* Cache base will be %esp plus cache->sp_offset (-4). */ + get_frame_register (this_frame, I386_ESP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 4, + byte_order) + cache->sp_offset; - /* Cache pc will be the frame func. */ - cache->pc = get_frame_pc (this_frame); + /* Cache pc will be the frame func. */ + cache->pc = get_frame_pc (this_frame); - /* The saved %esp will be at cache->base plus 8. */ - cache->saved_sp = cache->base + 8; + /* The saved %esp will be at cache->base plus 8. */ + cache->saved_sp = cache->base + 8; - /* The saved %eip will be at cache->base plus 4. */ - cache->saved_regs[I386_EIP_REGNUM] = cache->base + 4; + /* The saved %eip will be at cache->base plus 4. */ + cache->saved_regs[I386_EIP_REGNUM] = cache->base + 4; + + cache->base_p = 1; + } + if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); return cache; } +static enum unwind_stop_reason +i386_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache) +{ + struct i386_frame_cache *cache + = i386_epilogue_frame_cache (this_frame, this_cache); + + if (!cache->base_p) + return UNWIND_UNAVAILABLE; + + return UNWIND_NO_REASON; +} + static void i386_epilogue_frame_this_id (struct frame_info *this_frame, void **this_cache, @@ -1848,12 +1920,16 @@ i386_epilogue_frame_this_id (struct frame_info *this_frame, struct i386_frame_cache *cache = i386_epilogue_frame_cache (this_frame, this_cache); + if (!cache->base_p) + return; + (*this_id) = frame_id_build (cache->base + 8, cache->pc); } static const struct frame_unwind i386_epilogue_frame_unwind = { NORMAL_FRAME, + i386_epilogue_frame_unwind_stop_reason, i386_epilogue_frame_this_id, i386_frame_prev_register, NULL, @@ -1869,6 +1945,7 @@ i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + volatile struct gdb_exception ex; struct i386_frame_cache *cache; CORE_ADDR addr; gdb_byte buf[4]; @@ -1878,30 +1955,50 @@ i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) cache = i386_alloc_frame_cache (); - get_frame_register (this_frame, I386_ESP_REGNUM, buf); - cache->base = extract_unsigned_integer (buf, 4, byte_order) - 4; - - addr = tdep->sigcontext_addr (this_frame); - if (tdep->sc_reg_offset) + TRY_CATCH (ex, RETURN_MASK_ERROR) { - int i; + get_frame_register (this_frame, I386_ESP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 4, byte_order) - 4; - gdb_assert (tdep->sc_num_regs <= I386_NUM_SAVED_REGS); + addr = tdep->sigcontext_addr (this_frame); + if (tdep->sc_reg_offset) + { + int i; - for (i = 0; i < tdep->sc_num_regs; i++) - if (tdep->sc_reg_offset[i] != -1) - cache->saved_regs[i] = addr + tdep->sc_reg_offset[i]; - } - else - { - cache->saved_regs[I386_EIP_REGNUM] = addr + tdep->sc_pc_offset; - cache->saved_regs[I386_ESP_REGNUM] = addr + tdep->sc_sp_offset; + gdb_assert (tdep->sc_num_regs <= I386_NUM_SAVED_REGS); + + for (i = 0; i < tdep->sc_num_regs; i++) + if (tdep->sc_reg_offset[i] != -1) + cache->saved_regs[i] = addr + tdep->sc_reg_offset[i]; + } + else + { + cache->saved_regs[I386_EIP_REGNUM] = addr + tdep->sc_pc_offset; + cache->saved_regs[I386_ESP_REGNUM] = addr + tdep->sc_sp_offset; + } + + cache->base_p = 1; } + if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); *this_cache = cache; return cache; } +static enum unwind_stop_reason +i386_sigtramp_frame_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache) +{ + struct i386_frame_cache *cache = + i386_sigtramp_frame_cache (this_frame, this_cache); + + if (!cache->base_p) + return UNWIND_UNAVAILABLE; + + return UNWIND_NO_REASON; +} + static void i386_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) @@ -1909,6 +2006,9 @@ i386_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache, struct i386_frame_cache *cache = i386_sigtramp_frame_cache (this_frame, this_cache); + if (!cache->base_p) + return; + /* See the end of i386_push_dummy_call. */ (*this_id) = frame_id_build (cache->base + 8, get_frame_pc (this_frame)); } @@ -1956,6 +2056,7 @@ i386_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind i386_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + i386_sigtramp_frame_unwind_stop_reason, i386_sigtramp_frame_this_id, i386_sigtramp_frame_prev_register, NULL, diff --git a/gdb/i386obsd-tdep.c b/gdb/i386obsd-tdep.c index 842215f..480aa0c 100644 --- a/gdb/i386obsd-tdep.c +++ b/gdb/i386obsd-tdep.c @@ -434,6 +434,7 @@ static const struct frame_unwind i386obsd_trapframe_unwind = { frame, but SIGTRAMP_FRAME would print <signal handler called>, which really is not what we want here. */ NORMAL_FRAME, + default_frame_unwind_stop_reason, i386obsd_trapframe_this_id, i386obsd_trapframe_prev_register, NULL, diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index 363800d..68e5021 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -2175,6 +2175,7 @@ ia64_frame_prev_register (struct frame_info *this_frame, void **this_cache, static const struct frame_unwind ia64_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, &ia64_frame_this_id, &ia64_frame_prev_register, NULL, @@ -2366,6 +2367,7 @@ ia64_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind ia64_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, ia64_sigtramp_frame_this_id, ia64_sigtramp_frame_prev_register, NULL, @@ -3051,6 +3053,7 @@ ia64_libunwind_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind ia64_libunwind_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, ia64_libunwind_frame_this_id, ia64_libunwind_frame_prev_register, NULL, @@ -3139,6 +3142,7 @@ ia64_libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, ia64_libunwind_sigtramp_frame_this_id, ia64_libunwind_sigtramp_frame_prev_register, NULL, diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c index 7554fc7..dc05b8a 100644 --- a/gdb/inline-frame.c +++ b/gdb/inline-frame.c @@ -260,6 +260,7 @@ inline_frame_sniffer (const struct frame_unwind *self, const struct frame_unwind inline_frame_unwind = { INLINE_FRAME, + default_frame_unwind_stop_reason, inline_frame_this_id, inline_frame_prev_register, NULL, diff --git a/gdb/iq2000-tdep.c b/gdb/iq2000-tdep.c index 2e54478..1926da6 100644 --- a/gdb/iq2000-tdep.c +++ b/gdb/iq2000-tdep.c @@ -436,6 +436,7 @@ iq2000_frame_this_id (struct frame_info *this_frame, void **this_cache, static const struct frame_unwind iq2000_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, iq2000_frame_this_id, iq2000_frame_prev_register, NULL, diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c index 327ac32..d05b3b8 100644 --- a/gdb/lm32-tdep.c +++ b/gdb/lm32-tdep.c @@ -496,6 +496,7 @@ lm32_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind lm32_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, lm32_frame_this_id, lm32_frame_prev_register, NULL, diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c index 454a4b6..673e40c 100644 --- a/gdb/m32c-tdep.c +++ b/gdb/m32c-tdep.c @@ -1960,6 +1960,7 @@ m32c_prev_register (struct frame_info *this_frame, static const struct frame_unwind m32c_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, m32c_this_id, m32c_prev_register, NULL, diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c index 1339a87..a7efe61 100644 --- a/gdb/m32r-linux-tdep.c +++ b/gdb/m32r-linux-tdep.c @@ -305,6 +305,7 @@ m32r_linux_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind m32r_linux_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, m32r_linux_sigtramp_frame_this_id, m32r_linux_sigtramp_frame_prev_register, NULL, diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c index 659c3c8..136fd7b 100644 --- a/gdb/m32r-tdep.c +++ b/gdb/m32r-tdep.c @@ -876,6 +876,7 @@ m32r_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind m32r_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, m32r_frame_this_id, m32r_frame_prev_register, NULL, diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c index ced6eab..b789ce7 100644 --- a/gdb/m68hc11-tdep.c +++ b/gdb/m68hc11-tdep.c @@ -949,6 +949,7 @@ m68hc11_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind m68hc11_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, m68hc11_frame_this_id, m68hc11_frame_prev_register, NULL, diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index 2706969..6d7a824 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -976,6 +976,7 @@ m68k_frame_prev_register (struct frame_info *this_frame, void **this_cache, static const struct frame_unwind m68k_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, m68k_frame_this_id, m68k_frame_prev_register, NULL, diff --git a/gdb/m68klinux-tdep.c b/gdb/m68klinux-tdep.c index b95fad5..c3513bc 100644 --- a/gdb/m68klinux-tdep.c +++ b/gdb/m68klinux-tdep.c @@ -328,6 +328,7 @@ m68k_linux_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind m68k_linux_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, m68k_linux_sigtramp_frame_this_id, m68k_linux_sigtramp_frame_prev_register, NULL, diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c index 76dcbe1..1e4c546 100644 --- a/gdb/m88k-tdep.c +++ b/gdb/m88k-tdep.c @@ -749,6 +749,7 @@ m88k_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind m88k_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, m88k_frame_this_id, m88k_frame_prev_register, NULL, diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c index dd5a4a5..bc40b99 100644 --- a/gdb/mep-tdep.c +++ b/gdb/mep-tdep.c @@ -2094,6 +2094,7 @@ mep_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind mep_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, mep_frame_this_id, mep_frame_prev_register, NULL, diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c index 1e994a2..2482c87 100644 --- a/gdb/microblaze-tdep.c +++ b/gdb/microblaze-tdep.c @@ -521,6 +521,7 @@ microblaze_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind microblaze_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, microblaze_frame_this_id, microblaze_frame_prev_register, NULL, diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index e5aed94..47d9182 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -2028,6 +2028,7 @@ mips_insn16_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind mips_insn16_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, mips_insn16_frame_this_id, mips_insn16_frame_prev_register, NULL, @@ -2381,6 +2382,7 @@ mips_insn32_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind mips_insn32_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, mips_insn32_frame_this_id, mips_insn32_frame_prev_register, NULL, @@ -2505,6 +2507,7 @@ mips_stub_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind mips_stub_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, mips_stub_frame_this_id, mips_stub_frame_prev_register, NULL, diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c index 5b83b22..e949b40 100644 --- a/gdb/mn10300-tdep.c +++ b/gdb/mn10300-tdep.c @@ -1174,6 +1174,7 @@ mn10300_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind mn10300_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, mn10300_frame_this_id, mn10300_frame_prev_register, NULL, diff --git a/gdb/moxie-tdep.c b/gdb/moxie-tdep.c index 84d495f..5fb3d10 100644 --- a/gdb/moxie-tdep.c +++ b/gdb/moxie-tdep.c @@ -461,6 +461,7 @@ moxie_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind moxie_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, moxie_frame_this_id, moxie_frame_prev_register, NULL, diff --git a/gdb/mt-tdep.c b/gdb/mt-tdep.c index 9b0971f..ee98d3d 100644 --- a/gdb/mt-tdep.c +++ b/gdb/mt-tdep.c @@ -1115,6 +1115,7 @@ mt_frame_base_address (struct frame_info *this_frame, static const struct frame_unwind mt_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, mt_frame_this_id, mt_frame_prev_register, NULL, diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index ba70ffd..c6e4b83 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -1472,6 +1472,7 @@ ppu2spu_dealloc_cache (struct frame_info *self, void *this_cache) static const struct frame_unwind ppu2spu_unwind = { ARCH_FRAME, + default_frame_unwind_stop_reason, ppu2spu_this_id, ppu2spu_prev_register, NULL, diff --git a/gdb/ppcobsd-tdep.c b/gdb/ppcobsd-tdep.c index 51cb639..d4e2d79 100644 --- a/gdb/ppcobsd-tdep.c +++ b/gdb/ppcobsd-tdep.c @@ -239,6 +239,7 @@ ppcobsd_sigtramp_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind ppcobsd_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, ppcobsd_sigtramp_frame_this_id, ppcobsd_sigtramp_frame_prev_register, NULL, diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 23fe9e3..65396443 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -3319,6 +3319,7 @@ rs6000_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind rs6000_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, rs6000_frame_this_id, rs6000_frame_prev_register, NULL, diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c index d74bbf0..d9407ef 100644 --- a/gdb/s390-tdep.c +++ b/gdb/s390-tdep.c @@ -1758,6 +1758,7 @@ s390_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind s390_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, s390_frame_this_id, s390_frame_prev_register, NULL, @@ -1841,6 +1842,7 @@ s390_stub_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind s390_stub_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, s390_stub_frame_this_id, s390_stub_frame_prev_register, NULL, @@ -2032,6 +2034,7 @@ s390_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind s390_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, s390_sigtramp_frame_this_id, s390_sigtramp_frame_prev_register, NULL, diff --git a/gdb/score-tdep.c b/gdb/score-tdep.c index ffe562f..4ddcd27 100644 --- a/gdb/score-tdep.c +++ b/gdb/score-tdep.c @@ -1369,6 +1369,7 @@ score_prologue_prev_register (struct frame_info *this_frame, static const struct frame_unwind score_prologue_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, score_prologue_this_id, score_prologue_prev_register, NULL, diff --git a/gdb/sentinel-frame.c b/gdb/sentinel-frame.c index e6000cc..6c2f3e0 100644 --- a/gdb/sentinel-frame.c +++ b/gdb/sentinel-frame.c @@ -51,9 +51,10 @@ sentinel_frame_prev_register (struct frame_info *this_frame, struct gdbarch *gdbarch = get_frame_arch (this_frame); struct frame_unwind_cache *cache = *this_prologue_cache; struct value *value; + struct type *regtype = register_type (gdbarch, regnum); /* Return the actual value. */ - value = allocate_value (register_type (gdbarch, regnum)); + value = allocate_value (regtype); VALUE_LVAL (value) = lval_register; VALUE_REGNUM (value) = regnum; VALUE_FRAME_ID (value) = get_frame_id (this_frame); @@ -64,7 +65,7 @@ sentinel_frame_prev_register (struct frame_info *this_frame, if (regcache_cooked_read (cache->regcache, regnum, value_contents_raw (value)) == REG_UNAVAILABLE) - mark_value_bytes_unavailable (value, 0, register_size (gdbarch, regnum)); + mark_value_bytes_unavailable (value, 0, TYPE_LENGTH (regtype)); return value; } @@ -92,6 +93,7 @@ sentinel_frame_prev_arch (struct frame_info *this_frame, const struct frame_unwind sentinel_frame_unwind = { SENTINEL_FRAME, + default_frame_unwind_stop_reason, sentinel_frame_this_id, sentinel_frame_prev_register, NULL, diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index 49ef8c6..e713cee 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -2635,6 +2635,7 @@ sh_frame_this_id (struct frame_info *this_frame, void **this_cache, static const struct frame_unwind sh_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, sh_frame_this_id, sh_frame_prev_register, NULL, diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c index dca560a..a4da7a4 100644 --- a/gdb/sh64-tdep.c +++ b/gdb/sh64-tdep.c @@ -2437,6 +2437,7 @@ sh64_frame_this_id (struct frame_info *this_frame, void **this_cache, static const struct frame_unwind sh64_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, sh64_frame_this_id, sh64_frame_prev_register, NULL, diff --git a/gdb/sparc-sol2-tdep.c b/gdb/sparc-sol2-tdep.c index ee9d9b5..a49eb7f 100644 --- a/gdb/sparc-sol2-tdep.c +++ b/gdb/sparc-sol2-tdep.c @@ -164,6 +164,7 @@ sparc32_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, sparc32_sol2_sigtramp_frame_this_id, sparc32_sol2_sigtramp_frame_prev_register, NULL, diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index 90817c9..1039bd8 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -1031,6 +1031,7 @@ sparc32_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind sparc32_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, sparc32_frame_this_id, sparc32_frame_prev_register, NULL, diff --git a/gdb/sparc64-sol2-tdep.c b/gdb/sparc64-sol2-tdep.c index a50943f..d11619d 100644 --- a/gdb/sparc64-sol2-tdep.c +++ b/gdb/sparc64-sol2-tdep.c @@ -141,6 +141,7 @@ sparc64_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind sparc64_sol2_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, sparc64_sol2_sigtramp_frame_this_id, sparc64_sol2_sigtramp_frame_prev_register, NULL, diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c index 4b42f01..674d390 100644 --- a/gdb/sparc64-tdep.c +++ b/gdb/sparc64-tdep.c @@ -562,6 +562,7 @@ sparc64_frame_prev_register (struct frame_info *this_frame, void **this_cache, static const struct frame_unwind sparc64_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, sparc64_frame_this_id, sparc64_frame_prev_register, NULL, diff --git a/gdb/sparc64fbsd-tdep.c b/gdb/sparc64fbsd-tdep.c index 36a1177..49d3050 100644 --- a/gdb/sparc64fbsd-tdep.c +++ b/gdb/sparc64fbsd-tdep.c @@ -202,6 +202,7 @@ sparc64fbsd_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind sparc64fbsd_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, sparc64fbsd_sigtramp_frame_this_id, sparc64fbsd_sigtramp_frame_prev_register, NULL, diff --git a/gdb/sparc64nbsd-tdep.c b/gdb/sparc64nbsd-tdep.c index 12818d0..5d6c27c 100644 --- a/gdb/sparc64nbsd-tdep.c +++ b/gdb/sparc64nbsd-tdep.c @@ -230,6 +230,7 @@ sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, sparc64nbsd_sigcontext_frame_this_id, sparc64nbsd_sigcontext_frame_prev_register, NULL, diff --git a/gdb/sparc64obsd-tdep.c b/gdb/sparc64obsd-tdep.c index 226f277..adc16a1 100644 --- a/gdb/sparc64obsd-tdep.c +++ b/gdb/sparc64obsd-tdep.c @@ -195,6 +195,7 @@ sparc64obsd_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind sparc64obsd_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, sparc64obsd_frame_this_id, sparc64obsd_frame_prev_register, NULL, @@ -277,6 +278,7 @@ sparc64obsd_trapframe_sniffer (const struct frame_unwind *self, static const struct frame_unwind sparc64obsd_trapframe_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, sparc64obsd_trapframe_this_id, sparc64obsd_trapframe_prev_register, NULL, diff --git a/gdb/sparcnbsd-tdep.c b/gdb/sparcnbsd-tdep.c index 03eb1ef..8bbaa4b 100644 --- a/gdb/sparcnbsd-tdep.c +++ b/gdb/sparcnbsd-tdep.c @@ -254,6 +254,7 @@ sparc32nbsd_sigcontext_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, sparc32nbsd_sigcontext_frame_this_id, sparc32nbsd_sigcontext_frame_prev_register, NULL, diff --git a/gdb/sparcobsd-tdep.c b/gdb/sparcobsd-tdep.c index 6a3c43c..b9e9540 100644 --- a/gdb/sparcobsd-tdep.c +++ b/gdb/sparcobsd-tdep.c @@ -139,6 +139,7 @@ sparc32obsd_sigtramp_frame_sniffer (const struct frame_unwind *self, static const struct frame_unwind sparc32obsd_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, sparc32obsd_sigtramp_frame_this_id, sparc32obsd_sigtramp_frame_prev_register, NULL, diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c index da7024a..7f20794 100644 --- a/gdb/spu-tdep.c +++ b/gdb/spu-tdep.c @@ -1082,6 +1082,7 @@ spu_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind spu_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, spu_frame_this_id, spu_frame_prev_register, NULL, @@ -1236,6 +1237,7 @@ spu2ppu_dealloc_cache (struct frame_info *self, void *this_cache) static const struct frame_unwind spu2ppu_unwind = { ARCH_FRAME, + default_frame_unwind_stop_reason, spu2ppu_this_id, spu2ppu_prev_register, NULL, diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c index 620536f..96e8d22 100644 --- a/gdb/v850-tdep.c +++ b/gdb/v850-tdep.c @@ -935,6 +935,7 @@ v850_frame_this_id (struct frame_info *this_frame, void **this_cache, static const struct frame_unwind v850_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, v850_frame_this_id, v850_frame_prev_register, NULL, diff --git a/gdb/vax-tdep.c b/gdb/vax-tdep.c index b84977a..97d4534 100644 --- a/gdb/vax-tdep.c +++ b/gdb/vax-tdep.c @@ -402,6 +402,7 @@ vax_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind vax_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, vax_frame_this_id, vax_frame_prev_register, NULL, diff --git a/gdb/vaxobsd-tdep.c b/gdb/vaxobsd-tdep.c index f87f232..7089f15 100644 --- a/gdb/vaxobsd-tdep.c +++ b/gdb/vaxobsd-tdep.c @@ -135,6 +135,7 @@ vaxobsd_sigtramp_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind vaxobsd_sigtramp_frame_unwind = { SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, vaxobsd_sigtramp_frame_this_id, vaxobsd_sigtramp_frame_prev_register, NULL, diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c index 1aef08a..53cbecd 100644 --- a/gdb/xstormy16-tdep.c +++ b/gdb/xstormy16-tdep.c @@ -742,6 +742,7 @@ xstormy16_frame_base_address (struct frame_info *this_frame, void **this_cache) static const struct frame_unwind xstormy16_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, xstormy16_frame_this_id, xstormy16_frame_prev_register, NULL, diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c index 316a8cf..24cc79c 100644 --- a/gdb/xtensa-tdep.c +++ b/gdb/xtensa-tdep.c @@ -1549,6 +1549,7 @@ static const struct frame_unwind xtensa_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, xtensa_frame_this_id, xtensa_frame_prev_register, NULL, |