From patchwork Tue Nov 26 17:11:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Simon Marchi (Code Review)" X-Patchwork-Id: 36231 Received: (qmail 97328 invoked by alias); 26 Nov 2019 17:12:20 -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 96050 invoked by uid 89); 26 Nov 2019 17:12:11 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3 autolearn=ham version=3.3.1 spammy= X-HELO: mx1.osci.io Received: from polly.osci.io (HELO mx1.osci.io) (8.43.85.229) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 26 Nov 2019 17:12:08 +0000 Received: by mx1.osci.io (Postfix, from userid 994) id E1EA52094D; Tue, 26 Nov 2019 12:12:03 -0500 (EST) Received: from gnutoolchain-gerrit.osci.io (gnutoolchain-gerrit.osci.io [IPv6:2620:52:3:1:5054:ff:fe06:16ca]) by mx1.osci.io (Postfix) with ESMTP id E2EF122279 for ; Tue, 26 Nov 2019 12:11:33 -0500 (EST) Received: from localhost (localhost [127.0.0.1]) by gnutoolchain-gerrit.osci.io (Postfix) with ESMTP id D4AC328173 for ; Tue, 26 Nov 2019 12:11:33 -0500 (EST) X-Gerrit-PatchSet: 1 Date: Tue, 26 Nov 2019 12:11:33 -0500 From: "Tom Tromey (Code Review)" To: gdb-patches@sourceware.org Message-ID: Auto-Submitted: auto-generated X-Gerrit-MessageType: newchange Subject: [review] Implement stopped_by_sw_breakpoint for Windows gdbserver X-Gerrit-Change-Id: Ib603fca745bc4ae43b6399f40919b1b399de5d51 X-Gerrit-Change-Number: 723 X-Gerrit-ChangeURL: X-Gerrit-Commit: 268de908e863de092f352164472f0191cad0785c References: Reply-To: tromey@sourceware.org, gdb-patches@sourceware.org MIME-Version: 1.0 Content-Disposition: inline User-Agent: Gerrit/3.0.3-79-g83ff7f88f1 Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/723 ...................................................................... Implement stopped_by_sw_breakpoint for Windows gdbserver This changes the Windows gdbserver port to implement the stopped_by_sw_breakpoint target method. This is needed to support pending stops. This is a separate patch now, because Pedro suggested splitting it out for simpler bisecting, in the case that it introduces a bug. 2019-11-26 Tom Tromey * win32-low.c (win32_supports_z_point_type): Always handle Z_PACKET_SW_BP. (win32_insert_point): Call insert_memory_breakpoint when needed. (win32_remove_point): Call remove_memory_breakpoint when needed. (win32_stopped_by_sw_breakpoint) (win32_supports_stopped_by_sw_breakpoint): New functions. (win32_target_ops): Update. (maybe_adjust_pc): New function. (win32_wait): Call maybe_adjust_pc. Change-Id: Ib603fca745bc4ae43b6399f40919b1b399de5d51 --- M gdb/gdbserver/ChangeLog M gdb/gdbserver/win32-low.c 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 0002bf7..9008bdc 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,17 @@ 2019-11-26 Tom Tromey + * win32-low.c (win32_supports_z_point_type): Always handle + Z_PACKET_SW_BP. + (win32_insert_point): Call insert_memory_breakpoint when needed. + (win32_remove_point): Call remove_memory_breakpoint when needed. + (win32_stopped_by_sw_breakpoint) + (win32_supports_stopped_by_sw_breakpoint): New functions. + (win32_target_ops): Update. + (maybe_adjust_pc): New function. + (win32_wait): Call maybe_adjust_pc. + +2019-11-26 Tom Tromey + * win32-low.h (struct win32_target_ops) : New field. * win32-i386-low.c (the_low_target): Update. diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c index 9d88d1a..c472e0e 100644 --- a/gdb/gdbserver/win32-low.c +++ b/gdb/gdbserver/win32-low.c @@ -236,15 +236,18 @@ static int win32_supports_z_point_type (char z_type) { - return (the_low_target.supports_z_point_type != NULL - && the_low_target.supports_z_point_type (z_type)); + return (z_type == Z_PACKET_SW_BP + || (the_low_target.supports_z_point_type != NULL + && the_low_target.supports_z_point_type (z_type))); } static int win32_insert_point (enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp) { - if (the_low_target.insert_point != NULL) + if (type == raw_bkpt_type_sw) + return insert_memory_breakpoint (bp); + else if (the_low_target.insert_point != NULL) return the_low_target.insert_point (type, addr, size, bp); else /* Unsupported (see target.h). */ @@ -255,7 +258,9 @@ win32_remove_point (enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp) { - if (the_low_target.remove_point != NULL) + if (type == raw_bkpt_type_sw) + return remove_memory_breakpoint (bp); + else if (the_low_target.remove_point != NULL) return the_low_target.remove_point (type, addr, size, bp); else /* Unsupported (see target.h). */ @@ -1177,6 +1182,31 @@ return false; } +/* A helper function that will, if needed, set 'stopped_at_breakpoint' + on the thread and adjust the PC. */ + +static void +maybe_adjust_pc () +{ + struct regcache *regcache = get_thread_regcache (current_thread, 1); + child_fetch_inferior_registers (regcache, -1); + + windows_thread_info *th = thread_rec (current_thread_ptid (), + INVALIDATE_CONTEXT); + th->stopped_at_breakpoint = false; + + if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT + && (current_event.u.Exception.ExceptionRecord.ExceptionCode + == EXCEPTION_BREAKPOINT) + && child_initialization_done) + { + th->stopped_at_breakpoint = true; + CORE_ADDR pc = regcache_read_pc (regcache); + CORE_ADDR sw_breakpoint_pc = pc - the_low_target.decr_pc_after_break; + regcache_write_pc (regcache, sw_breakpoint_pc); + } +} + /* Get the next event from the child. */ static int @@ -1388,8 +1418,6 @@ static ptid_t win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options) { - struct regcache *regcache; - if (cached_status.kind != TARGET_WAITKIND_IGNORE) { /* The core always does a wait after creating the inferior, and @@ -1416,12 +1444,12 @@ return ptid_t (current_event.dwProcessId); case TARGET_WAITKIND_STOPPED: case TARGET_WAITKIND_LOADED: - OUTMSG2 (("Child Stopped with signal = %d \n", - ourstatus->value.sig)); - - regcache = get_thread_regcache (current_thread, 1); - child_fetch_inferior_registers (regcache, -1); - return debug_event_ptid (¤t_event); + { + OUTMSG2 (("Child Stopped with signal = %d \n", + ourstatus->value.sig)); + maybe_adjust_pc (); + return debug_event_ptid (¤t_event); + } default: OUTMSG (("Ignoring unknown internal event, %d\n", ourstatus->kind)); /* fall-through */ @@ -1585,6 +1613,26 @@ return the_low_target.breakpoint; } +/* Implementation of the target_ops method + "stopped_by_sw_breakpoint". */ + +static int +win32_stopped_by_sw_breakpoint () +{ + windows_thread_info *th = thread_rec (current_thread_ptid (), + DONT_INVALIDATE_CONTEXT); + return th == nullptr ? 0 : th->stopped_at_breakpoint; +} + +/* Implementation of the target_ops method + "supports_stopped_by_sw_breakpoint". */ + +static int +win32_supports_stopped_by_sw_breakpoint () +{ + return 1; +} + /* Implementation of the target_ops method "read_pc". */ static CORE_ADDR @@ -1624,8 +1672,8 @@ win32_supports_z_point_type, win32_insert_point, win32_remove_point, - NULL, /* stopped_by_sw_breakpoint */ - NULL, /* supports_stopped_by_sw_breakpoint */ + win32_stopped_by_sw_breakpoint, + win32_supports_stopped_by_sw_breakpoint, NULL, /* stopped_by_hw_breakpoint */ NULL, /* supports_stopped_by_hw_breakpoint */ target_can_do_hardware_single_step,