diff options
author | Pedro Alves <palves@redhat.com> | 2010-08-25 14:40:21 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2010-08-25 14:40:21 +0000 |
commit | 964e4306f80f7da4474eea57ce49492b73611acb (patch) | |
tree | a808e253ab7d90c5d2f355039eb559f32cd14156 /gdb/gdbserver/linux-x86-low.c | |
parent | 4563a8602899e7270a6a0d8dd5da822c6680c6ba (diff) | |
download | gdb-964e4306f80f7da4474eea57ce49492b73611acb.zip gdb-964e4306f80f7da4474eea57ce49492b73611acb.tar.gz gdb-964e4306f80f7da4474eea57ce49492b73611acb.tar.bz2 |
PR threads/10729
* linux-x86-low.c (update_debug_registers_callback): New.
(i386_dr_low_set_addr): Use it.
(i386_dr_low_get_addr): New.
(i386_dr_low_set_control): Use update_debug_registers_callback.
(i386_dr_low_get_control): New.
(i386_dr_low_get_status): Adjust.
* linux-low.c (linux_stop_lwp): New.
* linux-low.h (linux_stop_lwp): Declare.
* i386-low.c (I386_DR_GET_RW_LEN): Take the dr7 contents as
argument instead of a i386_debug_reg_state.
(I386_DR_WATCH_HIT): Take the dr6 contents as argument instead of
a i386_debug_reg_state.
(i386_insert_aligned_watchpoint): Adjust.
(i386_remove_aligned_watchpoint): Adjust.
(i386_low_stopped_data_address): Read the debug registers from the
inferior instead of from the mirrors.
* i386-low.h (struct i386_debug_reg_state): Extend comment.
(i386_dr_low_get_addr): Declare.
(i386_dr_low_get_control): Declare.
(i386_dr_low_get_status): Change prototype.
* win32-i386-low.c (dr_status_mirror, dr_control_mirror): New globals.
(i386_dr_low_get_addr): New.
(i386_dr_low_get_control): New.
(i386_dr_low_get_status): Adjust prototype. Return
dr_status_mirror.
(i386_initial_stuff): Clear dr_status_mirror and
dr_control_mirror.
(i386_get_thread_context): Adjust.
(i386_set_thread_context): Adjust.
(i386_thread_added): Adjust.
Diffstat (limited to 'gdb/gdbserver/linux-x86-low.c')
-rw-r--r-- | gdb/gdbserver/linux-x86-low.c | 77 |
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. */ |