mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-27 01:28:46 +00:00
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.
This commit is contained in:
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user