add "this" pointers to more target APIs
[deliverable/binutils-gdb.git] / gdb / i386-nat.c
index 559bc29b44d5c7b69885fe98fef9709bfd2d17b8..23edc38a4044184cf64fd3e8b27caeebbadcbb5c 100644 (file)
@@ -1,7 +1,6 @@
 /* Native-dependent code for the i386.
 
-   Copyright (C) 2001, 2004-2005, 2007-2012 Free Software Foundation,
-   Inc.
+   Copyright (C) 2001-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -154,104 +153,102 @@ struct i386_dr_low_type i386_dr_low;
 /* A macro to loop over all debug registers.  */
 #define ALL_DEBUG_REGISTERS(i) for (i = 0; i < DR_NADDR; i++)
 
-/* Clear the reference counts and forget everything we knew about the
-   debug registers.  */
+/* Per-process data.  We don't bind this to a per-inferior registry
+   because of targets like x86 GNU/Linux that need to keep track of
+   processes that aren't bound to any inferior (e.g., fork children,
+   checkpoints).  */
 
-static void
-i386_init_dregs (struct i386_debug_reg_state *state)
+struct i386_process_info
 {
-  int i;
-
-  ALL_DEBUG_REGISTERS (i)
-    {
-      state->dr_mirror[i] = 0;
-      state->dr_ref_count[i] = 0;
-    }
-  state->dr_control_mirror = 0;
-  state->dr_status_mirror  = 0;
-}
+  /* Linked list.  */
+  struct i386_process_info *next;
 
-/* Per-inferior data key.  */
-static const struct inferior_data *i386_inferior_data;
+  /* The process identifier.  */
+  pid_t pid;
 
-/* Per-inferior data.  */
-struct i386_inferior_data
-{
-  /* Copy of i386 hardware debug registers for performance reasons.  */
+  /* Copy of i386 hardware debug registers.  */
   struct i386_debug_reg_state state;
 };
 
-/* Per-inferior hook for register_inferior_data_with_cleanup.  */
+static struct i386_process_info *i386_process_list = NULL;
 
-static void
-i386_inferior_data_cleanup (struct inferior *inf, void *arg)
+/* Find process data for process PID.  */
+
+static struct i386_process_info *
+i386_find_process_pid (pid_t pid)
 {
-  struct i386_inferior_data *inf_data = arg;
+  struct i386_process_info *proc;
+
+  for (proc = i386_process_list; proc; proc = proc->next)
+    if (proc->pid == pid)
+      return proc;
 
-  xfree (inf_data);
+  return NULL;
 }
 
-/* Get data specific for INFERIOR_PTID LWP.  Return special data area
-   for processes being detached.  */
+/* Add process data for process PID.  Returns newly allocated info
+   object.  */
 
-static struct i386_inferior_data *
-i386_inferior_data_get (void)
+static struct i386_process_info *
+i386_add_process (pid_t pid)
 {
-  struct inferior *inf = current_inferior ();
-  struct i386_inferior_data *inf_data;
+  struct i386_process_info *proc;
 
-  inf_data = inferior_data (inf, i386_inferior_data);
-  if (inf_data == NULL)
-    {
-      inf_data = xzalloc (sizeof (*inf_data));
-      set_inferior_data (current_inferior (), i386_inferior_data, inf_data);
-    }
+  proc = xcalloc (1, sizeof (*proc));
+  proc->pid = pid;
 
-  if (inf->pid != ptid_get_pid (inferior_ptid))
-    {
-      /* INFERIOR_PTID is being detached from the inferior INF.
-        Provide local cache specific for the detached LWP.  */
+  proc->next = i386_process_list;
+  i386_process_list = proc;
 
-      static struct i386_inferior_data detached_inf_data_local;
-      static int detached_inf_pid = -1;
+  return proc;
+}
 
-      if (detached_inf_pid != ptid_get_pid (inferior_ptid))
-       {
-         /* Reinitialize the local cache if INFERIOR_PTID is
-            different from the LWP last detached.
-            Linux kernel before 2.6.33 commit
-            72f674d203cd230426437cdcf7dd6f681dad8b0d
-            will inherit hardware debug registers from parent
-            on fork/vfork/clone.  Newer Linux kernels create such tasks with
-            zeroed debug registers.
-
-            GDB will remove all breakpoints (and watchpoints) from the forked
-            off process.  We also need to reset the debug registers in that
-            process to be compatible with the older Linux kernels.
-
-            Copy the debug registers mirrors into the new process so that all
-            breakpoints and watchpoints can be removed together.  The debug
-            registers mirror will become zeroed in the end before detaching
-            the forked off process.  */
-
-         detached_inf_pid = ptid_get_pid (inferior_ptid);
-         detached_inf_data_local = *inf_data;
-       }
+/* Get data specific info for process PID, creating it if necessary.
+   Never returns NULL.  */
 
-      return &detached_inf_data_local;
-    }
+static struct i386_process_info *
+i386_process_info_get (pid_t pid)
+{
+  struct i386_process_info *proc;
+
+  proc = i386_find_process_pid (pid);
+  if (proc == NULL)
+    proc = i386_add_process (pid);
 
-  return inf_data;
+  return proc;
 }
 
-/* Get debug registers state for INFERIOR_PTID, see
-   i386_inferior_data_get.  */
+/* Get debug registers state for process PID.  */
 
 struct i386_debug_reg_state *
