2012-03-08 Luis Machado <lgustavo@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / alpha-nat.c
index a0c53991f4d9dec42be9febdd0a7282e43c781e3..900a5861062926f0a343076a5a2b143e2db5d2dc 100644 (file)
 /* Low level Alpha interface, for GDB when running native.
-   Copyright 1993 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1995-1996, 1998-2001, 2003, 2007-2012 Free
+   Software Foundation, Inc.
 
-This file is part of GDB.
+   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
-(at your option) any later version.
+   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 3 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "gdb_string.h"
 #include "inferior.h"
 #include "gdbcore.h"
 #include "target.h"
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-/* Size of elements in jmpbuf */
-
-#define JB_ELEMENT_SIZE 8
-
-/* The definition for JB_PC in machine/reg.h is wrong.
-   And we can't get at the correct definition in setjmp.h as it is
-   not always available (eg. if _POSIX_SOURCE is defined which is the
-   default). As the defintion is unlikely to change (see comment
-   in <setjmp.h>, define the correct value here.  */
-
-#undef JB_PC
-#define JB_PC 2
-
-/* Figure out where the longjmp will land.
-   We expect the first arg to be a pointer to the jmp_buf structure from which
-   we extract the pc (JB_PC) that we will land at.  The pc is copied into PC.
-   This routine returns true on success. */
+#include "procfs.h"
+#include "regcache.h"
 
