aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/linux-x86-low.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/gdbserver/linux-x86-low.c')
-rw-r--r--gdb/gdbserver/linux-x86-low.c77
1 files changed, 52 insertions, 25 deletions
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 1e0d684..841f053 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -461,30 +461,55 @@ x86_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
error ("Couldn't write debug register");
}
+static int
+update_debug_registers_callback (struct inferior_list_entry *entry,
+ void *pid_p)
+{
+ struct lwp_info *lwp = (struct lwp_info *) entry;
+ int pid = *(int *) pid_p;
+
+ /* Only update the threads of this process. */
+ if (pid_of (lwp) == pid)
+ {
+ /* The actual update is done later just before resuming the lwp,
+ we just mark that the registers need updating. */
+ lwp->arch_private->debug_registers_changed = 1;
+
+ /* If the lwp isn't stopped, force it to momentarily pause, so
+ we can update its debug registers. */
+ if (!lwp->stopped)
+ linux_stop_lwp (lwp);
+ }
+
+ return 0;
+}
+
/* Update the inferior's debug register REGNUM from STATE. */
void
i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum)
{
- struct inferior_list_entry *lp;
- CORE_ADDR addr;
- /* Only need to update the threads of this process. */
+ /* Only update the threads of this process. */
int pid = pid_of (get_thread_lwp (current_inferior));
if (! (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR))
fatal ("Invalid debug register %d", regnum);
- addr = state->dr_mirror[regnum];
+ find_inferior (&all_lwps, update_debug_registers_callback, &pid);
+}
- for (lp = all_lwps.head; lp; lp = lp->next)
- {
- struct lwp_info *lwp = (struct lwp_info *) lp;
+/* Return the inferior's debug register REGNUM. */
- /* The actual update is done later, we just mark that the register
- needs updating. */
- if (pid_of (lwp) == pid)
- lwp->arch_private->debug_registers_changed = 1;
- }
+CORE_ADDR
+i386_dr_low_get_addr (int regnum)
+{
+ struct lwp_info *lwp = get_thread_lwp (current_inferior);
+ ptid_t ptid = ptid_of (lwp);
+
+ /* DR6 and DR7 are retrieved with some other way. */
+ gdb_assert (DR_FIRSTADDR <= regnum && regnum < DR_LASTADDR);
+
+ return x86_linux_dr_get (ptid, regnum);
}
/* Update the inferior's DR7 debug control register from STATE. */
@@ -492,31 +517,33 @@ i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum)
void
i386_dr_low_set_control (const struct i386_debug_reg_state *state)
{
- struct inferior_list_entry *lp;
- /* Only need to update the threads of this process. */
+ /* Only update the threads of this process. */
int pid = pid_of (get_thread_lwp (current_inferior));
- for (lp = all_lwps.head; lp; lp = lp->next)
- {
- struct lwp_info *lwp = (struct lwp_info *) lp;
+ find_inferior (&all_lwps, update_debug_registers_callback, &pid);
+}
- /* The actual update is done later, we just mark that the register
- needs updating. */
- if (pid_of (lwp) == pid)
- lwp->arch_private->debug_registers_changed = 1;
- }
+/* Return the inferior's DR7 debug control register. */
+
+unsigned
+i386_dr_low_get_control (void)
+{
+ struct lwp_info *lwp = get_thread_lwp (current_inferior);
+ ptid_t ptid = ptid_of (lwp);
+
+ return x86_linux_dr_get (ptid, DR_CONTROL);
}
/* Get the value of the DR6 debug status register from the inferior
and record it in STATE. */
-void
-i386_dr_low_get_status (struct i386_debug_reg_state *state)
+unsigned
+i386_dr_low_get_status (void)
{
struct lwp_info *lwp = get_thread_lwp (current_inferior);
ptid_t ptid = ptid_of (lwp);
- state->dr_status_mirror = x86_linux_dr_get (ptid, DR_STATUS);
+ return x86_linux_dr_get (ptid, DR_STATUS);
}
/* Watchpoint support. */