summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <dan@debian.org>2004-11-07 21:16:11 +0000
committerDaniel Jacobowitz <dan@debian.org>2004-11-07 21:16:11 +0000
commit81ae55503b371625eccd79f65dfd978e354de963 (patch)
treebe8e0b1872a1450721ac63c731c3f6e662b0367c
parentc634af77cd554f7f3d1c705a71025a4fa8f75196 (diff)
downloadgdb-81ae55503b371625eccd79f65dfd978e354de963.tar.gz
* dwarf2-frame.c (struct dwarf2_frame_ops): Add signal_frame_p.
(dwarf2_frame_set_signal_frame_p, dwarf2_frame_signal_frame_p) (dwarf2_signal_frame_unwind): New. (dwarf2_frame_sniffer): Use dwarf2_frame_signal_frame_p. * dwarf2-frame.h (dwarf2_frame_set_signal_frame_p): New prototype.
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/dwarf2-frame.c52
-rw-r--r--gdb/dwarf2-frame.h8
3 files changed, 65 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4a9b4e39134..2b171379c83 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2004-11-07 Daniel Jacobowitz <dan@debian.org>
+
+ * dwarf2-frame.c (struct dwarf2_frame_ops): Add signal_frame_p.
+ (dwarf2_frame_set_signal_frame_p, dwarf2_frame_signal_frame_p)
+ (dwarf2_signal_frame_unwind): New.
+ (dwarf2_frame_sniffer): Use dwarf2_frame_signal_frame_p.
+ * dwarf2-frame.h (dwarf2_frame_set_signal_frame_p): New prototype.
+
2004-11-07 Mark Kettenis <kettenis@gnu.org>
* Makefile.in (mips64obsd-tdep.o): Fix typo.
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 4bad147ffd1..6a37e5df7df 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -471,6 +471,10 @@ struct dwarf2_frame_ops
{
/* Pre-initialize the register state REG for register REGNUM. */
void (*init_reg) (struct gdbarch *, int, struct dwarf2_frame_state_reg *);
+
+ /* Check whether the frame preceding NEXT_FRAME will be a signal
+ trampoline. */
+ int (*signal_frame_p) (struct gdbarch *, struct frame_info *);
};
/* Default architecture-specific register state initialization
@@ -547,6 +551,33 @@ dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
ops->init_reg (gdbarch, regnum, reg);
}
+
+/* Set the architecture-specific signal trampoline recognition
+ function for GDBARCH to SIGNAL_FRAME_P. */
+
+void
+dwarf2_frame_set_signal_frame_p (struct gdbarch *gdbarch,
+ int (*signal_frame_p) (struct gdbarch *,
+ struct frame_info *))
+{
+ struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
+
+ ops->signal_frame_p = signal_frame_p;
+}
+
+/* Query the architecture-specific signal frame recognizer for
+ NEXT_FRAME. */
+
+static int
+dwarf2_frame_signal_frame_p (struct gdbarch *gdbarch,
+ struct frame_info *next_frame)
+{
+ struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
+
+ if (ops->signal_frame_p == NULL)
+ return 0;
+ return ops->signal_frame_p (gdbarch, next_frame);
+}
struct dwarf2_frame_cache
@@ -845,6 +876,13 @@ static const struct frame_unwind dwarf2_frame_unwind =
dwarf2_frame_prev_register
};
+static const struct frame_unwind dwarf2_signal_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ dwarf2_frame_this_id,
+ dwarf2_frame_prev_register
+};
+
const struct frame_unwind *
dwarf2_frame_sniffer (struct frame_info *next_frame)
{
@@ -852,10 +890,18 @@ dwarf2_frame_sniffer (struct frame_info *next_frame)
function. frame_pc_unwind(), for a no-return next function, can
end up returning something past the end of this function's body. */
CORE_ADDR block_addr = frame_unwind_address_in_block (next_frame);
- if (dwarf2_frame_find_fde (&block_addr))
- return &dwarf2_frame_unwind;
+ if (!dwarf2_frame_find_fde (&block_addr))
+ return NULL;
- return NULL;
+ /* On some targets, signal trampolines may have unwind information.
+ We need to recognize them so that we set the frame type
+ correctly. */
+
+ if (dwarf2_frame_signal_frame_p (get_frame_arch (next_frame),
+ next_frame))
+ return &dwarf2_signal_frame_unwind;
+
+ return &dwarf2_frame_unwind;
}
diff --git a/gdb/dwarf2-frame.h b/gdb/dwarf2-frame.h
index 1ae44b5064c..5191c0e8d49 100644
--- a/gdb/dwarf2-frame.h
+++ b/gdb/dwarf2-frame.h
@@ -79,6 +79,14 @@ extern void dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
void (*init_reg) (struct gdbarch *, int,
struct dwarf2_frame_state_reg *));
+/* Set the architecture-specific signal trampoline recognition
+ function for GDBARCH to SIGNAL_FRAME_P. */
+
+extern void
+ dwarf2_frame_set_signal_frame_p (struct gdbarch *gdbarch,
+ int (*signal_frame_p) (struct gdbarch *,
+ struct frame_info *));
+
/* Return the frame unwind methods for the function that contains PC,
or NULL if it can't be handled by DWARF CFI frame unwinder. */