* dwarf2-frame.c (struct dwarf2_frame_ops): Add signal_frame_p.
authorDaniel Jacobowitz <drow@false.org>
Sun, 7 Nov 2004 21:16:11 +0000 (21:16 +0000)
committerDaniel Jacobowitz <drow@false.org>
Sun, 7 Nov 2004 21:16:11 +0000 (21:16 +0000)
(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.

gdb/ChangeLog
gdb/dwarf2-frame.c
gdb/dwarf2-frame.h

index 4a9b4e39134e78669aeb2e0c5be4632af9418649..2b171379c838a3ac2107a2aa46a3c0898d1deada 100644 (file)
@@ -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.
index 4bad147ffd1d9c396bfdee7e0ac3a1c9d9dbc13a..6a37e5df7df04a5cdcf85ef83432a4f7ede17eb7 100644 (file)
@@ -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);
+}
 \f
 
 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;
 }
 \f
 
index 1ae44b5064c74d565d17b6ee3ae31349ea0ef7d9..5191c0e8d497eab835a009d5992440611dc9480d 100644 (file)
@@ -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.  */