Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Antoine Tremblay <antoine.tremblay@ericsson.com>
To: <gdb-patches@sourceware.org>
Cc: Antoine Tremblay <antoine.tremblay@ericsson.com>
Subject: [PATCH 01/10] Fix breakpoint size when stepping over a permanent breakpoint in GDBServer.
Date: Thu, 29 Oct 2015 17:36:00 -0000	[thread overview]
Message-ID: <1446138583-13268-2-git-send-email-antoine.tremblay@ericsson.com> (raw)
In-Reply-To: <1446138583-13268-1-git-send-email-antoine.tremblay@ericsson.com>

When manually stepping over a permanent breakpoint on ARM we need to fetch the
right breakpoint size based on the current instruction set used.

Since this is not encoded in the stop_pc, the instruction mode needs to be
fetched from the CPSR register.

This is done by introducing a new target operation called :
breakpoint_kind_from_current_state.

For other targets that do not need this, breakpoint_kind_from_pc is used.

No regressions, tested on ubuntu 14.04 ARMv7 and x86.
With gdbserver-{native,extended} / { -marm -mthumb }

gdb/gdbserver/ChangeLog:

	* linux-arm-low.c (arm_is_thumb_mode): New function.
	(arm_breakpoint_at): Use arm_is_thumb_mode.
	(arm_breakpoint_kind_from_current_state): New function.
	(struct linux_target_ops) <breakpoint_kind_from_current_state>:
	Initialize.
	* linux-low.c (linux_wait_1): Call breakpoint_kind_from_current_state.
	(linux_breakpoint_kind_from_current_state): New function.
	(struct target_ops <breakpoint_kind_from_current_state>: Initialize.
	* linux-low.h (struct linux_target_ops)
	<breakpoint_kind_from_current_state>: New field.
	* target.h (struct target_ops): Likewise.
	(target_breakpoint_kind_from_current_state): New macro.
---
 gdb/gdbserver/linux-arm-low.c | 38 +++++++++++++++++++++++++++++++++++++-
 gdb/gdbserver/linux-low.c     | 18 ++++++++++++++++--
 gdb/gdbserver/linux-low.h     |  3 +++
 gdb/gdbserver/target.h        | 11 +++++++++++
 4 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index bab2aaf..d6767d7 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -265,7 +265,7 @@ static const unsigned short thumb2_breakpoint[] = { 0xf7f0, 0xa000 };
 #define thumb2_breakpoint_len 4
 
 static int
-arm_breakpoint_at (CORE_ADDR where)
+arm_is_thumb_mode (void)
 {
   struct regcache *regcache = get_thread_regcache (current_thread, 1);
   unsigned long cpsr;
@@ -273,6 +273,17 @@ arm_breakpoint_at (CORE_ADDR where)
   collect_register_by_name (regcache, "cpsr", &cpsr);
 
   if (cpsr & 0x20)
+    return 1;
+  else
+    return 0;
+}
+
+/* Returns 1 if there is a software breakpoint at location.  */
+
+static int
+arm_breakpoint_at (CORE_ADDR where)
+{
+  if (arm_is_thumb_mode ())
     {
       /* Thumb mode.  */
       unsigned short insn;
@@ -993,6 +1004,23 @@ arm_sw_breakpoint_from_kind (int kind , int *size)
   return NULL;
 }
 
+/* Implementation of the linux_target_ops method
+   "breakpoint_kind_from_current_state".  */
+
+static int
+arm_breakpoint_kind_from_current_state (CORE_ADDR *pcptr)
+{
+  if (arm_is_thumb_mode ())
+    {
+      *pcptr = MAKE_THUMB_ADDR (*pcptr);
+      return arm_breakpoint_kind_from_pc (pcptr);
+    }
+  else
+    {
+      return arm_breakpoint_kind_from_pc (pcptr);
+    }
+}
+
 struct linux_target_ops the_low_target = {
   arm_arch_setup,
   arm_regs_info,
@@ -1018,6 +1046,14 @@ struct linux_target_ops the_low_target = {
   arm_new_thread,
   arm_new_fork,
   arm_prepare_to_resume,
+  NULL, /* process_qsupported */
+  NULL, /* supports_tracepoints */
+  NULL, /* get_thread_area */
+  NULL, /* install_fast_tracepoint_jump_pad */
+  NULL, /* emit_ops */
+  NULL, /* get_min_fast_tracepoint_insn_len */
+  NULL, /* supports_range_stepping */
+  arm_breakpoint_kind_from_current_state
 };
 
 void
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 41ab510..3b6c131 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -3006,7 +3006,8 @@ linux_wait_1 (ptid_t ptid,
       int breakpoint_kind = 0;
       CORE_ADDR stop_pc = event_child->stop_pc;
 
-      breakpoint_kind = the_target->breakpoint_kind_from_pc (&stop_pc);
+      breakpoint_kind =
+	the_target->breakpoint_kind_from_current_state (&stop_pc);
       the_target->sw_breakpoint_from_kind (breakpoint_kind, &increment_pc);
 
       if (debug_threads)
@@ -6948,6 +6949,18 @@ linux_sw_breakpoint_from_kind (int kind, int *size)
   return (*the_low_target.sw_breakpoint_from_kind) (kind, size);
 }
 
+/* Implementation of the target_ops method
+   "breakpoint_kind_from_current_state".  */
+
+static int
+linux_breakpoint_kind_from_current_state (CORE_ADDR *pcptr)
+{
+  if (the_low_target.breakpoint_kind_from_current_state != NULL)
+    return (*the_low_target.breakpoint_kind_from_current_state) (pcptr);
+  else
+    return linux_breakpoint_kind_from_pc (pcptr);
+}
+
 static struct target_ops linux_target_ops = {
   linux_create_inferior,
   linux_arch_setup,
@@ -7043,7 +7056,8 @@ static struct target_ops linux_target_ops = {
   linux_mntns_unlink,
   linux_mntns_readlink,
   linux_breakpoint_kind_from_pc,
-  linux_sw_breakpoint_from_kind
+  linux_sw_breakpoint_from_kind,
+  linux_breakpoint_kind_from_current_state
 };
 
 static void
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index ccf4c94..fb15136 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -233,6 +233,9 @@ struct linux_target_ops
 
   /* Returns true if the low target supports range stepping.  */
   int (*supports_range_stepping) (void);
+
+  /* See target.h.  */
+  int (*breakpoint_kind_from_current_state) (CORE_ADDR *pcptr);
 };
 
 extern struct linux_target_ops the_low_target;
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 769c876..f0fb9d7 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -451,6 +451,12 @@ struct target_ops
      specific meaning like the Z0 kind parameter.
      SIZE is set to the software breakpoint's length in memory.  */
   const gdb_byte *(*sw_breakpoint_from_kind) (int kind, int *size);
+
+  /* Return the breakpoint kind for this target based on the current state
+     (e.g. the current instruction mode on ARM) and the PC. The PCPTR is
+     adjusted to the real memory location in case a flag (e.g., the Thumb
+     bit on ARM) was present in the PC.  */
+  int (*breakpoint_kind_from_current_state) (CORE_ADDR *pcptr);
 };
 
 extern struct target_ops *the_target;
@@ -638,6 +644,11 @@ int kill_inferior (int);
    ? (*the_target->breakpoint_kind_from_pc) (pcptr) \
    : default_breakpoint_kind_from_pc (pcptr))
 
+#define target_breakpoint_kind_from_current_state(pcptr) \
+  (the_target->breakpoint_kind_from_current_state \
+   ? (*the_target->breakpoint_kind_from_current_state) (pcptr) \
+   : target_breakpoint_kind_from_pc (pcptr))
+
 /* Start non-stop mode, returns 0 on success, -1 on failure.   */
 
 int start_non_stop (int nonstop);
-- 
1.9.1


  parent reply	other threads:[~2015-10-29 17:09 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-29 17:14 [PATCH 0/10] Support software single step and conditional breakpoints on ARM " Antoine Tremblay
2015-10-29 17:15 ` [PATCH 04/10] Remove support for thread events without TRACE_EVENT_CLONE " Antoine Tremblay
2015-11-03 17:05   ` Yao Qi
2015-11-03 17:24     ` Antoine Tremblay
2015-11-03 17:27     ` [PATCH v2] " Antoine Tremblay
2015-11-04 18:19   ` [PATCH 04/10] " Pedro Alves
2015-11-05 11:43     ` Antoine Tremblay
2015-10-29 17:15 ` [PATCH 07/10] Share some ARM target dependant code from GDB with GDBServer Antoine Tremblay
2015-11-04 19:56   ` Pedro Alves
2015-11-05 14:44     ` Antoine Tremblay
2015-10-29 17:15 ` [PATCH 10/10] Enable conditional breakpoints for targets that support software single step in GDBServer Antoine Tremblay
2015-11-04 18:58   ` Pedro Alves
2015-10-29 17:16 ` [PATCH 09/10] Enable software single stepping for while-stepping actions " Antoine Tremblay
2015-11-04 18:55   ` Pedro Alves
2015-10-29 17:28 ` [PATCH 03/10] Refactor queries for hardware and software single stepping support " Antoine Tremblay
2015-11-04 18:47   ` Pedro Alves
2015-10-29 17:31 ` [PATCH 05/10] Remove too simple breakpoint_reinsert_addr implementations Antoine Tremblay
2015-11-04 18:21   ` Pedro Alves
2015-10-29 17:36 ` Antoine Tremblay [this message]
2015-11-03 16:22   ` [PATCH 01/10] Fix breakpoint size when stepping over a permanent breakpoint in GDBServer Yao Qi
2015-11-03 17:05     ` Antoine Tremblay
2015-10-29 17:43 ` [PATCH 08/10] Support software single step on ARM " Antoine Tremblay
2015-11-04 18:46   ` Pedro Alves
2015-10-29 17:45 ` [PATCH 06/10] Replace breakpoint_reinsert_addr by get_next_pcs operation " Antoine Tremblay
2015-11-04 18:48   ` Pedro Alves
2015-11-05 14:35     ` Antoine Tremblay
2015-10-29 17:48 ` [PATCH 02/10] Fix instruction skipping when using software single step " Antoine Tremblay
2015-11-04 18:08   ` Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1446138583-13268-2-git-send-email-antoine.tremblay@ericsson.com \
    --to=antoine.tremblay@ericsson.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox