From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14947 invoked by alias); 11 Dec 2010 05:15:30 -0000 Received: (qmail 14878 invoked by uid 22791); 11 Dec 2010 05:15:27 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_RW,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 11 Dec 2010 05:15:16 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oBB5FCh4014635 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sat, 11 Dec 2010 00:15:14 -0500 Received: from host0.dyn.jankratochvil.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id oBB5F7IZ009895 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Sat, 11 Dec 2010 00:15:11 -0500 Received: from host0.dyn.jankratochvil.net (host0.dyn.jankratochvil.net [127.0.0.1]) by host0.dyn.jankratochvil.net (8.14.4/8.14.4) with ESMTP id oBB5F5KL013742; Sat, 11 Dec 2010 06:15:05 +0100 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.14.4/8.14.4/Submit) id oBB5F3LF013740; Sat, 11 Dec 2010 06:15:03 +0100 Date: Sat, 11 Dec 2010 05:15:00 -0000 From: Jan Kratochvil To: Mark Kettenis Cc: gdb-patches@sourceware.org Subject: Re: [patch 1/4] hw watchpoints code cleanups Message-ID: <20101211051502.GA10298@host0.dyn.jankratochvil.net> References: <20101206111206.GB27176@host0.dyn.jankratochvil.net> <201012061250.oB6Coi38017384@glazunov.sibelius.xs4all.nl> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <201012061250.oB6Coi38017384@glazunov.sibelius.xs4all.nl> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-12/txt/msg00154.txt.bz2 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 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;