[RFC,10/15] gdb: Add arm_fast_tracepoint_valid_at

Message ID 3a55070efb60b203fc73e0529a586d16f794ac26.1444820235.git.henrik.wallin@windriver.com
State New, archived
Headers

Commit Message

henrik.wallin@windriver.com Oct. 14, 2015, 11:14 a.m. UTC
  From: Henrik Wallin <henrik.wallin@windriver.com>

This adds the function. No users yet.

A 4 byte jump instruction will be used and the code need to
handle multiple cases as the instruction can be 2, or 4 bytes long and
the mode can be either arm or thumb.

gdb/ChangeLog:

	* arm-tdep.c (arm_fast_tracepoint_valid_at): New function.

Signed-off-by: Henrik Wallin <henrik.wallin@windriver.com>
---
 gdb/arm-tdep.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)
  

Comments

Yao Qi Oct. 27, 2015, 11:25 a.m. UTC | #1
henrik.wallin@windriver.com writes:

> +  if (arm_pc_is_thumb (gdbarch, addr))
> +    {
> +      len = gdb_print_insn (gdbarch, addr, gdb_null, NULL);

We don't need to call gdb_print_insn to know the instruction size.
Instead, we can do something simpler,

  if (arm_pc_is_thumb (gdbarch, pc))
    {
       len = thumb_insn_size (inst1);
    }
  else
    len = 4;

See how it is done in arm-tdep.c:arm_breakpoint_from_pc
  
henrik.wallin@windriver.com Oct. 29, 2015, 5:51 p.m. UTC | #2
2015-10-27 12:25 GMT+01:00 Yao Qi <qiyaoltc@gmail.com>:
> henrik.wallin@windriver.com writes:
>
>> +  if (arm_pc_is_thumb (gdbarch, addr))
>> +    {
>> +      len = gdb_print_insn (gdbarch, addr, gdb_null, NULL);
>
> We don't need to call gdb_print_insn to know the instruction size.
> Instead, we can do something simpler,
>
>   if (arm_pc_is_thumb (gdbarch, pc))
>     {
>        len = thumb_insn_size (inst1);
>     }
>   else
>     len = 4;

yes, that looks better.

thanks,
/ Henrik
  

Patch

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index b277c3ef405c..601d589b8a89 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -22,6 +22,7 @@ 
 #include <ctype.h>		/* XXX for isupper ().  */
 
 #include "frame.h"
+#include "disasm.h"
 #include "inferior.h"
 #include "infrun.h"
 #include "gdbcmd.h"
@@ -10506,6 +10507,52 @@  arm_relocate_instruction (struct gdbarch *gdbarch,
   arm_relocate_instruction_func (&rel);
 }
 
+static int
+arm_fast_tracepoint_valid_at (struct gdbarch *gdbarch,
+			      CORE_ADDR addr, char **msg)
+{
+  static struct ui_file *gdb_null = NULL;
+  int len;
+
+  /* Check if the instruction is relocatable.   */
+  if (arm_check_relocate_instruction (gdbarch, addr, msg) == -1)
+    return 0;
+
+  /* Dummy file descriptor for the disassembler.  */
+  if (!gdb_null)
+    gdb_null = ui_file_new ();
+
+  /* A branch instruction used for fast tracepoint takes 4 bytes.
+     (A 2 bytes branch instruction only gets us 4k away,
+     so will not be enough.)
+
+     target gdbserver will validate that the relative branch
+     distance will fit in the instructions.
+     (16M for Thumb, 32M for ARM)
+
+     We only allow to replace one instuction. (4 bytes)
+     Replacing 2 instructions is not safe. Consider
+     the case where code wants to jump to the 2nd instruction - it
+     will jump into the middle of a branch instruction.   */
+
+  if (arm_pc_is_thumb (gdbarch, addr))
+    {
+      len = gdb_print_insn (gdbarch, addr, gdb_null, NULL);
+      if (len == 2)
+	{
+	  if (msg)
+	    *msg = xstrprintf (_("; instruction is only 2 bytes long, "
+				 "need 4 bytes for the jump"));
+	  return 0;
+	}
+    }
+
+  if (msg)
+    *msg = NULL;
+
+  return 1;
+}
+
 
 /* Initialize the current architecture based on INFO.  If possible,
    re-use an architecture from ARCHES, which is a list of