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

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