2002-05-11 Daniel Jacobowitz <drow@mvista.com>
[deliverable/binutils-gdb.git] / gdb / alphanbsd-tdep.c
index 3f3ae529e52e849485a9bd350345ed619ed59619..d10a3cab1597762c4488948f7456abd48536969d 100644 (file)
 
 #include "defs.h"
 #include "gdbcore.h"
+#include "regcache.h"
 #include "value.h"
-#include "solib-svr4.h"
 
 #include "alpha-tdep.h"
+#include "alphabsd-tdep.h"
+#include "nbsd-tdep.h"
 
-/* Fetch (and possibly build) an appropriate link_map_offsets
-   structure for NetBSD/alpha targets using the struct offsets
-   defined in <link.h> (but without actual reference to that file).
-
-   This makes it possible to access NetBSD/alpha shared libraries
-   from a GDB that was not built on a NetBSD/alpha host (for cross
-   debugging).  */
-
-static struct link_map_offsets *
-alphanbsd_solib_svr4_fetch_link_map_offsets (void)
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+                      CORE_ADDR ignore)
 {
-  static struct link_map_offsets lmo;
-  static struct link_map_offsets *lmp = NULL;
-
-  if (lmp == NULL)
+  char *regs, *fpregs;
+  int regno;
+
+  /* Table to map a gdb register number to a trapframe register index.  */
+  static const int regmap[] =
+  {
+     0,   1,   2,   3,
+     4,   5,   6,   7,
+     8,   9,  10,  11,
+    12,  13,  14,  15, 
+    30,  31,  32,  16, 
+    17,  18,  19,  20,
+    21,  22,  23,  24,
+    25,  29,  26
+  };
+#define SIZEOF_TRAPFRAME (33 * 8)
+
+  /* We get everything from one section.  */
+  if (which != 0)
+    return;
+
+  regs = core_reg_sect;
+  fpregs = core_reg_sect + SIZEOF_TRAPFRAME;
+
+  if (core_reg_size < (SIZEOF_TRAPFRAME + SIZEOF_STRUCT_FPREG))
     {
-      lmp = &lmo;
-
-      lmo.r_debug_size = 32;
-
-      lmo.r_map_offset = 8;
-      lmo.r_map_size   = 8;
-
-      lmo.link_map_size = 40;
-
-      lmo.l_addr_offset = 0;
-      lmo.l_addr_size   = 8;
+      warning ("Wrong size register set in core file.");
+      return;
+    }
 
-      lmo.l_name_offset = 8;
-      lmo.l_name_size   = 8;
+  /* Integer registers.  */
+  for (regno = 0; regno < ALPHA_ZERO_REGNUM; regno++)
+    supply_register (regno, regs + (regmap[regno] * 8));
+  supply_register (ALPHA_ZERO_REGNUM, NULL);
+  supply_register (FP_REGNUM, NULL);
+  supply_register (PC_REGNUM, regs + (28 * 8));
 
-      lmo.l_next_offset = 24;
-      lmo.l_next_size   = 8;
+  /* Floating point registers.  */
+  alphabsd_supply_fpreg (fpregs, -1);
+}
 
-      lmo.l_prev_offset = 32;
-      lmo.l_prev_size   = 8;
+static void
+fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+                         CORE_ADDR ignore)
+{
+  switch (which)
+    {
+    case 0:  /* Integer registers.  */
+      if (core_reg_size != SIZEOF_STRUCT_REG)
+       warning ("Wrong size register set in core file.");
+      else
+       alphabsd_supply_reg (core_reg_sect, -1);
+      break;
+
+    case 2:  /* Floating point registers.  */
+      if (core_reg_size != SIZEOF_STRUCT_FPREG)
+       warning ("Wrong size FP register set in core file.");
+      else
+       alphabsd_supply_fpreg (core_reg_sect, -1);
+      break;
+
+    default:
+      /* Don't know what kind of register request this is; just ignore it.  */
+      break;
     }
-
-  return lmp;
 }
 
+static struct core_fns alphanbsd_core_fns =
+{
+  bfd_target_unknown_flavour,          /* core_flavour */
+  default_check_format,                        /* check_format */
+  default_core_sniffer,                        /* core_sniffer */
+  fetch_core_registers,                        /* core_read_registers */
+  NULL                                 /* next */
+};
+
+static struct core_fns alphanbsd_elfcore_fns =
+{
+  bfd_target_elf_flavour,              /* core_flavour */
+  default_check_format,                        /* check_format */
+  default_core_sniffer,                        /* core_sniffer */
+  fetch_elfcore_registers,             /* core_read_registers */
+  NULL                                 /* next */
+};
+
 /* Under NetBSD/alpha, 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
@@ -123,24 +173,38 @@ alphanbsd_sigtramp_offset (CORE_ADDR pc)
   return -1;
 }
 
+static int
+alphanbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
+{
+  return (alphanbsd_sigtramp_offset (pc) >= 0);
+}
+
 static void
 alphanbsd_init_abi (struct gdbarch_info info,
                     struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
+  set_gdbarch_pc_in_sigtramp (gdbarch, alphanbsd_pc_in_sigtramp);
+
   /* NetBSD/alpha does not provide single step support via ptrace(2); we
      must use software single-stepping.  */
   set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
 
   set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                  alphanbsd_solib_svr4_fetch_link_map_offsets);
+                                 nbsd_lp64_solib_svr4_fetch_link_map_offsets);
 
   tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
+
+  tdep->jb_pc = 2;
+  tdep->jb_elt_size = 8;
 }
 
 void
 _initialize_alphanbsd_tdep (void)
 {
   alpha_gdbarch_register_os_abi (ALPHA_ABI_NETBSD, alphanbsd_init_abi);
+
+  add_core_fns (&alphanbsd_core_fns);
+  add_core_fns (&alphanbsd_elfcore_fns);
 }
This page took 0.027551 seconds and 4 git commands to generate.