[RFC,15/15] gdb/gdbserver: Enable tracepoint for ARM

Message ID 38e54395d60fc93b63f57e6098ba96ef1c90bb54.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 enables tracepoint for ARM.

- Fast tracepoint.
  A fast tracepoint can be set in thumb and arm mode code.
  Validation is done for the instruction to relocate. Currently
  all PC-relative instructions are not possible to relocate.
  The inserted branch instruction needs to be 4 bytes, which also
  limit the possible instructions to relocate in thumb mode.
  It should be possible to rewrite some instructions, so more
  instructions are relocatable.

- Breakpoint based tracepoint does not work
  This needs new infrastructure in gdbserver for setting breakpoints
  and to step over an instruction. The infrastructure to be able to
  do this is currently only available in gdb.
  There is no added error check for this.

- jit compilation of tracepoint expressions is not implemented.

gdb/ChangeLog:

	* arm-tdep.c (arm_gdbarch_init) : Install fast tracepoint
	callbacks.

gdb/gdbserver/ChangeLog:

	* linux-arm-low.c (arm_get_thread_area) : New function.
	(arm_get_min_fast_tracepoint_insn_len) : New function.
	(arm_supports_tracepoints) : New function.
	(struct linux_target_ops) : Add fast tracepoint callbacks.

Signed-off-by: Henrik Wallin <henrik.wallin@windriver.com>
---
 gdb/arm-tdep.c                |  5 +++++
 gdb/gdbserver/linux-arm-low.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)
  

Patch

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 74c58eb91c4d..1c34d1a4715b 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -11156,6 +11156,11 @@  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     user_reg_add (gdbarch, arm_register_aliases[i].name,
 		  value_of_arm_user_reg, &arm_register_aliases[i].regnum);
 
+  set_gdbarch_fast_tracepoint_valid_at (gdbarch,
+					arm_fast_tracepoint_valid_at);
+
+  set_gdbarch_relocate_instruction (gdbarch, arm_relocate_instruction);
+
   return gdbarch;
 }
 
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index 6bb069fe71bb..c3f85960bb28 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -918,6 +918,30 @@  arm_regs_info (void)
 }
 
 static int
+arm_get_thread_area (int lwpid, CORE_ADDR *addr)
+{
+  uint32_t val;
+
+  if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, &val) != 0)
+    return -1;
+
+  *addr = val;
+  return 0;
+}
+
+static int
+arm_get_min_fast_tracepoint_insn_len(void)
+{
+  return 4;
+}
+
+static int
+arm_supports_tracepoints(void)
+{
+  return 1;
+}
+
+static int
 is_target_arm (CORE_ADDR to, CORE_ADDR from)
 {
   CORE_ADDR ptr = to;
@@ -1324,6 +1348,12 @@  struct linux_target_ops the_low_target = {
   arm_new_thread,
   arm_new_fork,
   arm_prepare_to_resume,
+  NULL,                         /* process_qsupported */
+  arm_supports_tracepoints,     /* supports_tracepoints */
+  arm_get_thread_area,          /* get_thread_area */
+  arm_install_fast_tracepoint_jump_pad, /* install_fast_tracepoint_jump_pad */
+  NULL,                         /* emit_ops */
+  arm_get_min_fast_tracepoint_insn_len, /* get_min_fast_tracepoint_insn_len */
 };
 
 void