Blame SOURCES/gdb-rhbz1247107-backport-aarch64-stap-sdt-support-2of2.patch

7b26da
commit 08248ca9fe11040e9a4126cefebc5023d1d67222
7b26da
Author: Sergio Durigan Junior <sergiodj@redhat.com>
7b26da
Date:   Sat Dec 28 14:14:11 2013 -0200
7b26da
7b26da
    Implement SystemTap SDT probe support for AArch64
7b26da
    
7b26da
    This commit implements the needed bits for SystemTap SDT probe support
7b26da
    on AArch64 architectures.
7b26da
    
7b26da
    First, I started by looking at AArch64 assembly specification and
7b26da
    filling the necessary options on gdbarch's stap machinery in order to
7b26da
    make the generic asm parser (implemented in stap-probe.c) recognize
7b26da
    AArch64's asm.
7b26da
    
7b26da
    After my last patch for the SystemTap SDT API, which extends it in order
7b26da
    to accept multiple prefixes and suffixes, this patch became simpler.  I
7b26da
    also followed Marcus suggestion and did not shared code between 32- and
7b26da
    64-bit ARM.
7b26da
    
7b26da
    Tom asked me in a previous message how I did my tests.  I believe I
7b26da
    replied that, but just in case: I ran the tests on
7b26da
    gdb.base/stap-probe.exp by hand.  I also managed to run the tests on
7b26da
    real hardware, and they pass without regressions.
7b26da
    
7b26da
    2013-12-28  Sergio Durigan Junior  <sergiodj@redhat.com>
7b26da
    
7b26da
    	PR tdep/15653
7b26da
    	* NEWS: Mention SystemTap SDT probe support for AArch64 GNU/Linux.
7b26da
    	* aarch64-linux-tdep.c: Include necessary headers for parsing of
7b26da
    	SystemTap SDT probes.
7b26da
    	(aarch64_stap_is_single_operand): New function.
7b26da
    	(aarch64_stap_parse_special_token): Likewise.
7b26da
    	(aarch64_linux_init_abi): Declare SystemTap SDT probe argument
7b26da
    	prefixes and suffixes.  Initialize gdbarch with them.
7b26da
7b26da
Index: gdb-7.6.1/gdb/NEWS
7b26da
===================================================================
7b26da
--- gdb-7.6.1.orig/gdb/NEWS
7b26da
+++ gdb-7.6.1/gdb/NEWS
7b26da
@@ -30,6 +30,8 @@ qXfer:libraries-svr4:read's annex
7b26da
 
7b26da
 *** Changes in GDB 7.6
7b26da
 
7b26da
+* GDB now supports SystemTap SDT probes on AArch64 GNU/Linux.
7b26da
+
7b26da
 * Target record has been renamed to record-full.
7b26da
   Record/replay is now enabled with the "record full" command.
7b26da
   This also affects settings that are associated with full record/replay
7b26da
Index: gdb-7.6.1/gdb/aarch64-linux-tdep.c
7b26da
===================================================================
7b26da
--- gdb-7.6.1.orig/gdb/aarch64-linux-tdep.c
7b26da
+++ gdb-7.6.1/gdb/aarch64-linux-tdep.c
7b26da
@@ -35,6 +35,12 @@
7b26da
 #include "regcache.h"
7b26da
 #include "regset.h"
7b26da
 
7b26da
+#include "cli/cli-utils.h"
7b26da
+#include "stap-probe.h"
7b26da
+#include "parser-defs.h"
7b26da
+#include "user-regs.h"
7b26da
+#include <ctype.h>
7b26da
+
7b26da
 /* The general-purpose regset consists of 31 X registers, plus SP, PC,
7b26da
    and PSTATE registers, as defined in the AArch64 port of the Linux
7b26da
    kernel.  */
7b26da
@@ -268,9 +274,129 @@ aarch64_linux_regset_from_core_section (
7b26da
   return NULL;
7b26da
 }
7b26da
 
7b26da
+/* Implementation of `gdbarch_stap_is_single_operand', as defined in
7b26da
+   gdbarch.h.  */
7b26da
+
7b26da
+static int
7b26da
+aarch64_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
7b26da
+{
7b26da
+  return (*s == '#' || isdigit (*s) /* Literal number.  */
7b26da
+	  || *s == '[' /* Register indirection.  */
7b26da
+	  || isalpha (*s)); /* Register value.  */
7b26da
+}
7b26da
+
7b26da
+/* This routine is used to parse a special token in AArch64's assembly.
7b26da
+
7b26da
+   The special tokens parsed by it are:
7b26da
+
7b26da
+      - Register displacement (e.g, [fp, #-8])
7b26da
+
7b26da
+   It returns one if the special token has been parsed successfully,
7b26da
+   or zero if the current token is not considered special.  */
7b26da
+
7b26da
+static int
7b26da
+aarch64_stap_parse_special_token (struct gdbarch *gdbarch,
7b26da
+				  struct stap_parse_info *p)
7b26da
+{
7b26da
+  if (*p->arg == '[')
7b26da
+    {
7b26da
+      /* Temporary holder for lookahead.  */
7b26da
+      const char *tmp = p->arg;
7b26da
+      char *endp;
7b26da
+      /* Used to save the register name.  */
7b26da
+      const char *start;
7b26da
+      char *regname;
7b26da
+      int len;
7b26da
+      int got_minus = 0;
7b26da
+      long displacement;
7b26da
+      struct stoken str;
7b26da
+
7b26da
+      ++tmp;
7b26da
+      start = tmp;
7b26da
+
7b26da
+      /* Register name.  */
7b26da
+      while (isalnum (*tmp))
7b26da
+	++tmp;
7b26da
+
7b26da
+      if (*tmp != ',')
7b26da
+	return 0;
7b26da
+
7b26da
+      len = tmp - start;
7b26da
+      regname = alloca (len + 2);
7b26da
+
7b26da
+      strncpy (regname, start, len);
7b26da
+      regname[len] = '\0';
7b26da
+
7b26da
+      if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
7b26da
+	error (_("Invalid register name `%s' on expression `%s'."),
7b26da
+	       regname, p->saved_arg);
7b26da
+
7b26da
+      ++tmp;
7b26da
+      tmp = skip_spaces_const (tmp);
7b26da
+      /* Now we expect a number.  It can begin with '#' or simply
7b26da
+	 a digit.  */
7b26da
+      if (*tmp == '#')
7b26da
+	++tmp;
7b26da
+
7b26da
+      if (*tmp == '-')
7b26da
+	{
7b26da
+	  ++tmp;
7b26da
+	  got_minus = 1;
7b26da
+	}
7b26da
+      else if (*tmp == '+')
7b26da
+	++tmp;
7b26da
+
7b26da
+      if (!isdigit (*tmp))
7b26da
+	return 0;
7b26da
+
7b26da
+      displacement = strtol (tmp, &endp, 10);
7b26da
+      tmp = endp;
7b26da
+
7b26da
+      /* Skipping last `]'.  */
7b26da
+      if (*tmp++ != ']')
7b26da
+	return 0;
7b26da
+
7b26da
+      /* The displacement.  */
7b26da
+      write_exp_elt_opcode (OP_LONG);
7b26da
+      write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
7b26da
+      write_exp_elt_longcst (displacement);
7b26da
+      write_exp_elt_opcode (OP_LONG);
7b26da
+      if (got_minus)
7b26da
+	write_exp_elt_opcode (UNOP_NEG);
7b26da
+
7b26da
+      /* The register name.  */
7b26da
+      write_exp_elt_opcode (OP_REGISTER);
7b26da
+      str.ptr = regname;
7b26da
+      str.length = len;
7b26da
+      write_exp_string (str);
7b26da
+      write_exp_elt_opcode (OP_REGISTER);
7b26da
+
7b26da
+      write_exp_elt_opcode (BINOP_ADD);
7b26da
+
7b26da
+      /* Casting to the expected type.  */
7b26da
+      write_exp_elt_opcode (UNOP_CAST);
7b26da
+      write_exp_elt_type (lookup_pointer_type (p->arg_type));
7b26da
+      write_exp_elt_opcode (UNOP_CAST);
7b26da
+
7b26da
+      write_exp_elt_opcode (UNOP_IND);
7b26da
+
7b26da
+      p->arg = tmp;
7b26da
+    }
7b26da
+  else
7b26da
+    return 0;
7b26da
+
7b26da
+  return 1;
7b26da
+}
7b26da
+
7b26da
 static void
7b26da
 aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
7b26da
 {
7b26da
+  static const char *const stap_integer_prefixes[] = { "#", "", NULL };
7b26da
+  static const char *const stap_register_prefixes[] = { "", NULL };
7b26da
+  static const char *const stap_register_indirection_prefixes[] = { "[",
7b26da
+								    NULL };
7b26da
+  static const char *const stap_register_indirection_suffixes[] = { "]",
7b26da
+								    NULL };
7b26da
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
7b26da
 
7b26da
   tdep->lowest_pc = 0x8000;
7b26da
@@ -295,6 +421,17 @@ aarch64_linux_init_abi (struct gdbarch_i
7b26da
 
7b26da
   set_gdbarch_regset_from_core_section (gdbarch,
7b26da
 					aarch64_linux_regset_from_core_section);
7b26da
+
7b26da
+  /* SystemTap related.  */
7b26da
+  set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes);
7b26da
+  set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
7b26da
+  set_gdbarch_stap_register_indirection_prefixes (gdbarch,
7b26da
+					    stap_register_indirection_prefixes);
7b26da
+  set_gdbarch_stap_register_indirection_suffixes (gdbarch,
7b26da
+					    stap_register_indirection_suffixes);
7b26da
+  set_gdbarch_stap_is_single_operand (gdbarch, aarch64_stap_is_single_operand);
7b26da
+  set_gdbarch_stap_parse_special_token (gdbarch,
7b26da
+					aarch64_stap_parse_special_token);
7b26da
 }
7b26da
 
7b26da
 /* Provide a prototype to silence -Wmissing-prototypes.  */