* Makefile.in (ALLDEPFILES): Update.
[deliverable/binutils-gdb.git] / gdb / ia64-linux-nat.c
index 338adbe44ac6a3a315aacf99aa92f1b65b61a04b..f570a967a6053013f6d6071c2a2f9d7025a50d4d 100644 (file)
@@ -1,5 +1,8 @@
-/* Functions specific to running gdb native on IA-64 running Linux.
-   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+/* Functions specific to running gdb native on IA-64 running
+   GNU/Linux.
+
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
+#include "gdb_string.h"
 #include "inferior.h"
 #include "target.h"
 #include "gdbcore.h"
 #include "regcache.h"
+#include "ia64-tdep.h"
+#include "linux-nat.h"
 
 #include <signal.h>
 #include <sys/ptrace.h>
-#include <sys/wait.h>
+#include "gdb_wait.h"
 #ifdef HAVE_SYS_REG_H
 #include <sys/reg.h>
 #endif
+#include <sys/syscall.h>
 #include <sys/user.h>
 
 #include <asm/ptrace_offsets.h>
@@ -302,7 +309,7 @@ register_addr (int regno, CORE_ADDR blockend)
   CORE_ADDR addr;
 
   if (regno < 0 || regno >= NUM_REGS)
-    error ("Invalid register number %d.", regno);
+    error (_("Invalid register number %d."), regno);
 
   if (u_offsets[regno] == -1)
     addr = 0;
@@ -338,7 +345,7 @@ int ia64_cannot_store_register (regno)
      to be changed by (roughly) N as well.  (It could be N-1 or N+1
      depending upon where the NaT collection bits fall.)
 
-     OTOH, the linux kernel provides read/write access to bsp (and
+     OTOH, the Linux kernel provides read/write access to bsp (and
      currently read/write access to bspstore as well).  But it
      is definitely the case that if you change one, the other
      will change at the same time.  It is more useful to gdb to
@@ -362,32 +369,47 @@ supply_gregset (gregset_t *gregsetp)
 
   for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
     {
-      supply_register (regi, (char *) (regp + (regi - IA64_GR0_REGNUM)));
+      regcache_raw_supply (current_regcache, regi,
+                          (char *) (regp + (regi - IA64_GR0_REGNUM)));
     }
 
   /* FIXME: NAT collection bits are at index 32; gotta deal with these
      somehow... */
 
-  supply_register (IA64_PR_REGNUM, (char *) (regp + 33));
+  regcache_raw_supply (current_regcache, IA64_PR_REGNUM, (char *) (regp + 33));
 
   for (regi = IA64_BR0_REGNUM; regi <= IA64_BR7_REGNUM; regi++)
     {
-      supply_register (regi, (char *) (regp + 34 + (regi - IA64_BR0_REGNUM)));
+      regcache_raw_supply (current_regcache, regi,
+                          (char *) (regp + 34 + (regi - IA64_BR0_REGNUM)));
     }
 
-  supply_register (IA64_IP_REGNUM, (char *) (regp + 42));
-  supply_register (IA64_CFM_REGNUM, (char *) (regp + 43));
-  supply_register (IA64_PSR_REGNUM, (char *) (regp + 44));
-  supply_register (IA64_RSC_REGNUM, (char *) (regp + 45));
-  supply_register (IA64_BSP_REGNUM, (char *) (regp + 46));
-  supply_register (IA64_BSPSTORE_REGNUM, (char *) (regp + 47));
-  supply_register (IA64_RNAT_REGNUM, (char *) (regp + 48));
-  supply_register (IA64_CCV_REGNUM, (char *) (regp + 49));
-  supply_register (IA64_UNAT_REGNUM, (char *) (regp + 50));
-  supply_register (IA64_FPSR_REGNUM, (char *) (regp + 51));
-  supply_register (IA64_PFS_REGNUM, (char *) (regp + 52));
-  supply_register (IA64_LC_REGNUM, (char *) (regp + 53));
-  supply_register (IA64_EC_REGNUM, (char *) (regp + 54));
+  regcache_raw_supply (current_regcache, IA64_IP_REGNUM,
+                      (char *) (regp + 42));
+  regcache_raw_supply (current_regcache, IA64_CFM_REGNUM,
+                      (char *) (regp + 43));
+  regcache_raw_supply (current_regcache, IA64_PSR_REGNUM,
+                      (char *) (regp + 44));
+  regcache_raw_supply (current_regcache, IA64_RSC_REGNUM,
+                      (char *) (regp + 45));
+  regcache_raw_supply (current_regcache, IA64_BSP_REGNUM,
+                      (char *) (regp + 46));
+  regcache_raw_supply (current_regcache, IA64_BSPSTORE_REGNUM,
+                      (char *) (regp + 47));
+  regcache_raw_supply (current_regcache, IA64_RNAT_REGNUM,
+                      (char *) (regp + 48));
+  regcache_raw_supply (current_regcache, IA64_CCV_REGNUM,
+                      (char *) (regp + 49));
+  regcache_raw_supply (current_regcache, IA64_UNAT_REGNUM,
+                      (char *) (regp + 50));
+  regcache_raw_supply (current_regcache, IA64_FPSR_REGNUM,
+                      (char *) (regp + 51));
+  regcache_raw_supply (current_regcache, IA64_PFS_REGNUM,
+                      (char *) (regp + 52));
+  regcache_raw_supply (current_regcache, IA64_LC_REGNUM,
+                      (char *) (regp + 53));
+  regcache_raw_supply (current_regcache, IA64_EC_REGNUM,
+                      (char *) (regp + 54));
 }
 
 void
@@ -398,8 +420,7 @@ fill_gregset (gregset_t *gregsetp, int regno)
 
 #define COPY_REG(_idx_,_regi_) \
   if ((regno == -1) || regno == _regi_) \
-    memcpy (regp + _idx_, &registers[REGISTER_BYTE (_regi_)], \
-           REGISTER_RAW_SIZE (_regi_))
+    regcache_raw_collect (current_regcache, _regi_, regp + _idx_)
 
   for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
     {
@@ -437,13 +458,13 @@ fill_gregset (gregset_t *gregsetp, int regno)
 void
 supply_fpregset (fpregset_t *fpregsetp)
 {
-  register int regi;
+  int regi;
   char *from;
 
   for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
     {
       from = (char *) &((*fpregsetp)[regi - IA64_FR0_REGNUM]);
-      supply_register (regi, from);
+      regcache_raw_supply (current_regcache, regi, from);
     }
 }
 
@@ -456,17 +477,12 @@ void
 fill_fpregset (fpregset_t *fpregsetp, int regno)
 {
   int regi;
-  char *to;
-  char *from;
 
   for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
     {
       if ((regno == -1) || (regno == regi))
-       {
-         from = (char *) &registers[REGISTER_BYTE (regi)];
-         to = (char *) &((*fpregsetp)[regi - IA64_FR0_REGNUM]);
-         memcpy (to, from, REGISTER_RAW_SIZE (regi));
-       }
+       regcache_raw_collect (current_regcache, regi,
+                             &((*fpregsetp)[regi - IA64_FR0_REGNUM]));
     }
 }
 
@@ -497,7 +513,7 @@ fetch_debug_register (ptid_t ptid, int idx)
   if (tid == 0)
     tid = PIDGET (ptid);
 
-  val = ptrace (PT_READ_U, tid, (PTRACE_ARG3_TYPE) (PT_DBR + 8 * idx), 0);
+  val = ptrace (PT_READ_U, tid, (PTRACE_TYPE_ARG3) (PT_DBR + 8 * idx), 0);
 
   return val;
 }
@@ -511,7 +527,7 @@ store_debug_register (ptid_t ptid, int idx, long val)
   if (tid == 0)
     tid = PIDGET (ptid);
 
-  (void) ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) (PT_DBR + 8 * idx), val);
+  (void) ptrace (PT_WRITE_U, tid, (PTRACE_TYPE_ARG3) (PT_DBR + 8 * idx), val);
 }
 
 static void
@@ -616,21 +632,23 @@ ia64_linux_remove_watchpoint (ptid_t ptid, CORE_ADDR addr, int len)
   return -1;
 }
 
-CORE_ADDR
-ia64_linux_stopped_by_watchpoint (ptid_t ptid)
+int
+ia64_linux_stopped_data_address (CORE_ADDR *addr_p)
 {
   CORE_ADDR psr;
   int tid;
   struct siginfo siginfo;
+  ptid_t ptid = inferior_ptid;
 
   tid = TIDGET(ptid);
   if (tid == 0)
     tid = PIDGET (ptid);
   
   errno = 0;
-  ptrace (PTRACE_GETSIGINFO, tid, (PTRACE_ARG3_TYPE) 0, &siginfo);
+  ptrace (PTRACE_GETSIGINFO, tid, (PTRACE_TYPE_ARG3) 0, &siginfo);
 
-  if (errno != 0 || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
+  if (errno != 0 || siginfo.si_signo != SIGTRAP || 
+      (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
     return 0;
 
   psr = read_register_pid (IA64_PSR_REGNUM, ptid);
@@ -638,5 +656,49 @@ ia64_linux_stopped_by_watchpoint (ptid_t ptid)
                            for the next instruction */
   write_register_pid (IA64_PSR_REGNUM, psr, ptid);
 
-  return (CORE_ADDR) siginfo.si_addr;
+  *addr_p = (CORE_ADDR)siginfo.si_addr;
+  return 1;
+}
+
+int
+ia64_linux_stopped_by_watchpoint (void)
+{
+  CORE_ADDR addr;
+  return ia64_linux_stopped_data_address (&addr);
+}
+
+static LONGEST (*super_xfer_partial) (struct target_ops *, enum target_object,
+                                     const char *, gdb_byte *, const gdb_byte *,
+                                     ULONGEST, LONGEST);
+
+static LONGEST 
+ia64_linux_xfer_partial (struct target_ops *ops,
+                        enum target_object object,
+                        const char *annex,
+                        gdb_byte *readbuf, const gdb_byte *writebuf,
+                        ULONGEST offset, LONGEST len)
+{
+  if (object == TARGET_OBJECT_UNWIND_TABLE && writebuf == NULL && offset == 0)
+    return syscall (__NR_getunwind, readbuf, len);
+
+  return super_xfer_partial (ops, object, annex, readbuf, writebuf,
+                            offset, len);
+}
+
+void _initialize_ia64_linux_nat (void);
+
+void
+_initialize_ia64_linux_nat (void)
+{
+  struct target_ops *t = linux_target ();
+
+  /* Fill in the generic GNU/Linux methods.  */
+  t = linux_target ();
+
+  /* Override the default to_xfer_partial.  */
+  super_xfer_partial = t->to_xfer_partial;
+  t->to_xfer_partial = ia64_linux_xfer_partial;
+
+  /* Register the target.  */
+  add_target (t);
 }
This page took 0.034869 seconds and 4 git commands to generate.