+ struct s390_process_info *proc;
+
+ for (proc = s390_process_list; proc; proc = proc->next)
+ if (proc->pid == pid)
+ return proc;
+
+ return NULL;
+}
+
+/* Add process data for process PID. Returns newly allocated info
+ object. */
+
+static struct s390_process_info *
+s390_add_process (pid_t pid)
+{
+ struct s390_process_info *proc = new struct s390_process_info;
+
+ proc->pid = pid;
+ proc->next = s390_process_list;
+ s390_process_list = proc;
+
+ return proc;
+}
+
+/* Get data specific info for process PID, creating it if necessary.
+ Never returns NULL. */
+
+static struct s390_process_info *
+s390_process_info_get (pid_t pid)
+{
+ struct s390_process_info *proc;
+
+ proc = s390_find_process_pid (pid);
+ if (proc == NULL)
+ proc = s390_add_process (pid);
+
+ return proc;
+}
+
+/* Get hardware debug state for process PID. */
+
+static struct s390_debug_reg_state *
+s390_get_debug_reg_state (pid_t pid)
+{
+ return &s390_process_info_get (pid)->state;
+}
+
+/* Called whenever GDB is no longer debugging process PID. It deletes
+ data structures that keep track of hardware debug state. */
+
+void
+s390_linux_nat_target::low_forget_process (pid_t pid)
+{
+ struct s390_process_info *proc, **proc_link;
+
+ proc = s390_process_list;
+ proc_link = &s390_process_list;
+
+ while (proc != NULL)
+ {
+ if (proc->pid == pid)
+ {
+ *proc_link = proc->next;
+ delete proc;
+ return;
+ }
+
+ proc_link = &proc->next;
+ proc = *proc_link;
+ }
+}
+
+/* linux_nat_new_fork hook. */
+
+void
+s390_linux_nat_target::low_new_fork (struct lwp_info *parent, pid_t child_pid)
+{
+ pid_t parent_pid;
+ struct s390_debug_reg_state *parent_state;
+ struct s390_debug_reg_state *child_state;
+
+ /* NULL means no watchpoint has ever been set in the parent. In
+ that case, there's nothing to do. */
+ if (lwp_arch_private_info (parent) == NULL)
+ return;
+
+ /* GDB core assumes the child inherits the watchpoints/hw breakpoints of
+ the parent. So copy the debug state from parent to child. */
+
+ parent_pid = parent->ptid.pid ();
+ parent_state = s390_get_debug_reg_state (parent_pid);
+ child_state = s390_get_debug_reg_state (child_pid);
+
+ child_state->watch_areas = parent_state->watch_areas;
+ child_state->break_areas = parent_state->break_areas;
+}
+
+/* Dump PER state. */
+
+static void
+s390_show_debug_regs (int tid, const char *where)
+{
+ per_struct per_info;
+ ptrace_area parea;
+
+ parea.len = sizeof (per_info);
+ parea.process_addr = (addr_t) &per_info;
+ parea.kernel_addr = offsetof (struct user_regs_struct, per_info);
+
+ if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea, 0) < 0)
+ perror_with_name (_("Couldn't retrieve debug regs"));
+
+ debug_printf ("PER (debug) state for %d -- %s\n"
+ " cr9-11: %lx %lx %lx\n"
+ " start, end: %lx %lx\n"
+ " code/ATMID: %x address: %lx PAID: %x\n",
+ tid,
+ where,
+ per_info.control_regs.words.cr[0],
+ per_info.control_regs.words.cr[1],
+ per_info.control_regs.words.cr[2],
+ per_info.starting_addr,
+ per_info.ending_addr,
+ per_info.lowcore.words.perc_atmid,
+ per_info.lowcore.words.address,
+ per_info.lowcore.words.access_id);
+}
+
+bool
+s390_linux_nat_target::stopped_by_watchpoint ()
+{
+ struct s390_debug_reg_state *state
+ = s390_get_debug_reg_state (inferior_ptid.pid ());