From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) by sourceware.org (Postfix) with ESMTPS id D4DE63893668 for ; Wed, 17 Jun 2020 15:59:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org D4DE63893668 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=hev.cc Authentication-Results: sourceware.org; spf=none smtp.mailfrom=r@hev.cc Received: by mail-pf1-x443.google.com with SMTP id d66so1336836pfd.6 for ; Wed, 17 Jun 2020 08:59:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hev-cc.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Se/UQhD3WXmzjMlh1EWhamkflzfS2G9z2M3otdAWVRM=; b=JgbMJ4UzEYaQTYb+1QhQOIo9CjNh17+aNX/ht0ygDQKs03vDgr9QURdBf3aBazgFUj 3jmShvdB0gBF9A/nlhyIcAQ90m9L1ivr3q6ZoXvsRRj+2XYuzFBV25o0j3+stXqF+3wP tHXz/xgOMOOd09a2zVhLUP0jTvrVvwxmT7I8ForeolbNiQLFY4XZc+zmPiJPbmF21I/s SJqe/t4EuUNWyNtq3lpgq5uUajlA/6KdsbV1SERSuxYEQKTXmGoyEmLv3/vz/AoYGaLk STCkr+WXArNiiL3diw1D0wj7qCi8ggoxhxmH8YGV2MqsmGfYgee0RtV/tVSOAn2JpnPZ +oAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Se/UQhD3WXmzjMlh1EWhamkflzfS2G9z2M3otdAWVRM=; b=XzdEt7dAkBz8oMm19EY14iQx9cdCMF3s6jDrjtkgzJaKBoFOoyQwfMAEs+w/PaWZbI C9ggwPKq1jpDq1toKpAW1AgT9uN99wFVmhlAnmVA1bdMVmojUFLslUthzKDFBZYaMnOp 7N5i1dzYjiX7NoXoJVrCczccHIc4yzDrmLtNwmMp1yiDmxK5YL/OJtYaSuGo9uyAoN5n 4qvy9JPVJg879Fboi73LvhftzKdMDIpgYImPQPNpzzGuoXNj3dUvaviKkGiiTDq4Zp2K 0bcD6fF8LucpiO45fiu+VlipYBf/mMEcUCbFUspbcGJyaEYGGwnZtKtQ9RcNLJeuf6S2 8/5Q== X-Gm-Message-State: AOAM531y4eQx4BRSP6P/auM0s1h+kuuFAOYuYv2lhQ6RRXW0UYC24/pa 1rJs+3CBAblO7QL4njIqQJupbzjkF9DDDg== X-Google-Smtp-Source: ABdhPJy1yjfMdgi0o2Xfb+D1riA+eZ0hjBHABzL3QVA9N+S8zUWyczwyitCVjW4k+AdQSLlJGCBP6g== X-Received: by 2002:a65:62c9:: with SMTP id m9mr6707918pgv.392.1592409551510; Wed, 17 Jun 2020 08:59:11 -0700 (PDT) Received: from localhost.localdomain (28.144.92.34.bc.googleusercontent.com. [34.92.144.28]) by smtp.gmail.com with ESMTPSA id o96sm65748pjo.13.2020.06.17.08.59.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Jun 2020 08:59:10 -0700 (PDT) From: Heiher To: gdb-patches@sourceware.org Cc: Heiher Subject: [PATCH] MIPS: Introduce hardware breakpoint Date: Wed, 17 Jun 2020 23:58:58 +0800 Message-Id: <20200617155858.13801-1-r@hev.cc> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Jun 2020 15:59:14 -0000 gdb/ChangeLog: 2020-06-17 Heiher * mips-linux-nat.c (mips_linux_nat_target::can_use_hw_breakpoint): Handle case. (mips_linux_nat_target::stopped_by_watchpoint): Update. (mips_linux_nat_target::insert_hw_breakpoint): New methods. (mips_linux_nat_target::remove_hw_breakpoint): New methods. * nat/mips-linux-watch.c (mips_linux_watch_type_to_irw): Handle case. --- gdb/ChangeLog | 8 +++ gdb/mips-linux-nat.c | 127 ++++++++++++++++++++++++++++++++++++- gdb/nat/mips-linux-watch.c | 2 + 3 files changed, 136 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cb3761c1ba..7e913abcb5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2020-06-17 Heiher + * mips-linux-nat.c (mips_linux_nat_target::can_use_hw_breakpoint): + Handle case. + (mips_linux_nat_target::stopped_by_watchpoint): Update. + (mips_linux_nat_target::insert_hw_breakpoint): New methods. + (mips_linux_nat_target::remove_hw_breakpoint): New methods. + * nat/mips-linux-watch.c (mips_linux_watch_type_to_irw): Handle case. + 2020-06-16 Tom Tromey * python/py-tui.c (tui_py_window::~tui_py_window): Handle case diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c index 38ff461a35..9b0a910861 100644 --- a/gdb/mips-linux-nat.c +++ b/gdb/mips-linux-nat.c @@ -52,6 +52,8 @@ class mips_linux_nat_target final : public linux_nat_trad_target void close () override; int can_use_hw_breakpoint (enum bptype, int, int) override; + int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; + int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, struct expression *) override; @@ -546,6 +548,9 @@ mips_linux_nat_target::can_use_hw_breakpoint (enum bptype type, switch (type) { + case bp_hardware_breakpoint: + wanted_mask = I_MASK; + break; case bp_hardware_watchpoint: wanted_mask = W_MASK; break; @@ -588,7 +593,7 @@ mips_linux_nat_target::stopped_by_watchpoint () num_valid = mips_linux_watch_get_num_valid (&watch_readback); for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++) - if (mips_linux_watch_get_watchhi (&watch_readback, n) & (R_MASK | W_MASK)) + if (mips_linux_watch_get_watchhi (&watch_readback, n) & IRW_MASK) return true; return false; @@ -761,6 +766,126 @@ mips_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len, return retval; } +/* Insert a hardware-assisted breakpoint at BP_TGT->reqstd_address. + Return 0 on success, -1 on failure. */ + +int +mips_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt) +{ + struct pt_watch_regs regs; + struct mips_watchpoint *new_watch; + struct mips_watchpoint **pw; + + const enum target_hw_bp_type type = hw_execute; + CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address; + int retval; + int len; + + gdbarch_breakpoint_from_pc (gdbarch, &addr, &len); + + if (show_debug_regs) + fprintf_unfiltered + (gdb_stdlog, + "insert_hw_breakpoint on entry (addr=0x%08lx, len=%d))\n", + (unsigned long) addr, len); + + if (!mips_linux_read_watch_registers (inferior_ptid.lwp (), + &watch_readback, + &watch_readback_valid, 0)) + return -1; + + if (len <= 0) + return -1; + + regs = watch_readback; + /* Add the current watches. */ + mips_linux_watch_populate_regs (current_watches, ®s); + + /* Now try to add the new watch. */ + if (!mips_linux_watch_try_one_watch (®s, addr, len, + mips_linux_watch_type_to_irw (type))) + return -1; + + /* It fit. Stick it on the end of the list. */ + new_watch = XNEW (struct mips_watchpoint); + new_watch->addr = addr; + new_watch->len = len; + new_watch->type = type; + new_watch->next = NULL; + + pw = ¤t_watches; + while (*pw != NULL) + pw = &(*pw)->next; + *pw = new_watch; + + watch_mirror = regs; + retval = write_watchpoint_regs (); + + if (show_debug_regs) + mips_show_dr ("insert_hw_breakpoint", addr, len, type); + + return retval; +} + +/* Remove a hardware-assisted breakpoint at BP_TGT->placed_address. + Return 0 on success, -1 on failure. */ + +int +mips_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt) +{ + int retval; + int deleted_one; + int len = 4; + + struct mips_watchpoint **pw; + struct mips_watchpoint *w; + + const enum target_hw_bp_type type = hw_execute; + CORE_ADDR addr = bp_tgt->placed_address; + + gdbarch_breakpoint_from_pc (gdbarch, &addr, &len); + + if (show_debug_regs) + fprintf_unfiltered + (gdb_stdlog, "remove_hw_breakpoint on entry (addr=0x%08lx, len=%d))\n", + (unsigned long) addr, len); + + /* Search for a known watch that matches. Then unlink and free + it. */ + deleted_one = 0; + pw = ¤t_watches; + while ((w = *pw)) + { + if (w->addr == addr && w->len == len && w->type == type) + { + *pw = w->next; + xfree (w); + deleted_one = 1; + break; + } + pw = &(w->next); + } + + if (!deleted_one) + return -1; /* We don't know about it, fail doing nothing. */ + + /* At this point watch_readback is known to be valid because we + could not have added the watch without reading it. */ + gdb_assert (watch_readback_valid == 1); + + watch_mirror = watch_readback; + mips_linux_watch_populate_regs (current_watches, &watch_mirror); + + retval = write_watchpoint_regs (); + + if (show_debug_regs) + mips_show_dr ("remove_hw_watchpoint", addr, len, type); + + return retval; +} + /* Target to_close implementation. Free any watches and call the super implementation. */ diff --git a/gdb/nat/mips-linux-watch.c b/gdb/nat/mips-linux-watch.c index c975e2218a..74b95a9ac7 100644 --- a/gdb/nat/mips-linux-watch.c +++ b/gdb/nat/mips-linux-watch.c @@ -202,6 +202,8 @@ mips_linux_watch_type_to_irw (enum target_hw_bp_type type) { switch (type) { + case hw_execute: + return I_MASK; case hw_write: return W_MASK; case hw_read: -- 2.27.0