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:
Pedro Alves
2010-08-25 14:40:21 +00:00
parent 4563a86028
commit 964e4306f8
7 changed files with 150 additions and 47 deletions

View File

@@ -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. */