From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4253 invoked by alias); 5 Jul 2011 20:21:38 -0000 Received: (qmail 4242 invoked by uid 22791); 5 Jul 2011 20:21:37 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00,TW_CP,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from e24smtp05.br.ibm.com (HELO e24smtp05.br.ibm.com) (32.104.18.26) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 05 Jul 2011 20:21:22 +0000 Received: from /spool/local by e24smtp05.br.ibm.com with XMail ESMTP for from ; Tue, 5 Jul 2011 17:21:15 -0300 Received: from mailhub1.br.ibm.com ([9.18.232.109]) by e24smtp05.br.ibm.com ([10.172.0.141]) with XMail ESMTP; Tue, 5 Jul 2011 17:21:13 -0300 Received: from d24av04.br.ibm.com (d24av04.br.ibm.com [9.8.31.97]) by mailhub1.br.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p65KNIY1184572 for ; Tue, 5 Jul 2011 17:23:18 -0300 Received: from d24av04.br.ibm.com (loopback [127.0.0.1]) by d24av04.br.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p65KKtge025792 for ; Tue, 5 Jul 2011 17:20:55 -0300 Received: from [9.8.13.12] ([9.8.13.12]) by d24av04.br.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p65KKtui025786 for ; Tue, 5 Jul 2011 17:20:55 -0300 Subject: [RFA] Make ppc-linux-nat insert/remove breakpoint and watchpoint functions return -1. From: Thiago Jung Bauermann To: gdb-patches ml Content-Type: text/plain; charset="UTF-8" Date: Tue, 05 Jul 2011 20:29:00 -0000 Message-ID: <1309897267.3634.6.camel@hactar> Mime-Version: 1.0 Content-Transfer-Encoding: 7bit x-cbid: 11070520-2362-0000-0000-00000419E9AE 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: 2011-07/txt/msg00171.txt.bz2 Hi, target_{insert,remove}_{hw_breakpoint,watchpoint,mask_watchpoint} are supposed to return 0, 1 and -1 for success, unsupported and error, respectively. This patch makes ppc-linux-nat.c comply. No regressions on ppc-linux and ppc64-linux. Ok? -- []'s Thiago Jung Bauermann IBM Linux Technology Center 2011-07-05 Thiago Jung Bauermann Make insert/remove breakpoint and watchpoint functions return -1. * ppc-linux-nat.c (ppc_linux_remove_watchpoint): Add prototype. (booke_insert_point): Return 0 on success and -1 on error. (booke_remove_point): Likewise. (ppc_linux_insert_hw_breakpoint): Return 0 on success, -1 on error and 1 if hardware breakpoints are not supported. Also, remove the breakpoint from all threads if it couldn't be installed in one of them. (ppc_linux_remove_hw_breakpoint): Likewise. (ppc_linux_insert_mask_watchpoint): Likewise. Also, remove the watchpoint from all threads if it couldn't be installed in one of them. (ppc_linux_remove_mask_watchpoint): Likewise. (ppc_linux_insert_watchpoint): Likewise. Also, remove the watchpoint from all threads if it couldn't be installed in one of them. (ppc_linux_remove_watchpoint): Likewise. diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index 275de78..410755f 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -336,6 +336,9 @@ PT_FPR0 + 56, PT_FPR0 + 58, PT_FPR0 + 60, PT_FPR0 + 62, PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, PT_XER, PT_MQ */ /* *INDENT_ON * */ +static int ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw, + struct expression *cond); + static int ppc_register_u_addr (struct gdbarch *gdbarch, int regno) { @@ -1566,8 +1569,10 @@ booke_find_thread_points_by_tid (int tid, int alloc_new) /* This function is a generic wrapper that is responsible for inserting a *point (i.e., calling `ptrace' in order to issue the request to the - kernel) and registering it internally in GDB. */ -static void + kernel) and registering it internally in GDB. Returns 0 for success + or -1 for failure. */ + +static int booke_insert_point (struct ppc_hw_breakpoint *b, int tid) { int i; @@ -1580,10 +1585,13 @@ booke_insert_point (struct ppc_hw_breakpoint *b, int tid) memcpy (p, b, sizeof (struct ppc_hw_breakpoint)); - errno = 0; slot = ptrace (PPC_PTRACE_SETHWDEBUG, tid, 0, p); if (slot < 0) - perror_with_name (_("Unexpected error setting breakpoint or watchpoint")); + { + do_cleanups (c); + + return -1; + } /* Everything went fine, so we have to register this *point. */ t = booke_find_thread_points_by_tid (tid, 1); @@ -1602,15 +1610,19 @@ booke_insert_point (struct ppc_hw_breakpoint *b, int tid) gdb_assert (i != max_slots_number); discard_cleanups (c); + + return 0; } /* This function is a generic wrapper that is responsible for removing a *point (i.e., calling `ptrace' in order to issue the request to the - kernel), and unregistering it internally at GDB. */ -static void + kernel), and unregistering it internally at GDB. Returns 0 for + success or -1 for failure. */ + +static int booke_remove_point (struct ppc_hw_breakpoint *b, int tid) { - int i; + int i, ret = 0; struct hw_break_tuple *hw_breaks; struct thread_points *t; @@ -1622,7 +1634,9 @@ booke_remove_point (struct ppc_hw_breakpoint *b, int tid) if (hw_breaks[i].hw_break && booke_cmp_hw_point (hw_breaks[i].hw_break, b)) break; - gdb_assert (i != max_slots_number); + /* There's no such breakpoint/watchpoint for this thread. */ + if (i == max_slots_number) + return -1; /* We have to ignore ENOENT errors because the kernel implements hardware breakpoints/watchpoints as "one-shot", that is, they are automatically @@ -1630,11 +1644,12 @@ booke_remove_point (struct ppc_hw_breakpoint *b, int tid) errno = 0; if (ptrace (PPC_PTRACE_DELHWDEBUG, tid, 0, hw_breaks[i].slot) < 0) if (errno != ENOENT) - perror_with_name (_("Unexpected error deleting " - "breakpoint or watchpoint")); + ret = -1; xfree (hw_breaks[i].hw_break); hw_breaks[i].hw_break = NULL; + + return ret; } /* Return the number of registers needed for a ranged breakpoint. */ @@ -1652,14 +1667,15 @@ ppc_linux_ranged_break_num_registers (struct target_ops *target) static int ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch, - struct bp_target_info *bp_tgt) + struct bp_target_info *bp_tgt) { + int ret; ptid_t ptid; struct lwp_info *lp; struct ppc_hw_breakpoint p; if (!have_ptrace_booke_interface ()) - return -1; + return 1; p.version = PPC_DEBUG_CURRENT_VERSION; p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE; @@ -1682,21 +1698,36 @@ ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch, } ALL_LWPS (lp, ptid) - booke_insert_point (&p, TIDGET (ptid)); + { + ret = booke_insert_point (&p, TIDGET (ptid)); + if (ret) + break; + } - return 0; + /* If an error occurred, remove the breakpoint from all threads, to + keep consistency (all threads must have the same breakpoints and + watchpoints intalled.) */ + if (ret) + ALL_LWPS (lp, ptid) + booke_remove_point (&p, TIDGET (ptid)); + + return ret; } +/* Remove the hardware breakpoint described by BP_TGT. Returns 0 for + success, 1 if hardware breakpoints are not supported or -1 for failure. */ + static int ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch, - struct bp_target_info *bp_tgt) + struct bp_target_info *bp_tgt) { + int ret = 0; ptid_t ptid; struct lwp_info *lp; struct ppc_hw_breakpoint p; if (!have_ptrace_booke_interface ()) - return -1; + return 1; p.version = PPC_DEBUG_CURRENT_VERSION; p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE; @@ -1719,9 +1750,9 @@ ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch, } ALL_LWPS (lp, ptid) - booke_remove_point (&p, TIDGET (ptid)); + ret |= booke_remove_point (&p, TIDGET (ptid)); - return 0; + return ret; } static int @@ -1741,13 +1772,14 @@ get_trigger_type (int rw) /* Insert a new masked watchpoint at ADDR using the mask MASK. RW may be hw_read for a read watchpoint, hw_write for a write watchpoint - or hw_access for an access watchpoint. Returns 0 on success and throws - an error on failure. */ + or hw_access for an access watchpoint. Returns 0 for success, 1 if + masked watchpoints are not supported or -1 for failure. */ static int ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr, CORE_ADDR mask, int rw) { + int ret; ptid_t ptid; struct lwp_info *lp; struct ppc_hw_breakpoint p; @@ -1763,20 +1795,32 @@ ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr, p.condition_value = 0; ALL_LWPS (lp, ptid) - booke_insert_point (&p, TIDGET (ptid)); + { + ret = booke_insert_point (&p, TIDGET (ptid)); + if (ret) + break; + } - return 0; + /* If an error occurred, remove the breakpoint from all threads, to + keep consistency (all threads must have the same breakpoints and + watchpoints intalled.) */ + if (ret) + ALL_LWPS (lp, ptid) + booke_remove_point (&p, TIDGET (ptid)); + + return ret; } /* Remove a masked watchpoint at ADDR with the mask MASK. RW may be hw_read for a read watchpoint, hw_write for a write watchpoint - or hw_access for an access watchpoint. Returns 0 on success and throws - an error on failure. */ + or hw_access for an access watchpoint. Returns 0 for success, 1 if + masked watchpoints are not supported or -1 for failure. */ static int ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr, CORE_ADDR mask, int rw) { + int ret = 0; ptid_t ptid; struct lwp_info *lp; struct ppc_hw_breakpoint p; @@ -1792,9 +1836,9 @@ ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr, p.condition_value = 0; ALL_LWPS (lp, ptid) - booke_remove_point (&p, TIDGET (ptid)); + ret |= booke_remove_point (&p, TIDGET (ptid)); - return 0; + return ret; } /* Check whether we have at least one free DVC register. */ @@ -2054,13 +2098,18 @@ create_watchpoint_request (struct ppc_hw_breakpoint *p, CORE_ADDR addr, p->addr = (uint64_t) addr; } +/* Insert a hardware watchpoint at address ADDR, spanning LEN bytes. + RW may be hw_read for a read watchpoint, hw_write for a write watchpoint + or hw_access for an access watchpoint. Returns 0 for success, 1 if + hardware watchpoints are not supported or -1 for failure. */ + 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; + int ret; if (have_ptrace_booke_interface ()) { @@ -2069,9 +2118,18 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw, create_watchpoint_request (&p, addr, len, rw, cond, 1); ALL_LWPS (lp, ptid) - booke_insert_point (&p, TIDGET (ptid)); + { + ret = booke_insert_point (&p, TIDGET (ptid)); + if (ret) + break; + } - ret = 0; + /* If an error occurred, remove the breakpoint from all threads, to + keep consistency (all threads must have the same breakpoints and + watchpoints intalled.) */ + if (ret) + ALL_LWPS (lp, ptid) + booke_remove_point (&p, TIDGET (ptid)); } else { @@ -2111,25 +2169,38 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw, } saved_dabr_value = dabr_value; + ret = 0; ALL_LWPS (lp, ptid) if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0, saved_dabr_value) < 0) - return -1; + { + ret = -1; + break; + } - ret = 0; + /* If an error occurred, remove the breakpoint from all threads, to + keep consistency (all threads must have the same breakpoints and + watchpoints intalled.) */ + if (ret) + ppc_linux_remove_watchpoint (addr, len, rw, cond); } return ret; } +/* Remove a hardware watchpoint at address ADDR, spanning LEN bytes. + RW may be hw_read for a read watchpoint, hw_write for a write watchpoint + or hw_access for an access watchpoint. Returns 0 for success, 1 if + hardware watchpoints are not supported or -1 for failure. */ + 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; + int ret = 0; if (have_ptrace_booke_interface ()) { @@ -2138,19 +2209,16 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw, create_watchpoint_request (&p, addr, len, rw, cond, 0); ALL_LWPS (lp, ptid) - booke_remove_point (&p, TIDGET (ptid)); - - ret = 0; + ret |= booke_remove_point (&p, TIDGET (ptid)); } 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; + ret = -1; } return ret;