add "this" pointers to more target APIs
[binutils-gdb.git] / gdb / arm-linux-nat.c
index f64c37c263670f3c03df9de476c4a593cac534b6..9fa5f5b16635bb439e191074c98a26082f6b1935 100644 (file)
@@ -1,6 +1,5 @@
 /* GNU/Linux on ARM native support.
-   Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009,
-   2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1999-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -20,7 +19,7 @@
 #include "defs.h"
 #include "inferior.h"
 #include "gdbcore.h"
-#include "gdb_string.h"
+#include <string.h>
 #include "regcache.h"
 #include "target.h"
 #include "linux-nat.h"
@@ -72,34 +71,18 @@ static int arm_linux_vfp_register_count;
 
 extern int arm_apcs_32;
 
-/* The following variables are used to determine the version of the
-   underlying GNU/Linux operating system.  Examples:
-
-   GNU/Linux 2.0.35             GNU/Linux 2.2.12
-   os_version = 0x00020023      os_version = 0x0002020c
-   os_major = 2                 os_major = 2
-   os_minor = 0                 os_minor = 2
-   os_release = 35              os_release = 12
-
-   Note: os_version = (os_major << 16) | (os_minor << 8) | os_release
-
-   These are initialized using get_linux_version() from
-   _initialize_arm_linux_nat().  */
-
-static unsigned int os_version, os_major, os_minor, os_release;
-
 /* On GNU/Linux, threads are implemented as pseudo-processes, in which
    case we may be tracing more than one process at a time.  In that
    case, inferior_ptid will contain the main process ID and the
    individual thread (process) ID.  get_thread_id () is used to get
    the thread id if it's available, and the process id otherwise.  */
 
-int
+static int
 get_thread_id (ptid_t ptid)
 {
-  int tid = TIDGET (ptid);
+  int tid = ptid_get_lwp (ptid);
   if (0 == tid)
-    tid = PIDGET (ptid);
+    tid = ptid_get_pid (ptid);
   return tid;
 }
 
@@ -644,31 +627,6 @@ ps_get_thread_area (const struct ps_prochandle *ph,
   return PS_OK;
 }
 
-static unsigned int
-get_linux_version (unsigned int *vmajor,
-                  unsigned int *vminor,
-                  unsigned int *vrelease)
-{
-  struct utsname info;
-  char *pmajor, *pminor, *prelease, *tail;
-
-  if (-1 == uname (&info))
-    {
-      warning (_("Unable to determine GNU/Linux version."));
-      return -1;
-    }
-
-  pmajor = strtok (info.release, ".");
-  pminor = strtok (NULL, ".");
-  prelease = strtok (NULL, ".");
-
-  *vmajor = (unsigned int) strtoul (pmajor, &tail, 0);
-  *vminor = (unsigned int) strtoul (pminor, &tail, 0);
-  *vrelease = (unsigned int) strtoul (prelease, &tail, 0);
-
-  return ((*vmajor << 16) | (*vminor << 8) | *vrelease);
-}
-
 static const struct target_desc *
 arm_linux_read_description (struct target_ops *ops)
 {
@@ -713,7 +671,7 @@ arm_linux_read_description (struct target_ops *ops)
 
       /* Now make sure that the kernel supports reading these
         registers.  Support was added in 2.6.30.  */
-      pid = GET_LWP (inferior_ptid);
+      pid = ptid_get_lwp (inferior_ptid);
       errno = 0;
       buf = alloca (VFP_REGS_SIZE);
       if (ptrace (PTRACE_GETVFPREGS, pid, 0, buf) < 0
@@ -938,11 +896,17 @@ arm_linux_hw_breakpoint_initialize (struct gdbarch *gdbarch,
   /* We have to create a mask for the control register which says which bits
      of the word pointed to by address to break on.  */
   if (arm_pc_is_thumb (gdbarch, address))
-    mask = 0x3 << (address & 2);
+    {
+      mask = 0x3;
+      address &= ~1;
+    }
   else
-    mask = 0xf;
+    {
+      mask = 0xf;
+      address &= ~3;
+    }
 
-  p->address = (unsigned int) (address & ~3);
+  p->address = (unsigned int) address;
   p->control = arm_hwbp_control_initialize (mask, arm_hwbp_break, 1);
 }
 
@@ -1075,7 +1039,6 @@ static int
 arm_linux_insert_hw_breakpoint (struct gdbarch *gdbarch, 
                                struct bp_target_info *bp_tgt)
 {
-  ptid_t ptid;
   struct lwp_info *lp;
   struct arm_linux_hw_breakpoint p;
 
@@ -1083,8 +1046,8 @@ arm_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
     return -1;
 
   arm_linux_hw_breakpoint_initialize (gdbarch, bp_tgt, &p);
-  ALL_LWPS (lp, ptid)
-    arm_linux_insert_hw_breakpoint1 (&p, TIDGET (ptid), 0);
+  ALL_LWPS (lp)
+    arm_linux_insert_hw_breakpoint1 (&p, ptid_get_lwp (lp->ptid), 0);
 
   return 0;
 }
@@ -1094,7 +1057,6 @@ static int
 arm_linux_remove_hw_breakpoint (struct gdbarch *gdbarch, 
                                struct bp_target_info *bp_tgt)
 {
-  ptid_t ptid;
   struct lwp_info *lp;
   struct arm_linux_hw_breakpoint p;
 
@@ -1102,8 +1064,8 @@ arm_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
     return -1;
 
   arm_linux_hw_breakpoint_initialize (gdbarch, bp_tgt, &p);
-  ALL_LWPS (lp, ptid)
-    arm_linux_remove_hw_breakpoint1 (&p, TIDGET (ptid), 0);
+  ALL_LWPS (lp)
+    arm_linux_remove_hw_breakpoint1 (&p, ptid_get_lwp (lp->ptid), 0);
 
   return 0;
 }
@@ -1146,7 +1108,6 @@ static int
 arm_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
                             struct expression *cond)
 {
-  ptid_t ptid;
   struct lwp_info *lp;
   struct arm_linux_hw_breakpoint p;
 
@@ -1154,8 +1115,8 @@ arm_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
     return -1;
 
   arm_linux_hw_watchpoint_initialize (addr, len, rw, &p);
-  ALL_LWPS (lp, ptid)
-    arm_linux_insert_hw_breakpoint1 (&p, TIDGET (ptid), 1);
+  ALL_LWPS (lp)
+    arm_linux_insert_hw_breakpoint1 (&p, ptid_get_lwp (lp->ptid), 1);
 
   return 0;
 }
@@ -1165,7 +1126,6 @@ static int
 arm_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
                             struct expression *cond)
 {
-  ptid_t ptid;
   struct lwp_info *lp;
   struct arm_linux_hw_breakpoint p;
 
@@ -1173,8 +1133,8 @@ arm_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
     return -1;
 
   arm_linux_hw_watchpoint_initialize (addr, len, rw, &p);
-  ALL_LWPS (lp, ptid)
-    arm_linux_remove_hw_breakpoint1 (&p, TIDGET (ptid), 1);
+  ALL_LWPS (lp)
+    arm_linux_remove_hw_breakpoint1 (&p, ptid_get_lwp (lp->ptid), 1);
 
   return 0;
 }
