[ARC] Add SYNTAX_NOP and SYNTAX_1OP for extension instructions
[deliverable/binutils-gdb.git] / gdb / i386nbsd-tdep.c
index 82013b59fc03e0aeb94cba13b97af9183063998b..9a48c5975d218fff7723003ce9d016d1babf2284 100644 (file)
@@ -1,14 +1,12 @@
 /* Target-dependent code for NetBSD/i386.
 
-   Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 2002,
-   2003, 2004
-   Free Software Foundation, Inc.
+   Copyright (C) 1988-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "arch-utils.h"
+#include "frame.h"
 #include "gdbcore.h"
 #include "regcache.h"
 #include "regset.h"
 #include "osabi.h"
-
-#include "gdb_assert.h"
-#include "gdb_string.h"
+#include "symtab.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
 
 #include "i386-tdep.h"
 #include "i387-tdep.h"
@@ -57,159 +54,216 @@ static int i386nbsd_r_reg_offset[] =
   15 * 4                       /* %gs */
 };
 
-static void
-i386nbsd_aout_supply_regset (const struct regset *regset,
-                            struct regcache *regcache, int regnum,
-                            const void *regs, size_t len)
+/* From <machine/signal.h>.  */
+int i386nbsd_sc_reg_offset[] =
 {
-  const struct gdbarch_tdep *tdep = regset->descr;
+  10 * 4,                      /* %eax */
+  9 * 4,                       /* %ecx */
+  8 * 4,                       /* %edx */
+  7 * 4,                       /* %ebx */
+  14 * 4,                      /* %esp */
+  6 * 4,                       /* %ebp */
+  5 * 4,                       /* %esi */
+  4 * 4,                       /* %edi */
+  11 * 4,                      /* %eip */
+  13 * 4,                      /* %eflags */
+  12 * 4,                      /* %cs */
+  15 * 4,                      /* %ss */
+  3 * 4,                       /* %ds */
+  2 * 4,                       /* %es */
+  1 * 4,                       /* %fs */
+  0 * 4                                /* %gs */
+};
 
-  gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE);
+/* 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 */
+};
 
-  i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
-  i387_supply_fsave (regcache, regnum, (char *) regs + tdep->sizeof_gregset);
-}
+static void i386nbsd_sigtramp_cache_init (const struct tramp_frame *,
+                                         struct frame_info *,
+                                         struct trad_frame_cache *,
+                                         CORE_ADDR);
 
-static const struct regset *
-i386nbsd_aout_regset_from_core_section (struct gdbarch *gdbarch,
-                                       const char *sect_name,
-                                       size_t sect_size)
+static const struct tramp_frame i386nbsd_sigtramp_sc16 =
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  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
+};
 
-  /* NetBSD a.out core dumps don't use seperate register sets for the
-     general-purpose and floating-point registers.  */
+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
+};
 
-  if (strcmp (sect_name, ".reg") == 0
-      && sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE)
-    {
-      if (tdep->gregset == NULL)
-       {
-         tdep->gregset = XMALLOC (struct regset);
-         tdep->gregset->descr = tdep;
-         tdep->gregset->supply_regset = i386nbsd_aout_supply_regset;
-       }
-      return tdep->gregset;
-    }
+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
+};
 
-  return NULL;
-}
+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
+};
 
