diff options
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/dwarf2-frame.c | 37 |
2 files changed, 15 insertions, 32 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c4bcdf6..4bc944c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,13 +1,3 @@ -2013-11-22 Pedro Alves <palves@redhat.com> - - PR 16155 - * dwarf2-frame.c (struct dwarf2_frame_cache) - <checked_tailcall_bottom, entry_cfa_sp_offset, - entry_cfa_sp_offset_p>: New fields. - (dwarf2_frame_cache): Adjust to use the new cache fields instead - of locals. Don't call dwarf2_tailcall_sniffer_first here. - (dwarf2_frame_prev_register): Call it here, but only once. - 2013-11-21 Doug Evans <xdje42@gmail.com> * gdbtypes.c: #include bcache.h, dwarf2loc.h. diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index c4f8771..91d8802 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -993,22 +993,12 @@ struct dwarf2_frame_cache /* The .text offset. */ CORE_ADDR text_offset; - /* True if we already checked whether this frame is the bottom frame - of a virtual tail call frame chain. */ - int checked_tailcall_bottom; - /* If not NULL then this frame is the bottom frame of a TAILCALL_FRAME sequence. If NULL then it is a normal case with no TAILCALL_FRAME involved. Non-bottom frames of a virtual tail call frames chain use dwarf2_tailcall_frame_unwind unwinder so this field does not apply for them. */ void *tailcall_cache; - - /* The number of bytes to subtract from TAILCALL_FRAME frames frame - base to get the SP, to simulate the return address pushed on the - stack. */ - LONGEST entry_cfa_sp_offset; - int entry_cfa_sp_offset_p; }; /* A cleanup that sets a pointer to NULL. */ @@ -1033,6 +1023,8 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) struct dwarf2_fde *fde; volatile struct gdb_exception ex; CORE_ADDR entry_pc; + LONGEST entry_cfa_sp_offset; + int entry_cfa_sp_offset_p = 0; const gdb_byte *instr; if (*this_cache) @@ -1097,8 +1089,8 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) && (gdbarch_dwarf2_reg_to_regnum (gdbarch, fs->regs.cfa_reg) == gdbarch_sp_regnum (gdbarch))) { - cache->entry_cfa_sp_offset = fs->regs.cfa_offset; - cache->entry_cfa_sp_offset_p = 1; + entry_cfa_sp_offset = fs->regs.cfa_offset; + entry_cfa_sp_offset_p = 1; } } else @@ -1247,6 +1239,13 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"), cache->undefined_retaddr = 1; do_cleanups (old_chain); + + /* Try to find a virtual tail call frames chain with bottom (callee) frame + starting at THIS_FRAME. */ + dwarf2_tailcall_sniffer_first (this_frame, &cache->tailcall_cache, + (entry_cfa_sp_offset_p + ? &entry_cfa_sp_offset : NULL)); + discard_cleanups (reset_cache_cleanup); return cache; } @@ -1293,16 +1292,6 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache, CORE_ADDR addr; int realnum; - /* Check whether THIS_FRAME is the bottom frame of a virtual tail - call frame chain. */ - if (!cache->checked_tailcall_bottom) - { - cache->checked_tailcall_bottom = 1; - dwarf2_tailcall_sniffer_first (this_frame, &cache->tailcall_cache, - (cache->entry_cfa_sp_offset_p - ? &cache->entry_cfa_sp_offset : NULL)); - } - /* Non-bottom frames of a virtual tail call frames chain use dwarf2_tailcall_frame_unwind unwinder so this code does not apply for them. If dwarf2_tailcall_prev_register_first does not have specific value @@ -1429,6 +1418,10 @@ dwarf2_frame_sniffer (const struct frame_unwind *self, if (self->type != NORMAL_FRAME) return 0; + /* Preinitializa the cache so that TAILCALL_FRAME can find the record by + dwarf2_tailcall_sniffer_first. */ + dwarf2_frame_cache (this_frame, this_cache); + return 1; } |