@@ -1183,33 +1143,38 @@ arm_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
 static int
 arm_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
 {
-  struct siginfo *siginfo_p = linux_nat_get_siginfo (inferior_ptid);
-  int slot = siginfo_p->si_errno;
+  siginfo_t siginfo;
+  int slot;
+
+  if (!linux_nat_get_siginfo (inferior_ptid, &siginfo))
+    return 0;
 
   /* This must be a hardware breakpoint.  */
-  if (siginfo_p->si_signo != SIGTRAP
-      || (siginfo_p->si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
+  if (siginfo.si_signo != SIGTRAP
+      || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
     return 0;
 
   /* We must be able to set hardware watchpoints.  */
   if (arm_linux_get_hw_watchpoint_count () == 0)
     return 0;
 
+  slot = siginfo.si_errno;
+
   /* If we are in a positive slot then we're looking at a breakpoint and not
      a watchpoint.  */
   if (slot >= 0)
     return 0;
 
-  *addr_p = (CORE_ADDR) (uintptr_t) siginfo_p->si_addr;
+  *addr_p = (CORE_ADDR) (uintptr_t) siginfo.si_addr;
   return 1;
 }
 
 /* Has the target been stopped by hitting a watchpoint?  */
 static int
-arm_linux_stopped_by_watchpoint (void)
+arm_linux_stopped_by_watchpoint (struct target_ops *ops)
 {
   CORE_ADDR addr;
-  return arm_linux_stopped_data_address (&current_target, &addr);
+  return arm_linux_stopped_data_address (ops, &addr);
 }
 
 static int
@@ -1223,9 +1188,9 @@ arm_linux_watchpoint_addr_within_range (struct target_ops *target,
 /* Handle thread creation.  We need to copy the breakpoints and watchpoints
    in the parent thread to the child thread.  */
 static void
-arm_linux_new_thread (ptid_t ptid)
+arm_linux_new_thread (struct lwp_info *lp)
 {
-  int tid = TIDGET (ptid);
+  int tid = ptid_get_lwp (lp->ptid);
   const struct arm_linux_hwbp_cap *info = arm_linux_get_hwbp_cap ();
 
   if (info != NULL)
@@ -1260,7 +1225,7 @@ arm_linux_thread_exit (struct thread_info *tp, int silent)
   if (info != NULL)
     {
       int i;
-      int tid = TIDGET (tp->ptid);
+      int tid = ptid_get_lwp (tp->ptid);
       struct arm_linux_thread_points *t = NULL, *p;
 
       for (i = 0; 
@@ -1291,8 +1256,6 @@ _initialize_arm_linux_nat (void)
 {
   struct target_ops *t;
 
-  os_version = get_linux_version (&os_major, &os_minor, &os_release);
-
   /* Fill in the generic GNU/Linux methods.  */
   t = linux_target ();