aboutsummaryrefslogtreecommitdiff
path: root/gdb/ppc-linux-nat.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2007-10-01 00:22:50 +0000
committerDaniel Jacobowitz <drow@false.org>2007-10-01 00:22:50 +0000
commit9f0bdab8028f185719d163f3bfeafd1406ba5a58 (patch)
treea4c91496632a8629237eb3766c4fe11e1c5bd8e0 /gdb/ppc-linux-nat.c
parentd983da9c3dfa91e6840fee2a7479d98ee4759f13 (diff)
downloadgdb-9f0bdab8028f185719d163f3bfeafd1406ba5a58.zip
gdb-9f0bdab8028f185719d163f3bfeafd1406ba5a58.tar.gz
gdb-9f0bdab8028f185719d163f3bfeafd1406ba5a58.tar.bz2
* linux-nat.c (linux_nat_new_thread): New variable.
(linux_child_follow_fork): Set inferior_ptid to include LWP ID. Use linux_nat_switch_fork. (lwp_list): Make public. (add_lwp): Call linux_nat_new_thread. (lin_lwp_attach_lwp, linux_nat_attach): Call add_lwp after stopping the new thread. (resume_callback): Clear lp->siginfo. Remove unused variable. (linux_nat_resume): Assert that the LWP list is already initialized. Clear lp->siginfo. (save_siginfo): New. (stop_wait_callback, linux_nat_wait): Call it. (linux_nat_set_new_thread, linux_nat_get_siginfo): New. * linux-nat.h (struct lwp_info): Add siginfo. (lwp_list, linux_nat_set_new_thread, linux_nat_get_siginfo): Declare. (ALL_LWPS): Define. * amd64-linux-nat.c (amd64_linux_dr): New. (amd64_linux_dr_get): Take a PTID argument. Correct typo. (amd64_linux_dr_set): Take a PTID argument. (amd64_linux_dr_set_control, amd64_linux_dr_set_addr): Use ALL_LWPS. (amd64_linux_dr_reset_addr): Use amd64_linux_dr_set_addr. (amd64_linux_dr_get_status): Pass inferior_ptid to amd64_linux_dr_get. (amd64_linux_new_thread): New. (_initialize_amd64_linux_nat): Call linux_nat_set_new_thread. * i386-linux-nat.c (i386_linux_dr): New. (i386_linux_dr_get, i386_linux_dr_set): Take a PTID argument. (i386_linux_dr_set_control, i386_linux_dr_set_addr): Use ALL_LWPS. (i386_linux_dr_reset_addr): Use i386_linux_dr_set_addr. (i386_linux_dr_get_status): Pass inferior_ptid to i386_linux_dr_get. (i386_linux_new_thread): New. (i386_linux_resume): Remove unnecessary PID check. (_initialize_i386_linux_nat): Call linux_nat_set_new_thread. * ia64-linux-nat.c (enable_watchpoints_in_psr): Take PTID argument. (fetch_debug_register, fetch_debug_register_pair): Delete. (debug_registers): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint): Use ALL_LWPS and debug_registers. (ia64_linux_new_thread): New. (ia64_linux_stopped_data_address): Use linux_nat_get_siginfo. (_initialize_ia64_linux_nat): Call linux_nat_set_new_thread. * ppc-linux-nat.c (last_stopped_data_address): Delete. (saved_dabr_value): New. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use ALL_LWPS. (ppc_linux_new_thread): New. (ppc_linux_stopped_data_address): Use linux_nat_get_siginfo. (ppc_linux_stopped_by_watchpoint): Call ppc_linux_stopped_data_address. (_initialize_ppc_linux_nat): Call linux_nat_set_new_thread. * s390-nat.c (s390_stopped_by_watchpoint): Clear the watchpoint status after reading it. (s390_fix_watch_points): Take a PTID argument. (s390_insert_watchpoint, s390_remove_watchpoint): Use ALL_LWPS. (_initialize_s390_nat): Call linux_nat_set_new_thread.
Diffstat (limited to 'gdb/ppc-linux-nat.c')
-rw-r--r--gdb/ppc-linux-nat.c76
1 files changed, 36 insertions, 40 deletions
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index f0b2abb..ec061b0 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -142,8 +142,6 @@ struct gdb_evrregset_t
error. */
int have_ptrace_getvrregs = 1;
-static CORE_ADDR last_stopped_data_address = 0;
-
/* Non-zero if our kernel may support the PTRACE_GETEVRREGS and
PTRACE_SETEVRREGS requests, for reading and writing the SPE
registers. Zero if we've tried one of them and gotten an
@@ -805,13 +803,16 @@ ppc_linux_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
return 1;
}
+/* The cached DABR value, to install in new threads. */
+static long saved_dabr_value;
+
/* Set a watchpoint of type TYPE at address ADDR. */
static int
ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw)
{
- int tid;
+ struct lwp_info *lp;
+ ptid_t ptid;
long dabr_value;
- ptid_t ptid = inferior_ptid;
dabr_value = addr & ~7;
switch (rw)
@@ -830,61 +831,55 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw)
break;
}
- tid = TIDGET (ptid);
- if (tid == 0)
- tid = PIDGET (ptid);
-
- return ptrace (PTRACE_SET_DEBUGREG, tid, 0, dabr_value);
+ ALL_LWPS (lp, ptid)
+ if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0, saved_dabr_value) < 0)
+ return -1;
+ saved_dabr_value = dabr_value;
+ return 0;
}
static int
ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw)
{
- int tid;
- ptid_t ptid = inferior_ptid;
-
- tid = TIDGET (ptid);
- if (tid == 0)
- tid = PIDGET (ptid);
-
- return ptrace (PTRACE_SET_DEBUGREG, tid, 0, 0);
+ struct lwp_info *lp;
+ ptid_t ptid;
+ long dabr_value = 0;
+
+ saved_dabr_value = 0;
+ ALL_LWPS (lp, ptid)
+ if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0, saved_dabr_value) < 0)
+ return -1;
+ return 0;
}
-static int
-ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
+static void
+ppc_linux_new_thread (ptid_t ptid)
{
- if (last_stopped_data_address)
- {
- *addr_p = last_stopped_data_address;
- last_stopped_data_address = 0;
- return 1;
- }
- return 0;
+ ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0, saved_dabr_value);
}
static int
-ppc_linux_stopped_by_watchpoint (void)
+ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
{
- int tid;
- struct siginfo siginfo;
- ptid_t ptid = inferior_ptid;
- CORE_ADDR *addr_p;
+ struct siginfo *siginfo_p;
- tid = TIDGET(ptid);
- if (tid == 0)
- tid = PIDGET (ptid);
+ siginfo_p = linux_nat_get_siginfo (inferior_ptid);
- errno = 0;
- ptrace (PTRACE_GETSIGINFO, tid, (PTRACE_TYPE_ARG3) 0, &siginfo);
-
- if (errno != 0 || siginfo.si_signo != SIGTRAP ||
- (siginfo.si_code & 0xffff) != 0x0004)
+ if (siginfo_p->si_signo != SIGTRAP
+ || (siginfo_p->si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
return 0;
- last_stopped_data_address = (uintptr_t) siginfo.si_addr;
+ *addr_p = (CORE_ADDR) siginfo_p->si_addr;
return 1;
}
+static int
+ppc_linux_stopped_by_watchpoint (void)
+{
+ CORE_ADDR addr;
+ return ppc_linux_stopped_data_address (&current_target, &addr);
+}
+
static void
ppc_linux_store_inferior_registers (struct regcache *regcache, int regno)
{
@@ -969,4 +964,5 @@ _initialize_ppc_linux_nat (void)
/* Register the target. */
linux_nat_add_target (t);
+ linux_nat_set_new_thread (t, ppc_linux_new_thread);
}