-/* 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[] =
+static const struct tramp_frame i386nbsd_sigtramp_si4 =
 {
-  RETCODE_INSN1, 0x44, 0x24, 0x10,
-  RETCODE_INSN2,
-  RETCODE_INSN3,
-  RETCODE_INSN4, 0x27, 0x01, 0x00, 0x00,
-  RETCODE_INSN5, 0x80,
+  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 LONGEST
-i386nbsd_sigtramp_offset (CORE_ADDR pc)
+static void
+i386nbsd_sigtramp_cache_init (const struct tramp_frame *self,
+                             struct frame_info *this_frame,
+                             struct trad_frame_cache *this_cache,
+                             CORE_ADDR func)
 {
-  unsigned char ret[sizeof(sigtramp_retcode)], insn;
-  LONGEST off;
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  CORE_ADDR sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);
+  CORE_ADDR base;
+  int *reg_offset;
+  int num_regs;
   int i;
 
-  if (read_memory_nobpt (pc, &insn, 1) != 0)
-    return -1;
-
-  switch (insn)
+  if (self == &i386nbsd_sigtramp_sc16 || self == &i386nbsd_sigtramp_sc2)
     {
-    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 (read_memory_nobpt (pc + 1, &insn, 1) != 0)
-       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;
+      reg_offset = i386nbsd_sc_reg_offset;
+      num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);
 
-  if (read_memory_nobpt (pc, (char *) ret, sizeof (ret)) != 0)
-    return -1;
+      /* Read in the sigcontext address.  */
+      base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
+    }
+  else
+    {
+      reg_offset = i386nbsd_mc_reg_offset;
+      num_regs = ARRAY_SIZE (i386nbsd_mc_reg_offset);
 
-  if (memcmp (ret, sigtramp_retcode, sizeof (ret)) == 0)
-    return off;
+      /* Read in the ucontext address.  */
+      base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
+      /* offsetof(ucontext_t, uc_mcontext) == 36 */
+      base += 36;
+    }
 
-  return -1;
-}
+  for (i = 0; i < num_regs; i++)
+    if (reg_offset[i] != -1)
+      trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
 
-static int
-i386nbsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
-{
-  return (nbsd_pc_in_sigtramp (pc, name)
-         || i386nbsd_sigtramp_offset (pc) >= 0);
+  /* Construct the frame ID using the function start.  */
+  trad_frame_set_id (this_cache, frame_id_build (sp, func));
 }
-
-/* From <machine/signal.h>.  */
-int i386nbsd_sc_reg_offset[] =
-{
-  10 * 4,                      /* %eax */
-  9 * 4,                       /* %ecx */
-  8 * 4,                       /* %edx */
-  7 * 4,                       /* %ebx */
-  14 * 4,                      /* %esp */
-  6 * 4,                       /* %ebp */
-  5 * 4,                       /* %esi */
-  4 * 4,                       /* %edi */
-  11 * 4,                      /* %eip */
-  13 * 4,                      /* %eflags */
-  12 * 4,                      /* %cs */
-  15 * 4,                      /* %ss */
-  3 * 4,                       /* %ds */
-  2 * 4,                       /* %es */
-  1 * 4,                       /* %fs */
-  0 * 4                                /* %gs */
-};
+\f
 
 static void 
 i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
@@ -224,33 +278,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.  */
-  set_gdbarch_pc_in_sigtramp (gdbarch, i386nbsd_pc_in_sigtramp);
-  /* FIXME: kettenis/20020906: We should probably provide
-     NetBSD-specific versions of these functions if we want to
-     recognize signal trampolines that live on the stack.  */
-  set_gdbarch_sigtramp_start (gdbarch, NULL);
-  set_gdbarch_sigtramp_end (gdbarch, NULL);
-
   /* NetBSD uses -freg-struct-return by default.  */
   tdep->struct_return = reg_struct_return;
 
-  /* NetBSD has a `struct sigcontext' that's different from the
-     origional 4.3 BSD.  */
-  tdep->sc_reg_offset = i386nbsd_sc_reg_offset;
-  tdep->sc_num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);
-}
-
-/* NetBSD a.out.  */
-
-static void
-i386nbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
-  i386nbsd_init_abi (info, gdbarch);
-
-  /* NetBSD a.out has a single register set.  */
-  set_gdbarch_regset_from_core_section
-    (gdbarch, i386nbsd_aout_regset_from_core_section);
+  /* 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.  */
@@ -267,8 +310,6 @@ i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   i386_elf_init_abi (info, gdbarch);
 
   /* NetBSD ELF uses SVR4-style shared libraries.  */
-  set_gdbarch_in_solib_call_trampoline
-    (gdbarch, generic_in_solib_call_trampoline);
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
 
@@ -276,11 +317,12 @@ i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->struct_return = pcc_struct_return;
 }
 
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_i386nbsd_tdep;
+
 void
 _initialize_i386nbsd_tdep (void)
 {
-  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETBSD_AOUT,
-                         i386nbsdaout_init_abi);
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETBSD_ELF,
                          i386nbsdelf_init_abi);
 }
This page took 0.095409 seconds and 4 git commands to generate.