-int
-get_longjmp_target (pc)
-     CORE_ADDR *pc;
-{
-  CORE_ADDR jb_addr;
-  char raw_buffer[MAX_REGISTER_RAW_SIZE];
-
-  jb_addr = read_register(A0_REGNUM);
+#include "alpha-tdep.h"
 
-  if (target_read_memory(jb_addr + JB_PC * JB_ELEMENT_SIZE, raw_buffer,
-                        sizeof(CORE_ADDR)))
-    return 0;
+#include <sys/ptrace.h>
+#include <alpha/coreregs.h>
+#include <sys/user.h>
 
-  *pc = extract_address (raw_buffer, sizeof(CORE_ADDR));
-  return 1;
-}
 
 /* Extract the register values out of the core file and store
-   them where `read_register' will find them.
+   them into REGCACHE.
 
    CORE_REG_SECT points to the register values themselves, read into memory.
    CORE_REG_SIZE is the size of that area.
    WHICH says which set of registers we are handling (0 = int, 2 = float
-         on machines where they are discontiguous).
+   on machines where they are discontiguous).
    REG_ADDR is the offset from u.u_ar0 to the register values relative to
-            core_reg_sect.  This is used with old-fashioned core files to
-           locate the registers in a large upage-plus-stack ".reg" section.
-           Original upage address X is at location core_reg_sect+x+reg_addr.
- */
-
-void
-fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
-     char *core_reg_sect;
-     unsigned core_reg_size;
-     int which;
-     unsigned reg_addr;
+   core_reg_sect.  This is used with old-fashioned core files to
+   locate the registers in a large upage-plus-stack ".reg" section.
+   Original upage address X is at location core_reg_sect+x+reg_addr.  */
+
+static void
+fetch_osf_core_registers (struct regcache *regcache,
+                         char *core_reg_sect, unsigned core_reg_size,
+                         int which, CORE_ADDR reg_addr)
 {
-  register int regno;
-  register int addr;
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regno;
+  int addr;
   int bad_reg = -1;
 
-  /* Table to map a gdb regnum to an index in the core register section.
-     The floating point register values are garbage in OSF/1.2 core files.  */
-  static int core_reg_mapping[NUM_REGS] =
+  /* Table to map a gdb regnum to an index in the core register
+     section.  The floating point register values are garbage in
+     OSF/1.2 core files.  OSF5 uses different names for the register
+     enum list, need to handle two cases.  The actual values are the
+     same.  */
+  static int const core_reg_mapping[ALPHA_NUM_REGS] =
   {
+#ifdef NCF_REGS
+#define EFL NCF_REGS
+    CF_V0, CF_T0, CF_T1, CF_T2, CF_T3, CF_T4, CF_T5, CF_T6,
+    CF_T7, CF_S0, CF_S1, CF_S2, CF_S3, CF_S4, CF_S5, CF_S6,
+    CF_A0, CF_A1, CF_A2, CF_A3, CF_A4, CF_A5, CF_T8, CF_T9,
+    CF_T10, CF_T11, CF_RA, CF_T12, CF_AT, CF_GP, CF_SP, -1,
+    EFL + 0, EFL + 1, EFL + 2, EFL + 3,
+    EFL + 4, EFL + 5, EFL + 6, EFL + 7,
+    EFL + 8, EFL + 9, EFL + 10, EFL + 11,
+    EFL + 12, EFL + 13, EFL + 14, EFL + 15,
+    EFL + 16, EFL + 17, EFL + 18, EFL + 19,
+    EFL + 20, EFL + 21, EFL + 22, EFL + 23,
+    EFL + 24, EFL + 25, EFL + 26, EFL + 27,
+    EFL + 28, EFL + 29, EFL + 30, EFL + 31,
+    CF_PC, -1, -1
+#else
 #define EFL (EF_SIZE / 8)
-       EF_V0,  EF_T0,  EF_T1,  EF_T2,  EF_T3,  EF_T4,  EF_T5,  EF_T6,
-       EF_T7,  EF_S0,  EF_S1,  EF_S2,  EF_S3,  EF_S4,  EF_S5,  EF_S6,
-       EF_A0,  EF_A1,  EF_A2,  EF_A3,  EF_A4,  EF_A5,  EF_T8,  EF_T9,
-       EF_T10, EF_T11, EF_RA,  EF_T12, EF_AT,  EF_GP,  EF_SP,  -1,
-       EFL+0,  EFL+1,  EFL+2,  EFL+3,  EFL+4,  EFL+5,  EFL+6,  EFL+7,
-       EFL+8,  EFL+9,  EFL+10, EFL+11, EFL+12, EFL+13, EFL+14, EFL+15,
-       EFL+16, EFL+17, EFL+18, EFL+19, EFL+20, EFL+21, EFL+22, EFL+23,
-       EFL+24, EFL+25, EFL+26, EFL+27, EFL+28, EFL+29, EFL+30, EFL+31,
-       EF_PC,  -1
+    EF_V0, EF_T0, EF_T1, EF_T2, EF_T3, EF_T4, EF_T5, EF_T6,
+    EF_T7, EF_S0, EF_S1, EF_S2, EF_S3, EF_S4, EF_S5, EF_S6,
+    EF_A0, EF_A1, EF_A2, EF_A3, EF_A4, EF_A5, EF_T8, EF_T9,
+    EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1,
+    EFL + 0, EFL + 1, EFL + 2, EFL + 3,
+    EFL + 4, EFL + 5, EFL + 6, EFL + 7,
+    EFL + 8, EFL + 9, EFL + 10, EFL + 11,
+    EFL + 12, EFL + 13, EFL + 14, EFL + 15,
+    EFL + 16, EFL + 17, EFL + 18, EFL + 19,
+    EFL + 20, EFL + 21, EFL + 22, EFL + 23,
+    EFL + 24, EFL + 25, EFL + 26, EFL + 27,
+    EFL + 28, EFL + 29, EFL + 30, EFL + 31,
+    EF_PC, -1, -1
+#endif
   };
-  static char zerobuf[MAX_REGISTER_RAW_SIZE] = {0};
 
-  for (regno = 0; regno < NUM_REGS; regno++)
+  for (regno = 0; regno < ALPHA_NUM_REGS; regno++)
     {
-      if (CANNOT_FETCH_REGISTER (regno))
+      if (gdbarch_cannot_fetch_register (gdbarch, regno))
        {
-         supply_register (regno, zerobuf);
+         regcache_raw_supply (regcache, regno, NULL);
          continue;
        }
+
+      if (regno == ALPHA_ZERO_REGNUM)
+       {
+         const gdb_byte zero[8] = { 0 };
+
+         regcache_raw_supply (regcache, regno, zero);
+         continue;
+       }
+
       addr = 8 * core_reg_mapping[regno];
       if (addr < 0 || addr >= core_reg_size)
        {
+         /* ??? UNIQUE is a new addition.  Don't generate an error.  */
+         if (regno == ALPHA_UNIQUE_REGNUM)
+           {
+             regcache_raw_supply (regcache, regno, NULL);
+             continue;
+           }
          if (bad_reg < 0)
            bad_reg = regno;
        }
       else
        {
-         supply_register (regno, core_reg_sect + addr);
+         regcache_raw_supply (regcache, regno, core_reg_sect + addr);
        }
     }
   if (bad_reg >= 0)
     {
-      error ("Register %s not found in core file.", reg_names[bad_reg]);
+      error (_("Register %s not found in core file."),
+            gdbarch_register_name (gdbarch, bad_reg));
     }
 }
 
