* i386nbsd-tdep.c: Include "trad-frame.h" and "tramp-frame.h"
authorMark Kettenis <kettenis@gnu.org>
Sat, 29 Dec 2007 17:01:41 +0000 (17:01 +0000)
committerMark Kettenis <kettenis@gnu.org>
Sat, 29 Dec 2007 17:01:41 +0000 (17:01 +0000)
(sigtramp_retcode, i386nbsd_sigtramp_offset, i386nbsd_sigtramp_p):
Remove
(i386nbsd_mc_reg_offset): New array.
(i386nbsd_sigtramp_cache_init): New function.
(i386nbsd_sigtramp_sc16, i386nbsd_sigtramp_sc2, i386nbsd_sigtramp_si2)
(i386nbsd_sigtramp_si31, i386nbsd_sigtramp_si4): New signal trampoline
frame descriptions.
(i386nbsd_init_abi): Override ABI sigcontext defaults and register
new signal frame unwinders
* Makefile.in (i386nbsd-tdep.o): Update dependencies.
* tramp-frame.h (struct tramp_frame): Allow for 48 instructions

gdb/ChangeLog
gdb/Makefile.in
gdb/i386nbsd-tdep.c
gdb/tramp-frame.h

index af088213de69888256efa5370c6e7a78b46fb58c..4b98da9415d79665e2bd9dea002d25d678f745ce 100644 (file)
@@ -1,3 +1,18 @@
+2007-12-29  Nick Hudson  <nick.hudson@dsl.pipex.com>
+
+       * i386nbsd-tdep.c: Include "trad-frame.h" and "tramp-frame.h"
+       (sigtramp_retcode, i386nbsd_sigtramp_offset, i386nbsd_sigtramp_p):
+       Remove
+       (i386nbsd_mc_reg_offset): New array.
+       (i386nbsd_sigtramp_cache_init): New function.
+       (i386nbsd_sigtramp_sc16, i386nbsd_sigtramp_sc2, i386nbsd_sigtramp_si2)
+       (i386nbsd_sigtramp_si31, i386nbsd_sigtramp_si4): New signal trampoline
+       frame descriptions.
+       (i386nbsd_init_abi): Override ABI sigcontext defaults and register
+       new signal frame unwinders
+       * Makefile.in (i386nbsd-tdep.o): Update dependencies.
+       * tramp-frame.h (struct tramp_frame): Allow for 48 instructions
+
 2007-12-29  Joel Brobecker  <brobecker@adacore.com>
 
        * ada-lang.c (_initialize_ada_language): Attach executable_changed
index 114333cff9753d949bce15a2a5e6d306f4129ecf..ede72270687449546cfe63a15215466710d88a70 100644 (file)
@@ -2226,7 +2226,7 @@ i386nbsd-nat.o: i386nbsd-nat.c $(defs_h) $(gdbcore_h) $(regcache_h) \
 i386nbsd-tdep.o: i386nbsd-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) \
        $(gdbcore_h) $(regcache_h) $(regset_h) $(osabi_h) $(symtab_h) \
        $(gdb_assert_h) $(gdb_string_h) $(i386_tdep_h) $(i387_tdep_h) \
-       $(nbsd_tdep_h) $(solib_svr4_h)
+       $(nbsd_tdep_h) $(solib_svr4_h) $(trad_frame_h) $(tramp_frame_h)
 i386-nto-tdep.o: i386-nto-tdep.c $(defs_h) $(frame_h) $(osabi_h) \
        $(regcache_h) $(target_h) $(gdb_assert_h) $(gdb_string_h) \
        $(i386_tdep_h) $(i387_tdep_h) $(nto_tdep_h) $(solib_h) \
index 6772639c930717cac7d772c9c5b4ccf2e56577b1..ea9b866559632a57c62564d4b956b25d0ef21d65 100644 (file)
@@ -26,6 +26,8 @@
 #include "regset.h"
 #include "osabi.h"
 #include "symtab.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -56,109 +58,6 @@ static int i386nbsd_r_reg_offset[] =
   15 * 4                       /* %gs */
 };
 
