aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/dwarf2-frame.c37
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;
}