From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 98108 invoked by alias); 31 Aug 2016 15:06:44 -0000 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 Received: (qmail 97991 invoked by uid 89); 31 Aug 2016 15:06:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,RCVD_IN_SORBS_SPAM,SPF_PASS autolearn=no version=3.3.2 spammy=28006, 586,7, 5867 X-HELO: mail-pf0-f195.google.com Received: from mail-pf0-f195.google.com (HELO mail-pf0-f195.google.com) (209.85.192.195) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 31 Aug 2016 15:06:28 +0000 Received: by mail-pf0-f195.google.com with SMTP id h186so2897833pfg.2 for ; Wed, 31 Aug 2016 08:06:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=PczrKwE8mK+W6PSOuuPUuYAKVaqcgCXd/oCyUX99agY=; b=UpdgQyVEjT5sXz5W+sH5okwNaJXFGuTGGU52f7YMd2I/2EOM/iq3eVy6kowEz9y9s1 uEsR/GTOLc3QPwcBzcgGsIXT6dJZEISIazz4P7HLL7AsZeK2AmL1GHY01D8IbLF78Mnn AjSJ0tMjROMucRahLsyGHXVmdG77HCVQMSWBcSwFVPuxQSXBZauQGuIFdDH9DzXOJwfS YVihCyJDTIEfHwwXaIL7AMnq+2/9z9JL/mkdPCEpQB9376WACY5Bxja+x+QF6xvshauo KZ0GZ3GYD9xMKdZVx0i95yaVdISvFw4h28ocgZzfU9c4a0mxrV16HLOBjQd6EH9GJBBY kFBA== X-Gm-Message-State: AE9vXwNKy3o7T6VARIFvmQuycBMagJnLPLbCdpzoM71iBc0IF0j6KeNn5HXzkP/7DRSh+Q== X-Received: by 10.98.26.133 with SMTP id a127mr17436644pfa.46.1472655986861; Wed, 31 Aug 2016 08:06:26 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (gcc115.osuosl.org. [140.211.9.73]) by smtp.gmail.com with ESMTPSA id c125sm464809pfc.40.2016.08.31.08.06.25 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 31 Aug 2016 08:06:26 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 12/13] Determine the kind of single step breakpoint Date: Wed, 31 Aug 2016 15:06:00 -0000 Message-Id: <1472655965-12212-13-git-send-email-yao.qi@linaro.org> In-Reply-To: <1472655965-12212-1-git-send-email-yao.qi@linaro.org> References: <1472655965-12212-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes X-SW-Source: 2016-08/txt/msg00325.txt.bz2 This patch adds a new gdbarch method breakpoint_kind_from_current_state for single step breakpoint, and uses it in breakpoint_kind. gdb: 2016-07-20 Yao Qi * arch-utils.c (default_breakpoint_kind_from_current_state): New function. * arch-utils.h (default_breakpoint_kind_from_current_state): Declare. * arm-tdep.c (arm_breakpoint_kind_from_current_state): New function. (arm_gdbarch_init): Call set_gdbarch_breakpoint_kind_from_current_state. * breakpoint.c (breakpoint_kind): Call gdbarch_breakpoint_kind_from_current_state for single step breakpoint. * gdbarch.sh (breakpoint_kind_from_current_state): New. * gdbarch.c, gdbarch.h: Regenerate. --- gdb/arch-utils.c | 8 ++++++++ gdb/arch-utils.h | 4 ++++ gdb/arm-tdep.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/breakpoint.c | 13 ++++++++++++- gdb/gdbarch.c | 23 +++++++++++++++++++++++ gdb/gdbarch.h | 8 ++++++++ gdb/gdbarch.sh | 5 +++++ 7 files changed, 115 insertions(+), 1 deletion(-) diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index e236877..ad2787a 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -820,6 +820,14 @@ default_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, return gdbarch_sw_breakpoint_from_kind (gdbarch, kind, lenptr); } +int +default_breakpoint_kind_from_current_state (struct gdbarch *gdbarch, + struct regcache *regcache, + CORE_ADDR *pcptr) +{ + return gdbarch_breakpoint_kind_from_pc (gdbarch, pcptr); +} + void default_gen_return_address (struct gdbarch *gdbarch, diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 4af8b9f..2db5ce7 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -213,6 +213,10 @@ extern const gdb_byte *default_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr); +extern int default_breakpoint_kind_from_current_state (struct gdbarch *gdbarch, + struct regcache *regcache, + CORE_ADDR *pcptr); + extern void default_gen_return_address (struct gdbarch *gdbarch, struct agent_expr *ax, struct axs_value *value, diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index f03897c..37b68ed 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -7853,6 +7853,59 @@ arm_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size) } } +/* Implement the breakpoint_kind_from_current_state gdbarch method. */ + +static int +arm_breakpoint_kind_from_current_state (struct gdbarch *gdbarch, + struct regcache *regcache, + CORE_ADDR *pcptr) +{ + gdb_byte buf[4]; + + /* Check the memory pointed by PC is readable. */ + if (target_read_memory (regcache_read_pc (regcache), buf, 4) == 0) + { + struct arm_get_next_pcs next_pcs_ctx; + CORE_ADDR pc; + int i; + VEC (CORE_ADDR) *next_pcs = NULL; + struct cleanup *old_chain + = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs); + + arm_get_next_pcs_ctor (&next_pcs_ctx, + &arm_get_next_pcs_ops, + gdbarch_byte_order (gdbarch), + gdbarch_byte_order_for_code (gdbarch), + 0, + regcache); + + next_pcs = arm_get_next_pcs (&next_pcs_ctx); + + /* If MEMADDR is the next instruction of current pc, do the + software single step computation, and get the thumb mode by + the destination address. */ + for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++) + { + if (UNMAKE_THUMB_ADDR (pc) == *pcptr) + { + do_cleanups (old_chain); + + if (IS_THUMB_ADDR (pc)) + { + *pcptr = MAKE_THUMB_ADDR (*pcptr); + return arm_breakpoint_kind_from_pc (gdbarch, pcptr); + } + else + return ARM_BP_KIND_ARM; + } + } + + do_cleanups (old_chain); + } + + return arm_breakpoint_kind_from_pc (gdbarch, pcptr); +} + /* Extract from an array REGBUF containing the (raw) register state a function return value of type TYPE, and copy that, in virtual format, into VALBUF. */ @@ -9361,6 +9414,8 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Breakpoint manipulation. */ SET_GDBARCH_BREAKPOINT_MANIPULATION (arm); + set_gdbarch_breakpoint_kind_from_current_state (gdbarch, + arm_breakpoint_kind_from_current_state); /* Information about registers, etc. */ set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM); diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index cc672f7..2b6976e 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -2607,7 +2607,18 @@ build_target_command_list (struct bp_location *bl) static int breakpoint_kind (struct bp_location *bl, CORE_ADDR *addr) { - return gdbarch_breakpoint_kind_from_pc (bl->gdbarch, addr); + if (bl->owner->type == bp_single_step) + { + struct thread_info *thr = find_thread_global_id (bl->owner->thread); + struct regcache *regcache; + + regcache = get_thread_regcache (thr->ptid); + + return gdbarch_breakpoint_kind_from_current_state (bl->gdbarch, + regcache, addr); + } + else + return gdbarch_breakpoint_kind_from_pc (bl->gdbarch, addr); } /* Insert a low-level "breakpoint" of some type. BL is the breakpoint diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index ca430a9..e480023 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -231,6 +231,7 @@ struct gdbarch gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc; gdbarch_breakpoint_kind_from_pc_ftype *breakpoint_kind_from_pc; gdbarch_sw_breakpoint_from_kind_ftype *sw_breakpoint_from_kind; + gdbarch_breakpoint_kind_from_current_state_ftype *breakpoint_kind_from_current_state; gdbarch_adjust_breakpoint_address_ftype *adjust_breakpoint_address; gdbarch_memory_insert_breakpoint_ftype *memory_insert_breakpoint; gdbarch_memory_remove_breakpoint_ftype *memory_remove_breakpoint; @@ -404,6 +405,7 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->return_in_first_hidden_param_p = default_return_in_first_hidden_param_p; gdbarch->breakpoint_from_pc = default_breakpoint_from_pc; gdbarch->sw_breakpoint_from_kind = NULL; + gdbarch->breakpoint_kind_from_current_state = default_breakpoint_kind_from_current_state; gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint; gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint; gdbarch->remote_register_number = default_remote_register_number; @@ -584,6 +586,7 @@ verify_gdbarch (struct gdbarch *gdbarch) if (gdbarch->breakpoint_kind_from_pc == 0) fprintf_unfiltered (log, "\n\tbreakpoint_kind_from_pc"); /* Skip verify of sw_breakpoint_from_kind, invalid_p == 0 */ + /* Skip verify of breakpoint_kind_from_current_state, invalid_p == 0 */ /* Skip verify of adjust_breakpoint_address, has predicate. */ /* Skip verify of memory_insert_breakpoint, invalid_p == 0 */ /* Skip verify of memory_remove_breakpoint, invalid_p == 0 */ @@ -793,6 +796,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: breakpoint_from_pc = <%s>\n", host_address_to_string (gdbarch->breakpoint_from_pc)); fprintf_unfiltered (file, + "gdbarch_dump: breakpoint_kind_from_current_state = <%s>\n", + host_address_to_string (gdbarch->breakpoint_kind_from_current_state)); + fprintf_unfiltered (file, "gdbarch_dump: breakpoint_kind_from_pc = <%s>\n", host_address_to_string (gdbarch->breakpoint_kind_from_pc)); fprintf_unfiltered (file, @@ -2800,6 +2806,23 @@ set_gdbarch_sw_breakpoint_from_kind (struct gdbarch *gdbarch, } int +gdbarch_breakpoint_kind_from_current_state (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR *pcptr) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->breakpoint_kind_from_current_state != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_breakpoint_kind_from_current_state called\n"); + return gdbarch->breakpoint_kind_from_current_state (gdbarch, regcache, pcptr); +} + +void +set_gdbarch_breakpoint_kind_from_current_state (struct gdbarch *gdbarch, + gdbarch_breakpoint_kind_from_current_state_ftype breakpoint_kind_from_current_state) +{ + gdbarch->breakpoint_kind_from_current_state = breakpoint_kind_from_current_state; +} + +int gdbarch_adjust_breakpoint_address_p (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 65a6a6e..0df6dc8 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -556,6 +556,14 @@ typedef const gdb_byte * (gdbarch_sw_breakpoint_from_kind_ftype) (struct gdbarch extern const gdb_byte * gdbarch_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size); extern void set_gdbarch_sw_breakpoint_from_kind (struct gdbarch *gdbarch, gdbarch_sw_breakpoint_from_kind_ftype *sw_breakpoint_from_kind); +/* Return the breakpoint kind for this target based on the current + processor state (e.g. the current instruction mode on ARM) and the + *PCPTR. In default, it is gdbarch->breakpoint_kind_from_pc. */ + +typedef int (gdbarch_breakpoint_kind_from_current_state_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR *pcptr); +extern int gdbarch_breakpoint_kind_from_current_state (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR *pcptr); +extern void set_gdbarch_breakpoint_kind_from_current_state (struct gdbarch *gdbarch, gdbarch_breakpoint_kind_from_current_state_ftype *breakpoint_kind_from_current_state); + extern int gdbarch_adjust_breakpoint_address_p (struct gdbarch *gdbarch); typedef CORE_ADDR (gdbarch_adjust_breakpoint_address_ftype) (struct gdbarch *gdbarch, CORE_ADDR bpaddr); diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index c999f30..82d2c71 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -564,6 +564,11 @@ m:int:breakpoint_kind_from_pc:CORE_ADDR *pcptr:pcptr::0: # SIZE is set to the software breakpoint's length in memory. m:const gdb_byte *:sw_breakpoint_from_kind:int kind, int *size:kind, size::NULL::0 +# Return the breakpoint kind for this target based on the current +# processor state (e.g. the current instruction mode on ARM) and the +# *PCPTR. In default, it is gdbarch->breakpoint_kind_from_pc. +m:int:breakpoint_kind_from_current_state:struct regcache *regcache, CORE_ADDR *pcptr:regcache, pcptr:0:default_breakpoint_kind_from_current_state::0 + M:CORE_ADDR:adjust_breakpoint_address:CORE_ADDR bpaddr:bpaddr m:int:memory_insert_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_insert_breakpoint::0 m:int:memory_remove_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_remove_breakpoint::0 -- 1.9.1