-i386_debug_reg_state (void)
+i386_debug_reg_state (pid_t pid)
 {
-  return &i386_inferior_data_get ()->state;
+  return &i386_process_info_get (pid)->state;
+}
+
+/* See declaration in i386-nat.h.  */
+
+void
+i386_forget_process (pid_t pid)
+{
+  struct i386_process_info *proc, **proc_link;
+
+  proc = i386_process_list;
+  proc_link = &i386_process_list;
+
+  while (proc != NULL)
+    {
+      if (proc->pid == pid)
+       {
+         *proc_link = proc->next;
+
+         xfree (proc);
+         return;
+       }
+
+      proc_link = &proc->next;
+      proc = *proc_link;
+    }
 }
 
 /* Whether or not to print the mirrored debug registers.  */
@@ -304,9 +301,8 @@ static int i386_handle_nonaligned_watchpoint (struct i386_debug_reg_state *state
 void
 i386_cleanup_dregs (void)
 {
-  struct i386_debug_reg_state *state = i386_debug_reg_state ();
-
-  i386_init_dregs (state);
+  /* Starting from scratch has the same effect.  */
+  i386_forget_process (ptid_get_pid (inferior_ptid));
 }
 
 /* Print the values of the mirrored debug registers.  This is called
@@ -318,7 +314,7 @@ i386_show_dr (struct i386_debug_reg_state *state,
              const char *func, CORE_ADDR addr,
              int len, enum target_hw_bp_type type)
 {
-  int addr_size = gdbarch_addr_bit (target_gdbarch) / 8;
+  int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
   int i;
 
   puts_unfiltered (func);
@@ -570,7 +566,8 @@ Invalid value %d of operation in i386_handle_nonaligned_watchpoint.\n"),
 static void
 i386_update_inferior_debug_regs (struct i386_debug_reg_state *new_state)
 {
-  struct i386_debug_reg_state *state = i386_debug_reg_state ();
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   int i;
 
   ALL_DEBUG_REGISTERS (i)
@@ -595,7 +592,8 @@ static int
 i386_insert_watchpoint (CORE_ADDR addr, int len, int type,
                        struct expression *cond)
 {
-  struct i386_debug_reg_state *state = i386_debug_reg_state ();
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   int retval;
   /* Work on a local copy of the debug registers, and on success,
      commit the change back to the inferior.  */
@@ -632,7 +630,8 @@ static int
 i386_remove_watchpoint (CORE_ADDR addr, int len, int type,
                        struct expression *cond)
 {
-  struct i386_debug_reg_state *state = i386_debug_reg_state ();
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   int retval;
   /* Work on a local copy of the debug registers, and on success,
      commit the change back to the inferior.  */
@@ -665,7 +664,8 @@ i386_remove_watchpoint (CORE_ADDR addr, int len, int type,
 static int
 i386_region_ok_for_watchpoint (CORE_ADDR addr, int len)
 {
-  struct i386_debug_reg_state *state = i386_debug_reg_state ();
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   int nregs;
 
   /* Compute how many aligned watchpoints we would need to cover this
@@ -682,7 +682,8 @@ i386_region_ok_for_watchpoint (CORE_ADDR addr, int len)
 static int
 i386_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
 {
-  struct i386_debug_reg_state *state = i386_debug_reg_state ();
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   CORE_ADDR addr = 0;
   int i;
   int rc = 0;
@@ -755,10 +756,10 @@ i386_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
 }
 
 static int
-i386_stopped_by_watchpoint (void)
+i386_stopped_by_watchpoint (struct target_ops *ops)
 {
   CORE_ADDR addr = 0;
-  return i386_stopped_data_address (&current_target, &addr);
+  return i386_stopped_data_address (ops, &addr);
 }
 
 /* Insert a hardware-assisted breakpoint at BP_TGT->placed_address.
@@ -767,7 +768,8 @@ static int
 i386_insert_hw_breakpoint (struct gdbarch *gdbarch,
                           struct bp_target_info *bp_tgt)
 {
-  struct i386_debug_reg_state *state = i386_debug_reg_state ();
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   unsigned len_rw = i386_length_and_rw_bits (1, hw_execute);
   CORE_ADDR addr = bp_tgt->placed_address;
   /* Work on a local copy of the debug registers, and on success,
@@ -792,7 +794,8 @@ static int
 i386_remove_hw_breakpoint (struct gdbarch *gdbarch,
                           struct bp_target_info *bp_tgt)
 {
-  struct i386_debug_reg_state *state = i386_debug_reg_state ();
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   unsigned len_rw = i386_length_and_rw_bits (1, hw_execute);
   CORE_ADDR addr = bp_tgt->placed_address;
   /* Work on a local copy of the debug registers, and on success,
@@ -870,10 +873,6 @@ i386_use_watchpoints (struct target_ops *t)
   t->to_remove_watchpoint = i386_remove_watchpoint;
   t->to_insert_hw_breakpoint = i386_insert_hw_breakpoint;
   t->to_remove_hw_breakpoint = i386_remove_hw_breakpoint;
-
-  if (i386_inferior_data == NULL)
-    i386_inferior_data
-      = register_inferior_data_with_cleanup (NULL, i386_inferior_data_cleanup);
 }
 
 void
This page took 0.029235 seconds and 4 git commands to generate.