-/* Under NetBSD/i386, signal handler invocations can be identified by the
-   designated code sequence that is used to return from a signal handler.
-   In particular, the return address of a signal handler points to the
-   following code sequence:
-
-       leal    0x10(%esp), %eax
-       pushl   %eax
-       pushl   %eax
-       movl    $0x127, %eax            # __sigreturn14
-       int     $0x80
-
-   Each instruction has a unique encoding, so we simply attempt to match
-   the instruction the PC is pointing to with any of the above instructions.
-   If there is a hit, we know the offset to the start of the designated
-   sequence and can then check whether we really are executing in the
-   signal trampoline.  If not, -1 is returned, otherwise the offset from the
-   start of the return sequence is returned.  */
-#define RETCODE_INSN1          0x8d
-#define RETCODE_INSN2          0x50
-#define RETCODE_INSN3          0x50
-#define RETCODE_INSN4          0xb8
-#define RETCODE_INSN5          0xcd
-
-#define RETCODE_INSN2_OFF      4
-#define RETCODE_INSN3_OFF      5
-#define RETCODE_INSN4_OFF      6
-#define RETCODE_INSN5_OFF      11
-
-static const unsigned char sigtramp_retcode[] =
-{
-  RETCODE_INSN1, 0x44, 0x24, 0x10,
-  RETCODE_INSN2,
-  RETCODE_INSN3,
-  RETCODE_INSN4, 0x27, 0x01, 0x00, 0x00,
-  RETCODE_INSN5, 0x80,
-};
-
-static LONGEST
-i386nbsd_sigtramp_offset (struct frame_info *next_frame)
-{
-  CORE_ADDR pc = frame_pc_unwind (next_frame);
-  unsigned char ret[sizeof(sigtramp_retcode)], insn;
-  LONGEST off;
-  int i;
-
-  if (!safe_frame_unwind_memory (next_frame, pc, &insn, 1))
-    return -1;
-
-  switch (insn)
-    {
-    case RETCODE_INSN1:
-      off = 0;
-      break;
-
-    case RETCODE_INSN2:
-      /* INSN2 and INSN3 are the same.  Read at the location of PC+1
-        to determine if we're actually looking at INSN2 or INSN3.  */
-      if (!safe_frame_unwind_memory (next_frame, pc + 1, &insn, 1))
-       return -1;
-
-      if (insn == RETCODE_INSN3)
-       off = RETCODE_INSN2_OFF;
-      else
-       off = RETCODE_INSN3_OFF;
-      break;
-
-    case RETCODE_INSN4:
-      off = RETCODE_INSN4_OFF;
-      break;
-
-    case RETCODE_INSN5:
-      off = RETCODE_INSN5_OFF;
-      break;
-
-    default:
-      return -1;
-    }
-
-  pc -= off;
-
-  if (!safe_frame_unwind_memory (next_frame, pc, ret, sizeof (ret)))
-    return -1;
-
-  if (memcmp (ret, sigtramp_retcode, sizeof (ret)) == 0)
-    return off;
-
-  return -1;
-}
-
-/* Return whether the frame preceding NEXT_FRAME corresponds to a
-   NetBSD sigtramp routine.  */
-
-static int
-i386nbsd_sigtramp_p (struct frame_info *next_frame)
-{
-  CORE_ADDR pc = frame_pc_unwind (next_frame);
-  char *name;
-
-  find_pc_partial_function (pc, &name, NULL, NULL);
-  return (nbsd_pc_in_sigtramp (pc, name)
-         || i386nbsd_sigtramp_offset (next_frame) >= 0);
-}
-
 /* From <machine/signal.h>.  */
 int i386nbsd_sc_reg_offset[] =
 {
@@ -180,6 +79,195 @@ int i386nbsd_sc_reg_offset[] =
   0 * 4                                /* %gs */
 };
 
