From patchwork Mon Sep 24 21:42:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Brobecker X-Patchwork-Id: 29529 Received: (qmail 27533 invoked by alias); 24 Sep 2018 21:42:36 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 27445 invoked by uid 89); 24 Sep 2018 21:42:35 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=duo, notified X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 24 Sep 2018 21:42:33 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 1B8A5117B6B; Mon, 24 Sep 2018 17:42:32 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id O0dJEdflv69Z; Mon, 24 Sep 2018 17:42:32 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id DCD9A117B6A; Mon, 24 Sep 2018 17:42:31 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id F2F46874C9; Mon, 24 Sep 2018 14:42:29 -0700 (PDT) From: Joel Brobecker To: gdb-patches@sourceware.org Cc: Andrew Burgess , Tim Newsome Subject: [RFA/RFC] riscv: expect hardware watchpoints to trigger before the memory is written Date: Mon, 24 Sep 2018 14:42:28 -0700 Message-Id: <20180924214228.14578-1-brobecker@adacore.com> Hello, below is a patch that fixes hardware watchpoint support, at least when using QEMU. The reason why I say "at least" is because I'm not entirely clear whether RISCV defined if GDB is expected to be notified before or after the memory is being written. At the moment, the notification comes before, but I am wondering if it should be after. That reminded me of https://sourceware.org/ml/gdb/2018-08/msg00047.html, where it was said the debug spec suggests the event be triggered before. However, I couldn't find confirmation of that, or its contrary, in the document I could find at https://github.com/riscv/riscv-debug-spec. It looks to me like the behavior might not be specified. Does anyone know? I'm copying Tim Newsome (author of the thread quoted above) in case he knows more. If not, I suggest we put this patch in. At worst, GDB does one extra instruction single-step. Without it, the GDB / QEMU duo get stuck in an infinite loop. ---------------------------------------------------------------------- When using QEMU as a RISCV simulator, hardware watchpoint events are reported to GDB before the target memory gets written. GDB currently expects the event to be reported after it is written. As a result of this mismatch, upon receiving the event, GDB sees that the target memory region has not changed, and therefore decides to ignore the event. It therefore resumes the program's execution with a continue, which is the start of an infinite loop between QEMU repeatedly reporting the same watchpoint event over and over, and GDB repeatedly ignoring it. This patch fixes the issue by telling GDB to expect the watchpoint event to be reported ahead of the memory region being modified. Upon receiving the event, GDB then single-steps the program before checking the watched memory value. gdb/ChangeLog: * riscv-tdep.c (riscv_gdbarch_init): Set the gdbarch's have_nonsteppable_watchpoint attribute to 1. Tested on riscv64-elf using AdaCore's testsuite. --- gdb/riscv-tdep.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index 8bd78a24b48..ab3763349bf 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -2737,6 +2737,7 @@ riscv_gdbarch_init (struct gdbarch_info info, set_gdbarch_return_value (gdbarch, riscv_return_value); set_gdbarch_breakpoint_kind_from_pc (gdbarch, riscv_breakpoint_kind_from_pc); set_gdbarch_sw_breakpoint_from_kind (gdbarch, riscv_sw_breakpoint_from_kind); + set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); /* Register architecture. */ set_gdbarch_num_regs (gdbarch, RISCV_LAST_REGNUM + 1);