This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch 1/4] hw watchpoints code cleanups
On Mon, 06 Dec 2010 13:50:44 +0100, Mark Kettenis wrote:
> > + iterate_over_lwps (minus_one_ptid, amd64_linux_dr_set_control_callback,
> > + (void *) control);
>
> It really is bad style to assume you can cast an integer to (void *),
> even if you know the pointer has the same width as the integer.
I remember now some arches may have for example bit 0 of addresses cleared
etc.? OK, used `&control'.
> Please keep the i386_ prefix in all these functions.
done.
Thanks,
Jan
gdb/
2010-12-06 Jan Kratochvil <jan.kratochvil@redhat.com>
Code cleanup.
* amd64-linux-nat.c (amd64_linux_dr_get, amd64_linux_dr_set): Use
parameter TID.
(amd64_linux_dr_set_control_callback): New, split out from
amd64_linux_dr_set_control.
(amd64_linux_dr_set_control): Remove variables lp and ptid. Replace
ALL_LWPS by iterate_over_lwps.
(struct amd64_linux_dr_set_addr_data): New.
(amd64_linux_dr_set_addr_callback): New, split out from
amd64_linux_dr_set_addr.
(amd64_linux_dr_set_addr): Remove variables lp and ptid. New variable
data. Replace ALL_LWPS by iterate_over_lwps.
(amd64_linux_dr_get_status): New variable tid, use it.
(amd64_linux_dr_unset_status_callback): New, split out from
amd64_linux_dr_unset_status.
(amd64_linux_dr_unset_status): Remove variables lp and ptid. Replace
ALL_LWPS by iterate_over_lwps.
(amd64_linux_new_thread): New variable tid, use it.
* i386-linux-nat.c (i386_linux_dr_get, i386_linux_dr_set): Use
parameter TID.
(i386_linux_dr_set_control_callback): New, split out from
i386_linux_dr_set_control.
(i386_linux_dr_set_control): Remove variables lp and ptid. Replace
ALL_LWPS by iterate_over_lwps.
(struct i386_linux_dr_set_addr_data): New.
(i386_linux_dr_set_addr_callback): New, split out from
i386_linux_dr_set_addr.
(i386_linux_dr_set_addr): Remove variables lp and ptid. New variable
data. Replace ALL_LWPS by iterate_over_lwps.
(i386_linux_dr_get_status): New variable tid, use it.
(i386_linux_dr_unset_status_callback): New, split out from
i386_linux_dr_unset_status.
(i386_linux_dr_unset_status): Remove variables lp and ptid. Replace
ALL_LWPS by iterate_over_lwps.
(i386_linux_new_thread): New variable tid, use it.
* i386-nat.c (struct i386_dr_mirror): New.
(I386_DR_VACANT): Replace by ...
(i386_dr_vacant): ... this one. Update all the callers.
(I386_DR_LOCAL_ENABLE): Replace by ...
(i386_dr_local_enable): ... this one. Update all the callers.
(I386_DR_GLOBAL_ENABLE): Remove.
(I386_DR_DISABLE): Replace by ...
(i386_dr_disable): ... this one. Update all the callers.
(I386_DR_SET_RW_LEN): Replace by ...
(i386_dr_set_rw_len): ... this one. Update all the callers.
(I386_DR_GET_RW_LEN): Replace by ...
(i386_dr_get_rw_len): ... this one. Update all the callers.
(I386_DR_WATCH_HIT): Replace by ...
(i386_dr_watch_hit): ... this one. Update all the callers.
(dr_mirror, dr_status_mirror, dr_control_mirror, dr_ref_count):
Remove, use struct i386_dr_mirror instead in the callers.
(i386_dr_mirror_get): New function.
(i386_cleanup_dregs, i386_show_dr, i386_insert_aligned_watchpoint)
(i386_remove_aligned_watchpoint, i386_stopped_data_address): New
variable dr_mirror, use it.
* ppc-linux-nat.c (booke_insert_point_callback): New, split out from
ppc_linux_insert_hw_breakpoint.
(ppc_linux_insert_hw_breakpoint): Remove variables ptid and lp.
Replace ALL_LWPS by iterate_over_lwps.
(booke_remove_point_callback): New, split out from
ppc_linux_remove_hw_breakpoint.
(ppc_linux_remove_hw_breakpoint): Remove variables ptid and lp.
Replace ALL_LWPS by iterate_over_lwps.
(set_saved_dabr_value_callback): New, split out from
ppc_linux_insert_watchpoint.
(ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Remove
variables lp and ptid. Replace ALL_LWPS by iterate_over_lwps.
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -268,15 +268,10 @@ amd64_linux_store_inferior_registers (struct target_ops *ops,
static unsigned long amd64_linux_dr[DR_CONTROL + 1];
static unsigned long
-amd64_linux_dr_get (ptid_t ptid, int regnum)
+amd64_linux_dr_get (int tid, int regnum)
{
- int tid;
unsigned long value;
- tid = TIDGET (ptid);
- if (tid == 0)
- tid = PIDGET (ptid);
-
/* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
ptrace call fails breaks debugging remote targets. The correct
way to fix this is to add the hardware breakpoint and watchpoint
@@ -298,14 +293,8 @@ amd64_linux_dr_get (ptid_t ptid, int regnum)
/* Set debug register REGNUM to VALUE in only the one LWP of PTID. */
static void
-amd64_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
+amd64_linux_dr_set (int tid, int regnum, unsigned long value)
{
- int tid;
-
- tid = TIDGET (ptid);
- if (tid == 0)
- tid = PIDGET (ptid);
-
errno = 0;
ptrace (PTRACE_POKEUSER, tid,
offsetof (struct user, u_debugreg[regnum]), value);
@@ -313,35 +302,69 @@ amd64_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
perror_with_name (_("Couldn't write debug register"));
}
-/* Set DR_CONTROL to ADDR in all LWPs of LWP_LIST. */
+/* Helper for amd64_linux_dr_set_control. */
+
+static int
+amd64_linux_dr_set_control_callback (struct lwp_info *lp, void *control_voidp)
+{
+ unsigned long control = *(unsigned long *) control_voidp;
+
+ amd64_linux_dr_set (GET_LWP (lp->ptid), DR_CONTROL, control);
+
+ /* Continue the traversal. */
+ return 0;
+}
+
+/* Set DR_CONTROL to ADDR in all LWPs of CURRENT_INFERIOR. */
static void
amd64_linux_dr_set_control (unsigned long control)
{
- struct lwp_info *lp;
- ptid_t ptid;
-
amd64_linux_dr[DR_CONTROL] = control;
- ALL_LWPS (lp, ptid)
- amd64_linux_dr_set (ptid, DR_CONTROL, control);
+
+ iterate_over_lwps (minus_one_ptid, amd64_linux_dr_set_control_callback,
+ &control);
+}
+
+/* Helper for amd64_linux_dr_set_addr. */
+
+struct amd64_linux_dr_set_addr_data
+ {
+ int regnum;
+ CORE_ADDR addr;
+ };
+
+static int
+amd64_linux_dr_set_addr_callback (struct lwp_info *lp, void *datap_voidp)
+{
+ const struct amd64_linux_dr_set_addr_data *datap = datap_voidp;
+
+ amd64_linux_dr_set (GET_LWP (lp->ptid), DR_FIRSTADDR + datap->regnum,
+ datap->addr);
+
+ /* Continue the traversal. */
+ return 0;
}
-/* Set address REGNUM (zero based) to ADDR in all LWPs of LWP_LIST. */
+/* Set address REGNUM (zero based) to ADDR in all LWPs of CURRENT_INFERIOR.
+ */
static void
amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
{
- struct lwp_info *lp;
- ptid_t ptid;
+ struct amd64_linux_dr_set_addr_data data;
gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
amd64_linux_dr[DR_FIRSTADDR + regnum] = addr;
- ALL_LWPS (lp, ptid)
- amd64_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
+
+ data.regnum = regnum;
+ data.addr = addr;
+ iterate_over_lwps (minus_one_ptid, amd64_linux_dr_set_addr_callback, &data);
}
-/* Set address REGNUM (zero based) to zero in all LWPs of LWP_LIST. */
+/* Set address REGNUM (zero based) to zero in all LWPs of CURRENT_INFERIOR.
+ */
static void
amd64_linux_dr_reset_addr (int regnum)
@@ -354,37 +377,54 @@ amd64_linux_dr_reset_addr (int regnum)
static unsigned long
amd64_linux_dr_get_status (void)
{
- return amd64_linux_dr_get (inferior_ptid, DR_STATUS);
+ int tid;
+
+ tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid);
+
+ return amd64_linux_dr_get (tid, DR_STATUS);
}
-/* Unset MASK bits in DR_STATUS in all LWPs of LWP_LIST. */
+/* Helper for amd64_linux_dr_unset_status. */
-static void
-amd64_linux_dr_unset_status (unsigned long mask)
+static int
+amd64_linux_dr_unset_status_callback (struct lwp_info *lp, void *mask_voidp)
{
- struct lwp_info *lp;
- ptid_t ptid;
-
- ALL_LWPS (lp, ptid)
- {
- unsigned long value;
+ unsigned long mask = *(unsigned long *) mask_voidp;
+ unsigned long value;
+ int tid = GET_LWP (lp->ptid);
- value = amd64_linux_dr_get (ptid, DR_STATUS);
- value &= ~mask;
- amd64_linux_dr_set (ptid, DR_STATUS, value);
- }
+ value = amd64_linux_dr_get (tid, DR_STATUS);
+ value &= ~mask;
+ amd64_linux_dr_set (tid, DR_STATUS, value);
+
+ /* Continue the traversal. */
+ return 0;
}
+/* Unset MASK bits in DR_STATUS in all LWPs of CURRENT_INFERIOR. */
+
+static void
+amd64_linux_dr_unset_status (unsigned long mask)
+{
+ iterate_over_lwps (minus_one_ptid, amd64_linux_dr_unset_status_callback,
+ &mask);
+}
static void
amd64_linux_new_thread (ptid_t ptid)
{
- int i;
+ int i, tid;
+
+ tid = TIDGET (ptid);
+ if (tid == 0)
+ tid = PIDGET (ptid);
for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
- amd64_linux_dr_set (ptid, i, amd64_linux_dr[i]);
+ amd64_linux_dr_set (tid, i, amd64_linux_dr[i]);
- amd64_linux_dr_set (ptid, DR_CONTROL, amd64_linux_dr[DR_CONTROL]);
+ amd64_linux_dr_set (tid, DR_CONTROL, amd64_linux_dr[DR_CONTROL]);
}
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -640,15 +640,10 @@ static unsigned long i386_linux_dr[DR_CONTROL + 1];
/* Get debug register REGNUM value from only the one LWP of PTID. */
static unsigned long
-i386_linux_dr_get (ptid_t ptid, int regnum)
+i386_linux_dr_get (int tid, int regnum)
{
- int tid;
unsigned long value;
- tid = TIDGET (ptid);
- if (tid == 0)
- tid = PIDGET (ptid);
-
/* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
ptrace call fails breaks debugging remote targets. The correct
way to fix this is to add the hardware breakpoint and watchpoint
@@ -670,14 +665,8 @@ i386_linux_dr_get (ptid_t ptid, int regnum)
/* Set debug register REGNUM to VALUE in only the one LWP of PTID. */
static void
-i386_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
+i386_linux_dr_set (int tid, int regnum, unsigned long value)
{
- int tid;
-
- tid = TIDGET (ptid);
- if (tid == 0)
- tid = PIDGET (ptid);
-
errno = 0;
ptrace (PTRACE_POKEUSER, tid,
offsetof (struct user, u_debugreg[regnum]), value);
@@ -685,35 +674,69 @@ i386_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
perror_with_name (_("Couldn't write debug register"));
}
-/* Set DR_CONTROL to ADDR in all LWPs of LWP_LIST. */
+/* Helper for i386_linux_dr_set_control. */
+
+static int
+i386_linux_dr_set_control_callback (struct lwp_info *lp, void *control_voidp)
+{
+ unsigned long control = *(unsigned long *) control_voidp;
+
+ i386_linux_dr_set (GET_LWP (lp->ptid), DR_CONTROL, control);
+
+ /* Continue the traversal. */
+ return 0;
+}
+
+/* Set DR_CONTROL to ADDR in all LWPs of CURRENT_INFERIOR. */
static void
i386_linux_dr_set_control (unsigned long control)
{
- struct lwp_info *lp;
- ptid_t ptid;
-
i386_linux_dr[DR_CONTROL] = control;
- ALL_LWPS (lp, ptid)
- i386_linux_dr_set (ptid, DR_CONTROL, control);
+
+ iterate_over_lwps (minus_one_ptid, i386_linux_dr_set_control_callback,
+ &control);
}
-/* Set address REGNUM (zero based) to ADDR in all LWPs of LWP_LIST. */
+/* Helper for i386_linux_dr_set_addr. */
+
+struct i386_linux_dr_set_addr_data
+ {
+ int regnum;
+ CORE_ADDR addr;
+ };
+
+static int
+i386_linux_dr_set_addr_callback (struct lwp_info *lp, void *datap_voidp)
+{
+ const struct i386_linux_dr_set_addr_data *datap = datap_voidp;
+
+ i386_linux_dr_set (GET_LWP (lp->ptid), DR_FIRSTADDR + datap->regnum,
+ datap->addr);
+
+ /* Continue the traversal. */
+ return 0;
+}
+
+/* Set address REGNUM (zero based) to ADDR in all LWPs of CURRENT_INFERIOR.
+ */
static void
i386_linux_dr_set_addr (int regnum, CORE_ADDR addr)
{
- struct lwp_info *lp;
- ptid_t ptid;
+ struct i386_linux_dr_set_addr_data data;
gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
i386_linux_dr[DR_FIRSTADDR + regnum] = addr;
- ALL_LWPS (lp, ptid)
- i386_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
+
+ data.regnum = regnum;
+ data.addr = addr;
+ iterate_over_lwps (minus_one_ptid, i386_linux_dr_set_addr_callback, &data);
}
-/* Set address REGNUM (zero based) to zero in all LWPs of LWP_LIST. */
+/* Set address REGNUM (zero based) to zero in all LWPs of CURRENT_INFERIOR.
+ */
static void
i386_linux_dr_reset_addr (int regnum)
@@ -726,36 +749,54 @@ i386_linux_dr_reset_addr (int regnum)
static unsigned long
i386_linux_dr_get_status (void)
{
- return i386_linux_dr_get (inferior_ptid, DR_STATUS);
+ int tid;
+
+ tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid);
+
+ return i386_linux_dr_get (tid, DR_STATUS);
}
-/* Unset MASK bits in DR_STATUS in all LWPs of LWP_LIST. */
+/* Helper for i386_linux_dr_unset_status. */
+
+static int
+i386_linux_dr_unset_status_callback (struct lwp_info *lp, void *mask_voidp)
+{
+ unsigned long mask = *(unsigned long *) mask_voidp;
+ unsigned long value;
+ int tid = GET_LWP (lp->ptid);
+
+ value = i386_linux_dr_get (tid, DR_STATUS);
+ value &= ~mask;
+ i386_linux_dr_set (tid, DR_STATUS, value);
+
+ /* Continue the traversal. */
+ return 0;
+}
+
+/* Unset MASK bits in DR_STATUS in all LWPs of CURRENT_INFERIOR. */
static void
i386_linux_dr_unset_status (unsigned long mask)
{
- struct lwp_info *lp;
- ptid_t ptid;
-
- ALL_LWPS (lp, ptid)
- {
- unsigned long value;
-
- value = i386_linux_dr_get (ptid, DR_STATUS);
- value &= ~mask;
- i386_linux_dr_set (ptid, DR_STATUS, value);
- }
+ iterate_over_lwps (minus_one_ptid, i386_linux_dr_unset_status_callback,
+ &mask);
}
static void
i386_linux_new_thread (ptid_t ptid)
{
- int i;
+ int i, tid;
+
+ tid = TIDGET (ptid);
+ if (tid == 0)
+ tid = PIDGET (ptid);
for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
- i386_linux_dr_set (ptid, i, i386_linux_dr[i]);
+ i386_linux_dr_set (tid, i, i386_linux_dr[i]);
- i386_linux_dr_set (ptid, DR_CONTROL, i386_linux_dr[DR_CONTROL]);
+ i386_linux_dr_set (tid, DR_CONTROL, i386_linux_dr[DR_CONTROL]);
}
--- a/gdb/i386-nat.c
+++ b/gdb/i386-nat.c
@@ -104,6 +104,19 @@ struct i386_dr_low_type i386_dr_low;
FIXME: My Intel manual says we should use 0xF800, not 0xFC00. */
#define DR_CONTROL_RESERVED (0xFC00)
+/* Copy of hardware debug registers for performance reasons. */
+
+struct i386_dr_mirror
+ {
+ /* Mirror the inferior's DRi registers. We keep the status and
+ control registers separated because they don't hold addresses. */
+ CORE_ADDR addr[DR_NADDR];
+ unsigned long status, control;
+
+ /* Reference counts for each debug register. */
+ int ref_count[DR_NADDR];
+ };
+
/* Auxiliary helper macros. */
/* A value that masks all fields in DR7 that are reserved by Intel. */
@@ -111,49 +124,60 @@ struct i386_dr_low_type i386_dr_low;
/* The I'th debug register is vacant if its Local and Global Enable
bits are reset in the Debug Control register. */
-#define I386_DR_VACANT(i) \
- ((dr_control_mirror & (3 << (DR_ENABLE_SIZE * (i)))) == 0)
+
+static inline int
+i386_dr_vacant (struct i386_dr_mirror *dr_mirror, int i)
+{
+ return (dr_mirror->control & (3 << (DR_ENABLE_SIZE * i))) == 0;
+}
/* Locally enable the break/watchpoint in the I'th debug register. */
-#define I386_DR_LOCAL_ENABLE(i) \
- dr_control_mirror |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i)))
-/* Globally enable the break/watchpoint in the I'th debug register. */
-#define I386_DR_GLOBAL_ENABLE(i) \
- dr_control_mirror |= (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i)))
+static inline void
+i386_dr_local_enable (struct i386_dr_mirror *dr_mirror, int i)
+{
+ dr_mirror->control |= 1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * i);
+}
/* Disable the break/watchpoint in the I'th debug register. */
-#define I386_DR_DISABLE(i) \
- dr_control_mirror &= ~(3 << (DR_ENABLE_SIZE * (i)))
+
+static inline void
+i386_dr_disable (struct i386_dr_mirror *dr_mirror, int i)
+{
+ dr_mirror->control &= ~(3 << (DR_ENABLE_SIZE * i));
+}
/* Set in DR7 the RW and LEN fields for the I'th debug register. */
-#define I386_DR_SET_RW_LEN(i,rwlen) \
- do { \
- dr_control_mirror &= ~(0x0f << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
- dr_control_mirror |= ((rwlen) << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
- } while (0)
+
+static inline void
+i386_dr_set_rw_len (struct i386_dr_mirror *dr_mirror, int i, unsigned rwlen)
+{
+ dr_mirror->control &= ~(0x0f << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * i));
+ dr_mirror->control |= rwlen << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * i);
+}
/* Get from DR7 the RW and LEN fields for the I'th debug register. */
-#define I386_DR_GET_RW_LEN(i) \
- ((dr_control_mirror >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (i))) & 0x0f)
+
+static inline unsigned
+i386_dr_get_rw_len (struct i386_dr_mirror *dr_mirror, int i)
+{
+ return ((dr_mirror->control >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * i))
+ & 0x0f);
+}
/* Mask that this I'th watchpoint has triggered. */
#define I386_DR_WATCH_MASK(i) (1 << (i))
/* Did the watchpoint whose address is in the I'th register break? */
-#define I386_DR_WATCH_HIT(i) (dr_status_mirror & I386_DR_WATCH_MASK (i))
+static inline int
+i386_dr_watch_hit (struct i386_dr_mirror *dr_mirror, int i)
+{
+ return (dr_mirror->status & I386_DR_WATCH_MASK (i)) != 0;
+}
/* A macro to loop over all debug registers. */
#define ALL_DEBUG_REGISTERS(i) for (i = 0; i < DR_NADDR; i++)
-/* Mirror the inferior's DRi registers. We keep the status and
- control registers separated because they don't hold addresses. */
-static CORE_ADDR dr_mirror[DR_NADDR];
-static unsigned long dr_status_mirror, dr_control_mirror;
-
-/* Reference counts for each debug register. */
-static int dr_ref_count[DR_NADDR];
-
/* Whether or not to print the mirrored debug registers. */
static int maint_show_dr;
@@ -198,18 +222,28 @@ static int i386_handle_nonaligned_watchpoint (i386_wp_op_t what,
/* Clear the reference counts and forget everything we knew about the
debug registers. */
+static struct i386_dr_mirror *
+i386_dr_mirror_get (void)
+{
+ /* Intermediate patch stub. */
+ static struct i386_dr_mirror dr_mirror;
+
+ return &dr_mirror;
+}
+
void
i386_cleanup_dregs (void)
{
+ struct i386_dr_mirror *dr_mirror = i386_dr_mirror_get ();
int i;
ALL_DEBUG_REGISTERS(i)
{
- dr_mirror[i] = 0;
- dr_ref_count[i] = 0;
+ dr_mirror->addr[i] = 0;
+ dr_mirror->ref_count[i] = 0;
}
- dr_control_mirror = 0;
- dr_status_mirror = 0;
+ dr_mirror->control = 0;
+ dr_mirror->status = 0;
}
/* Print the values of the mirrored debug registers. This is called
@@ -220,6 +254,7 @@ static void
i386_show_dr (const char *func, CORE_ADDR addr,
int len, enum target_hw_bp_type type)
{
+ struct i386_dr_mirror *dr_mirror = i386_dr_mirror_get ();
int addr_size = gdbarch_addr_bit (target_gdbarch) / 8;
int i;
@@ -239,13 +274,16 @@ i386_show_dr (const char *func, CORE_ADDR addr,
: "??unknown??"))));
puts_unfiltered (":\n");
printf_unfiltered ("\tCONTROL (DR7): %s STATUS (DR6): %s\n",
- phex (dr_control_mirror, 8), phex (dr_status_mirror, 8));
+ phex (dr_mirror->control, 8),
+ phex (dr_mirror->status, 8));
ALL_DEBUG_REGISTERS(i)
{
printf_unfiltered ("\
\tDR%d: addr=0x%s, ref.count=%d DR%d: addr=0x%s, ref.count=%d\n",
- i, phex (dr_mirror[i], addr_size), dr_ref_count[i],
- i+1, phex (dr_mirror[i+1], addr_size), dr_ref_count[i+1]);
+ i, phex (dr_mirror->addr[i], addr_size),
+ dr_mirror->ref_count[i], i + 1,
+ phex (dr_mirror->addr[i + 1], addr_size),
+ dr_mirror->ref_count[i + 1]);
i++;
}
}
@@ -311,6 +349,7 @@ Invalid hardware breakpoint length %d in i386_length_and_rw_bits.\n"), len);
static int
i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
{
+ struct i386_dr_mirror *dr_mirror = i386_dr_mirror_get ();
int i;
if (!i386_dr_low.set_addr || !i386_dr_low.set_control)
@@ -321,11 +360,10 @@ i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
reuse it for this watchpoint as well (and save a register). */
ALL_DEBUG_REGISTERS(i)
{
- if (!I386_DR_VACANT (i)
- && dr_mirror[i] == addr
- && I386_DR_GET_RW_LEN (i) == len_rw_bits)
+ if (!i386_dr_vacant (dr_mirror, i) && dr_mirror->addr[i] == addr
+ && i386_dr_get_rw_len (dr_mirror, i) == len_rw_bits)
{
- dr_ref_count[i]++;
+ dr_mirror->ref_count[i]++;
return 0;
}
}
@@ -333,7 +371,7 @@ i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
/* Next, look for a vacant debug register. */
ALL_DEBUG_REGISTERS(i)
{
- if (I386_DR_VACANT (i))
+ if (i386_dr_vacant (dr_mirror, i))
break;
}
@@ -344,9 +382,9 @@ i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
/* Now set up the register I to watch our region. */
/* Record the info in our local mirrored array. */
- dr_mirror[i] = addr;
- dr_ref_count[i] = 1;
- I386_DR_SET_RW_LEN (i, len_rw_bits);
+ dr_mirror->addr[i] = addr;
+ dr_mirror->ref_count[i] = 1;
+ i386_dr_set_rw_len (dr_mirror, i, len_rw_bits);
/* Note: we only enable the watchpoint locally, i.e. in the current
task. Currently, no i386 target allows or supports global
watchpoints; however, if any target would want that in the
@@ -354,13 +392,13 @@ i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
to enable watchpoints globally or locally, and the code below
should use global or local enable and slow-down flags as
appropriate. */
- I386_DR_LOCAL_ENABLE (i);
- dr_control_mirror |= DR_LOCAL_SLOWDOWN;
- dr_control_mirror &= I386_DR_CONTROL_MASK;
+ i386_dr_local_enable (dr_mirror, i);
+ dr_mirror->control |= DR_LOCAL_SLOWDOWN;
+ dr_mirror->control &= I386_DR_CONTROL_MASK;
/* Finally, actually pass the info to the inferior. */
i386_dr_low.set_addr (i, addr);
- i386_dr_low.set_control (dr_control_mirror);
+ i386_dr_low.set_control (dr_mirror->control);
/* Only a sanity check for leftover bits (set possibly only by inferior). */
if (i386_dr_low.unset_status)
@@ -378,21 +416,21 @@ i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
static int
i386_remove_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
{
+ struct i386_dr_mirror *dr_mirror = i386_dr_mirror_get ();
int i, retval = -1;
ALL_DEBUG_REGISTERS(i)
{
- if (!I386_DR_VACANT (i)
- && dr_mirror[i] == addr
- && I386_DR_GET_RW_LEN (i) == len_rw_bits)
+ if (!i386_dr_vacant (dr_mirror, i) && dr_mirror->addr[i] == addr
+ && i386_dr_get_rw_len (dr_mirror, i) == len_rw_bits)
{
- if (--dr_ref_count[i] == 0) /* no longer in use? */
+ if (--dr_mirror->ref_count[i] == 0) /* no longer in use? */
{
/* Reset our mirror. */
- dr_mirror[i] = 0;
- I386_DR_DISABLE (i);
+ dr_mirror->addr[i] = 0;
+ i386_dr_disable (dr_mirror, i);
/* Reset it in the inferior. */
- i386_dr_low.set_control (dr_control_mirror);
+ i386_dr_low.set_control (dr_mirror->control);
if (i386_dr_low.reset_addr)
i386_dr_low.reset_addr (i);
}
@@ -554,26 +592,27 @@ i386_region_ok_for_watchpoint (CORE_ADDR addr, int len)
static int
i386_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
{
+ struct i386_dr_mirror *dr_mirror = i386_dr_mirror_get ();
CORE_ADDR addr = 0;
int i;
int rc = 0;
- dr_status_mirror = i386_dr_low.get_status ();
+ dr_mirror->status = i386_dr_low.get_status ();
ALL_DEBUG_REGISTERS(i)
{
- if (I386_DR_WATCH_HIT (i)
+ if (i386_dr_watch_hit (dr_mirror, i)
/* This second condition makes sure DRi is set up for a data
watchpoint, not a hardware breakpoint. The reason is
that GDB doesn't call the target_stopped_data_address
method except for data watchpoints. In other words, I'm
being paranoiac. */
- && I386_DR_GET_RW_LEN (i) != 0
+ && i386_dr_get_rw_len (dr_mirror, i) != 0
/* This third condition makes sure DRi is not vacant, this
avoids false positives in windows-nat.c. */
- && !I386_DR_VACANT (i))
+ && !i386_dr_vacant (dr_mirror, i))
{
- addr = dr_mirror[i];
+ addr = dr_mirror->addr[i];
rc = 1;
if (maint_show_dr)
i386_show_dr ("watchpoint_hit", addr, -1, hw_write);
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -1621,11 +1621,20 @@ booke_remove_point (struct ppc_hw_breakpoint *b, int tid)
}
static int
+booke_insert_point_callback (struct lwp_info *lp, void *pp_voidp)
+{
+ struct ppc_hw_breakpoint *pp = pp_voidp;
+
+ booke_insert_point (pp, GET_LWP (lp->ptid));
+
+ /* Continue the traversal. */
+ return 0;
+}
+
+static int
ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
{
- ptid_t ptid;
- struct lwp_info *lp;
struct ppc_hw_breakpoint p;
if (!have_ptrace_booke_interface ())
@@ -1639,9 +1648,19 @@ ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
p.addr2 = 0;
p.condition_value = 0;
- ALL_LWPS (lp, ptid)
- booke_insert_point (&p, TIDGET (ptid));
+ iterate_over_lwps (minus_one_ptid, booke_insert_point_callback, &p);
+
+ return 0;
+}
+
+static int
+booke_remove_point_callback (struct lwp_info *lp, void *pp_voidp)
+{
+ struct ppc_hw_breakpoint *pp = pp_voidp;
+
+ booke_remove_point (pp, GET_LWP (lp->ptid));
+ /* Continue the traversal. */
return 0;
}
@@ -1649,8 +1668,6 @@ static int
ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
{
- ptid_t ptid;
- struct lwp_info *lp;
struct ppc_hw_breakpoint p;
if (!have_ptrace_booke_interface ())
@@ -1664,8 +1681,7 @@ ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
p.addr2 = 0;
p.condition_value = 0;
- ALL_LWPS (lp, ptid)
- booke_remove_point (&p, TIDGET (ptid));
+ iterate_over_lwps (minus_one_ptid, booke_remove_point_callback, &p);
return 0;
}
@@ -1879,11 +1895,22 @@ ppc_linux_can_accel_watchpoint_condition (CORE_ADDR addr, int len, int rw,
}
static int
+set_saved_dabr_value_callback (struct lwp_info *lp, void *retp_voidp)
+{
+ int *retp = retp_voidp;
+
+ if (ptrace (PTRACE_SET_DEBUGREG, GET_LWP (lp->ptid), 0, saved_dabr_value)
+ < 0)
+ *retp = -1;
+
+ /* Continue the traversal. */
+ return 0;
+}
+
+static int
ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
struct expression *cond)
{
- struct lwp_info *lp;
- ptid_t ptid;
int ret = -1;
if (have_ptrace_booke_interface ())
@@ -1907,8 +1934,7 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
p.addr = (uint64_t) addr;
p.addr2 = 0;
- ALL_LWPS (lp, ptid)
- booke_insert_point (&p, TIDGET (ptid));
+ iterate_over_lwps (minus_one_ptid, booke_insert_point_callback, &p);
ret = 0;
}
@@ -1951,12 +1977,8 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
saved_dabr_value = dabr_value;
- ALL_LWPS (lp, ptid)
- if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0,
- saved_dabr_value) < 0)
- return -1;
-
ret = 0;
+ iterate_over_lwps (minus_one_ptid, set_saved_dabr_value_callback, &ret);
}
return ret;
@@ -1966,8 +1988,6 @@ static int
ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
struct expression *cond)
{
- struct lwp_info *lp;
- ptid_t ptid;
int ret = -1;
if (have_ptrace_booke_interface ())
@@ -1991,20 +2011,16 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
p.addr = (uint64_t) addr;
p.addr2 = 0;
- ALL_LWPS (lp, ptid)
- booke_remove_point (&p, TIDGET (ptid));
+ iterate_over_lwps (minus_one_ptid, booke_remove_point_callback, &p);
ret = 0;
}
else
{
saved_dabr_value = 0;
- ALL_LWPS (lp, ptid)
- if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0,
- saved_dabr_value) < 0)
- return -1;
ret = 0;
+ iterate_over_lwps (minus_one_ptid, set_saved_dabr_value_callback, &ret);
}
return ret;