This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[rfa:NetBSD/ppc] Implement signal trampoline unwinder


It appears to work (but doesn't have much effect without an rs6000 unwinder).

One question (and to follow up my earlier post) is there a better way of doing this:

+  if (frame_pc_unwind (next_frame) > 0x7f000000)
+    /* Assume anything that is vaguely on the stack is a signal
+       trampoline.  */
+    return &ppcnbsd_sigtramp_unwind;

ok?, eventually for 6.1?

Andrew
2004-02-29  Andrew Cagney  <cagney@redhat.com>

	* ppcnbsd-tdep.c: Include "trad-frame.h", and "frame-unwind.h".
	(struct ppcnbsd_sigtramp_cache, ppcnbsd_sigtramp_this_id)
	(ppcnbsd_sigtramp_prev_register, ppcnbsd_sigtramp_cache)
	(ppcnbsd_sigtramp_sniffer, ppcnbsd_sigtramp_unwind)
	(ppcnbsd_init_abi): Implement a NetBSD/PPC signal trampline
	unwinder, register.

Index: ppcnbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppcnbsd-tdep.c,v
retrieving revision 1.11
diff -u -r1.11 ppcnbsd-tdep.c
--- ppcnbsd-tdep.c	10 Nov 2003 22:47:28 -0000	1.11
+++ ppcnbsd-tdep.c	1 Mar 2004 00:58:20 -0000
@@ -26,6 +26,8 @@
 #include "breakpoint.h"
 #include "value.h"
 #include "osabi.h"
+#include "trad-frame.h"
+#include "frame-unwind.h"
 
 #include "ppc-tdep.h"
 #include "ppcnbsd-tdep.h"
@@ -227,6 +229,89 @@
 					     readbuf, writebuf);
 }
 
+struct ppcnbsd_sigtramp_cache
+{
+  CORE_ADDR base;
+  struct trad_frame_saved_reg *saved_regs;
+};
+
+static struct ppcnbsd_sigtramp_cache *
+ppcnbsd_sigtramp_cache (struct frame_info *next_frame, void **this_cache)
+{
+  CORE_ADDR offset;
+  int i;
+  struct ppcnbsd_sigtramp_cache *cache;
+  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if ((*this_cache) != NULL)
+    return (*this_cache);
+  cache = FRAME_OBSTACK_ZALLOC (struct ppcnbsd_sigtramp_cache);
+  (*this_cache) = cache;
+  cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+
+  cache->base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
+  offset = cache->base + 0x18 + 2 * tdep->wordsize;
+  for (i = 0; i < 32; i++)
+    {
+      int regnum = i + tdep->ppc_gp0_regnum;
+      cache->saved_regs[regnum].addr = offset;
+      offset += tdep->wordsize;
+    }
+  cache->saved_regs[tdep->ppc_lr_regnum].addr = offset;
+  offset += tdep->wordsize;
+  cache->saved_regs[tdep->ppc_cr_regnum].addr = offset;
+  offset += tdep->wordsize;
+  cache->saved_regs[tdep->ppc_xer_regnum].addr = offset;
+  offset += tdep->wordsize;
+  cache->saved_regs[tdep->ppc_ctr_regnum].addr = offset;
+  offset += tdep->wordsize;
+  cache->saved_regs[PC_REGNUM].addr = offset; /* SRR0? */
+  offset += tdep->wordsize;
+  return cache;
+}
+
+static void
+ppcnbsd_sigtramp_this_id (struct frame_info *next_frame, void **this_cache,
+			  struct frame_id *this_id)
+{
+  struct ppcnbsd_sigtramp_cache *info = ppcnbsd_sigtramp_cache (next_frame,
+								this_cache);
+  (*this_id) = frame_id_build (info->base, frame_pc_unwind (next_frame));
+}
+
+static void
+ppcnbsd_sigtramp_prev_register (struct frame_info *next_frame,
+				void **this_cache,
+				int regnum, int *optimizedp,
+				enum lval_type *lvalp, CORE_ADDR *addrp,
+				int *realnump, void *valuep)
+{
+  struct ppcnbsd_sigtramp_cache *info = ppcnbsd_sigtramp_cache (next_frame,
+								this_cache);
+  trad_frame_prev_register (next_frame, info->saved_regs, regnum,
+			    optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind ppcnbsd_sigtramp_unwind =
+{
+  SIGTRAMP_FRAME,
+  ppcnbsd_sigtramp_this_id,
+  ppcnbsd_sigtramp_prev_register
+};
+
+static const struct frame_unwind *
+ppcnbsd_sigtramp_sniffer (struct frame_info *next_frame)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame));
+  if (frame_pc_unwind (next_frame) > 0x7f000000)
+    /* Assume anything that is vaguely on the stack is a signal
+       trampoline.  */
+    return &ppcnbsd_sigtramp_unwind;
+  else
+    return NULL;
+}
+
 static void
 ppcnbsd_init_abi (struct gdbarch_info info,
                   struct gdbarch *gdbarch)
@@ -237,6 +322,7 @@
   set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);
   set_solib_svr4_fetch_link_map_offsets (gdbarch,
                                 nbsd_ilp32_solib_svr4_fetch_link_map_offsets);
+  frame_unwind_append_sniffer (gdbarch, ppcnbsd_sigtramp_sniffer);
 }
 
 void

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]