-/* Map gdb internal register number to a ptrace ``address''.
-   These ``addresses'' are defined in <sys/ptrace.h> */
 
-#define REGISTER_PTRACE_ADDR(regno) \
-   (regno < FP0_REGNUM ?       GPR_BASE + (regno) \
-  : regno == PC_REGNUM ?       PC      \
-  : regno >= FP0_REGNUM ?      FPR_BASE + ((regno) - FP0_REGNUM) \
-  : 0)
+#include <sys/procfs.h>
+/* Prototypes for supply_gregset etc.  */
+#include "gregset.h"
 
-/* Return the ptrace ``address'' of register REGNO. */
+/* See the comment in m68k-tdep.c regarding the utility of these
+   functions.  */
 
-unsigned int
-register_addr (regno, blockend)
-     int regno;
-     int blockend;
+void
+supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
+{
+  const long *regp = gregsetp->regs;
+
+  /* PC is in slot 32.  */
+  alpha_supply_int_regs (regcache, -1, regp, regp + 31, NULL);
+}
+
+void
+fill_gregset (const struct regcache *regcache,
+             gdb_gregset_t *gregsetp, int regno)
 {
-  return REGISTER_PTRACE_ADDR (regno);
+  long *regp = gregsetp->regs;
+
+  /* PC is in slot 32.  */
+  alpha_fill_int_regs (regcache, regno, regp, regp + 31, NULL);
+}
+
+/* Now we do the same thing for floating-point registers.
+   Again, see the comments in m68k-tdep.c.  */
+
+void
+supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
+{
+  const long *regp = fpregsetp->regs;
+
+  /* FPCR is in slot 32.  */
+  alpha_supply_fp_regs (regcache, -1, regp, regp + 31);
+}
+
+void
+fill_fpregset (const struct regcache *regcache,
+              gdb_fpregset_t *fpregsetp, int regno)
+{
+  long *regp = fpregsetp->regs;
+
+  /* FPCR is in slot 32.  */
+  alpha_fill_fp_regs (regcache, regno, regp, regp + 31);
+}
+\f
+
+/* Register that we are able to handle alpha core file formats.  */
+
+static struct core_fns alpha_osf_core_fns =
+{
+  /* This really is bfd_target_unknown_flavour.  */
+
+  bfd_target_unknown_flavour,          /* core_flavour */
+  default_check_format,                        /* check_format */
+  default_core_sniffer,                        /* core_sniffer */
+  fetch_osf_core_registers,            /* core_read_registers */
+  NULL                                 /* next */
+};
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_alpha_nat;
+
+void
+_initialize_alpha_nat (void)
+{
+  struct target_ops *t;
+
+  t = procfs_target ();
+  add_target (t);
+
+  deprecated_add_core_fns (&alpha_osf_core_fns);
 }
This page took 0.051189 seconds and 4 git commands to generate.