+/* From <machine/mcontext.h>.  */
+int i386nbsd_mc_reg_offset[] =
+{
+  11 * 4,                      /* %eax */
+  10 * 4,                      /* %ecx */
+  9 * 4,                       /* %edx */
+  8 * 4,                       /* %ebx */
+  7 * 4,                       /* %esp */
+  6 * 4,                       /* %ebp */
+  5 * 4,                       /* %esi */
+  4 * 4,                       /* %edi */
+  14 * 4,                      /* %eip */
+  16 * 4,                      /* %eflags */
+  15 * 4,                      /* %cs */
+  18 * 4,                      /* %ss */
+  3 * 4,                       /* %ds */
+  2 * 4,                       /* %es */
+  1 * 4,                       /* %fs */
+  0 * 4                                /* %gs */
+};
+
+static void i386nbsd_sigtramp_cache_init (const struct tramp_frame *,
+                                         struct frame_info *,
+                                         struct trad_frame_cache *,
+                                         CORE_ADDR);
+
+static const struct tramp_frame i386nbsd_sigtramp_sc16 =
+{
+  SIGTRAMP_FRAME,
+  1,
+  {
+    { 0x8d, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x10, -1 },
+                       /* leal  0x10(%esp), %eax */
+    { 0x50, -1 },      /* pushl %eax */
+    { 0x50, -1 },      /* pushl %eax */
+    { 0xb8, -1 }, { 0x27, -1 }, {0x01, -1 }, {0x00, -1 }, {0x00, -1 },
+                       /* movl  $0x127, %eax           # __sigreturn14 */
+    { 0xcd, -1 }, { 0x80, -1},
+                       /* int   $0x80 */
+    { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+                       /* movl  $0x1, %eax             # exit */
+    { 0xcd, -1 }, { 0x80, -1},
+                       /* int   $0x80 */
+    { TRAMP_SENTINEL_INSN, -1 }
+  },
+  i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_sc2 =
+{
+  SIGTRAMP_FRAME,
+  1,
+  {
+    { 0x8d, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x0c, -1 },
+                       /* leal  0x0c(%esp), %eax */
+    { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+                       /* movl  %eax, 0x4(%esp) */
+    { 0xb8, -1 }, { 0x27, -1 }, {0x01, -1 }, {0x00, -1 }, {0x00, -1 },
+                       /* movl  $0x127, %eax           # __sigreturn14 */
+    { 0xcd, -1 }, { 0x80, -1},
+                       /* int   $0x80 */
+    { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+                       /* movl  %eax, 0x4(%esp) */
+    { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+                       /* movl  $0x1, %eax */
+    { 0xcd, -1 }, { 0x80, -1},
+                       /* int   $0x80 */
+    { TRAMP_SENTINEL_INSN, -1 }
+  },
+  i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si2 =
+{
+  SIGTRAMP_FRAME,
+  1,
+  {
+    { 0x8b, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x08, -1 },
+                       /* movl  8(%esp),%eax */
+    { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+                       /* movl  %eax, 0x4(%esp) */
+    { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
+                       /* movl  $0x134, %eax            # setcontext */
+    { 0xcd, -1 }, { 0x80, -1 },
+                       /* int   $0x80 */
+    { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+                       /* movl  %eax, 0x4(%esp) */
+    { 0xb8, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
+                       /* movl  $0x1, %eax */
+    { 0xcd, -1 }, { 0x80, -1 },
+                       /* int   $0x80 */
+    { TRAMP_SENTINEL_INSN, -1 }
+  },
+  i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si31 =
+{
+  SIGTRAMP_FRAME,
+  1,
+  {
+    { 0x8d, -1 }, { 0x84, -1 }, { 0x24, -1 },
+        { 0x8c, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
+                       /* leal  0x8c(%esp), %eax */
+    { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+                       /* movl  %eax, 0x4(%esp) */
+    { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
+                       /* movl  $0x134, %eax            # setcontext */
+    { 0xcd, -1 }, { 0x80, -1},
+                       /* int   $0x80 */
+    { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+                       /* movl  %eax, 0x4(%esp) */
+    { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+                       /* movl  $0x1, %eax */
+    { 0xcd, -1 }, { 0x80, -1},
+                       /* int   $0x80 */
+    { TRAMP_SENTINEL_INSN, -1 }
+  },
+  i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si4 =
+{
+  SIGTRAMP_FRAME,
+  1,
+  {
+    { 0x8d, -1 }, { 0x84, -1 }, { 0x24, -1 },
+        { 0x8c, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
+                       /* leal  0x8c(%esp), %eax */
+    { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+                       /* movl  %eax, 0x4(%esp) */
+    { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
+                       /* movl  $0x134, %eax            # setcontext */
+    { 0xcd, -1 }, { 0x80, -1},
+                       /* int   $0x80 */
+    { 0xc7, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+        { 0xff, -1 }, { 0xff, -1 }, { 0xff, -1 }, { 0xff, -1 },
+                       /* movl   $0xffffffff,0x4(%esp) */
+    { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+                       /* movl  $0x1, %eax */
+    { 0xcd, -1 }, { 0x80, -1},
+                       /* int   $0x80 */
+    { TRAMP_SENTINEL_INSN, -1 }
+  },
+  i386nbsd_sigtramp_cache_init
+};
+
+static void
+i386nbsd_sigtramp_cache_init (const struct tramp_frame *self,
+                            struct frame_info *next_frame,
+                            struct trad_frame_cache *this_cache,
+                            CORE_ADDR func)
+{
+  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  CORE_ADDR sp = frame_unwind_register_unsigned (next_frame, I386_ESP_REGNUM);
+  CORE_ADDR base;
+  int *reg_offset;
+  int num_regs;
+  int i;
+
+  if (self == &i386nbsd_sigtramp_sc16 || self == &i386nbsd_sigtramp_sc2)
+    {
+      reg_offset = i386nbsd_sc_reg_offset;
+      num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);
+
+      /* Read in the sigcontext address */
+      base = read_memory_unsigned_integer (sp + 8, 4);
+    }
+  else
+    {
+      reg_offset = i386nbsd_mc_reg_offset;
+      num_regs = ARRAY_SIZE (i386nbsd_mc_reg_offset);
+
+      /* Read in the ucontext address */
+      base = read_memory_unsigned_integer (sp + 8, 4);
+      /* offsetof(ucontext_t, uc_mcontext) == 36 */
+      base += 36;
+    }
+
+  for (i = 0; i < num_regs; i++)
+    if (reg_offset[i] != -1)
+      trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
+
+  /* Construct the frame ID using the function start.  */
+  trad_frame_set_id (this_cache, frame_id_build (sp, func));
+}
+\f
+
 static void 
 i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -193,18 +281,22 @@ i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->gregset_num_regs = ARRAY_SIZE (i386nbsd_r_reg_offset);
   tdep->sizeof_gregset = 16 * 4;
 
-  /* NetBSD has different signal trampoline conventions.  */
-  tdep->sigtramp_start = 0;
-  tdep->sigtramp_end = 0;
-  tdep->sigtramp_p = i386nbsd_sigtramp_p;
-
   /* NetBSD uses -freg-struct-return by default.  */
   tdep->struct_return = reg_struct_return;
 
-  /* NetBSD has a `struct sigcontext' that's different from the
-     original 4.3 BSD.  */
-  tdep->sc_reg_offset = i386nbsd_sc_reg_offset;
-  tdep->sc_num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);
+  /* NetBSD uses tramp_frame sniffers for signal trampolines. */
+  tdep->sigcontext_addr= 0;
+  tdep->sigtramp_start = 0;
+  tdep->sigtramp_end = 0;
+  tdep->sigtramp_p = 0;
+  tdep->sc_reg_offset = 0;
+  tdep->sc_num_regs = 0;
+
+  tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc16);
+  tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc2);
+  tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si2);
+  tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si31);
+  tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si4);
 }
 
 /* NetBSD ELF.  */
index 67a39f87e18684695e13e72dbc2ad90281020d6b..886f94d32fb52f87afe626da04e76987d90de732 100644 (file)
@@ -62,7 +62,7 @@ struct tramp_frame
   {
     ULONGEST bytes;
     ULONGEST mask;
-  } insn[16];
+  } insn[48];
   /* Initialize a trad-frame cache corresponding to the tramp-frame.
      FUNC is the address of the instruction TRAMP[0] in memory.  */
   void (*init) (const struct tramp_frame *self,