This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Split i386_stap_parse_special_token into smaller functions


Hi,

As requested by Joel on:

<https://sourceware.org/ml/gdb-patches/2013-12/msg00977.html>

I am reposting this separate patch whose only purpose is to split
i386_stap_parse_special_token into smaller functions.  I haven't
modified anything logical in the functions, i.e., there's still one
latent bug on i386_stap_parse_special_token_triplet now.  I will soon
post a patch to fix this, and to also improve the readability of the two
new functions.

I am also posting the output of "git diff -b" here.

-=-=- git diff -b -=-=-

diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 4f86f0c..1a435c1 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -3605,40 +3605,20 @@ i386_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
 	  || (*s == '%' && isalpha (s[1]))); /* Register access.  */
 }
 
-/* Implementation of `gdbarch_stap_parse_special_token', as defined in
-   gdbarch.h.  */
-
-int
-i386_stap_parse_special_token (struct gdbarch *gdbarch,
-			       struct stap_parse_info *p)
-{
-  /* In order to parse special tokens, we use a state-machine that go
-     through every known token and try to get a match.  */
-  enum
-    {
-      TRIPLET,
-      THREE_ARG_DISPLACEMENT,
-      DONE
-    } current_state;
-
-  current_state = TRIPLET;
+/* Helper function for i386_stap_parse_special_token.
 
-  /* The special tokens to be parsed here are:
-
-     - `register base + (register index * size) + offset', as represented
-     in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
+   This function parses operands of the form `-8+3+1(%rbp)', which
+   must be interpreted as `*(-8 + 3 - 1 + (void *) $eax)'.
 
-     - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
-     `*(-8 + 3 - 1 + (void *) $eax)'.  */
+   Return 1 if the operand was parsed successfully, zero
+   otherwise.  */
 
-  while (current_state != DONE)
-    {
+static int
+i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
+				       struct stap_parse_info *p)
+{
   const char *s = p->arg;
 
-      switch (current_state)
-	{
-	case TRIPLET:
-	    {
   if (isdigit (*s) || *s == '-' || *s == '+')
     {
       int got_minus[3];
@@ -3665,7 +3645,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
       if (*s != '+' && *s != '-')
 	{
 	  /* We are not dealing with a triplet.  */
-		      break;
+	  return 0;
 	}
 
       got_minus[1] = 0;
@@ -3683,7 +3663,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
       if (*s != '+' && *s != '-')
 	{
 	  /* We are not dealing with a triplet.  */
-		      break;
+	  return 0;
 	}
 
       got_minus[2] = 0;
@@ -3699,7 +3679,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
       s = endp;
 
       if (*s != '(' || s[1] != '%')
-		    break;
+	return 0;
 
       s += 2;
       start = s;
@@ -3708,7 +3688,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
 	++s;
 
       if (*s++ != ')')
-		    break;
+	return 0;
 
       len = s - start;
       regname = alloca (len + 1);
@@ -3716,17 +3696,14 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
       strncpy (regname, start, len);
       regname[len] = '\0';
 
-		  if (user_reg_map_name_to_regnum (gdbarch,
-						   regname, len) == -1)
-		    error (_("Invalid register name `%s' "
-			     "on expression `%s'."),
+      if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
+	error (_("Invalid register name `%s' on expression `%s'."),
 	       regname, p->saved_arg);
 
       for (i = 0; i < 3; i++)
 	{
 	  write_exp_elt_opcode (OP_LONG);
-		      write_exp_elt_type
-			(builtin_type (gdbarch)->builtin_long);
+	  write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
 	  write_exp_elt_longcst (displacements[i]);
 	  write_exp_elt_opcode (OP_LONG);
 	  if (got_minus[i])
@@ -3757,10 +3734,25 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
 
       return 1;
     }
-	      break;
-	    }
-	case THREE_ARG_DISPLACEMENT:
-	    {
+
+  return 0;
+}
+
+/* Helper function for i386_stap_parse_special_token.
+
+   This function parses operands of the form `register base +
+   (register index * size) + offset', as represented in
+   `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
+
+   Return 1 if the operand was parsed successfully, zero
+   otherwise.  */
+
+static int
+i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
+					      struct stap_parse_info *p)
+{
+  const char *s = p->arg;
+
   if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
     {
       int offset_minus = 0;
@@ -3783,7 +3775,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
 	}
 
       if (offset_minus && !isdigit (*s))
-		    break;
+	return 0;
 
       if (isdigit (*s))
 	{
@@ -3794,7 +3786,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
 	}
 
       if (*s != '(' || s[1] != '%')
-		    break;
+	return 0;
 
       s += 2;
       start = s;
@@ -3803,17 +3795,15 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
 	++s;
 
       if (*s != ',' || s[1] != '%')
-		    break;
+	return 0;
 
       len_base = s - start;
       base = alloca (len_base + 1);
       strncpy (base, start, len_base);
       base[len_base] = '\0';
 
-		  if (user_reg_map_name_to_regnum (gdbarch,
-						   base, len_base) == -1)
-		    error (_("Invalid register name `%s' "
-			     "on expression `%s'."),
+      if (user_reg_map_name_to_regnum (gdbarch, base, len_base) == -1)
+	error (_("Invalid register name `%s' on expression `%s'."),
 	       base, p->saved_arg);
 
       s += 2;
@@ -3827,14 +3817,12 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
       strncpy (index, start, len_index);
       index[len_index] = '\0';
 
-		  if (user_reg_map_name_to_regnum (gdbarch,
-						   index, len_index) == -1)
-		    error (_("Invalid register name `%s' "
-			     "on expression `%s'."),
+      if (user_reg_map_name_to_regnum (gdbarch, index, len_index) == -1)
+	error (_("Invalid register name `%s' on expression `%s'."),
 	       index, p->saved_arg);
 
       if (*s != ',' && *s != ')')
-		    break;
+	return 0;
 
       if (*s == ',')
 	{
@@ -3853,7 +3841,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
 	  s = endp;
 
 	  if (*s != ')')
-			break;
+	    return 0;
 	}
 
       ++s;
@@ -3861,8 +3849,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
       if (offset)
 	{
 	  write_exp_elt_opcode (OP_LONG);
-		      write_exp_elt_type
-			(builtin_type (gdbarch)->builtin_long);
+	  write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
 	  write_exp_elt_longcst (offset);
 	  write_exp_elt_opcode (OP_LONG);
 	  if (offset_minus)
@@ -3887,8 +3874,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
       if (size)
 	{
 	  write_exp_elt_opcode (OP_LONG);
-		      write_exp_elt_type
-			(builtin_type (gdbarch)->builtin_long);
+	  write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
 	  write_exp_elt_longcst (size);
 	  write_exp_elt_opcode (OP_LONG);
 	  if (size_minus)
@@ -3908,8 +3894,49 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
 
       return 1;
     }
+
+  return 0;
+}
+
+/* Implementation of `gdbarch_stap_parse_special_token', as defined in
+   gdbarch.h.  */
+
+int
+i386_stap_parse_special_token (struct gdbarch *gdbarch,
+			       struct stap_parse_info *p)
+{
+  /* In order to parse special tokens, we use a state-machine that go
+     through every known token and try to get a match.  */
+  enum
+    {
+      TRIPLET,
+      THREE_ARG_DISPLACEMENT,
+      DONE
+    } current_state;
+
+  current_state = TRIPLET;
+
+  /* The special tokens to be parsed here are:
+
+     - `register base + (register index * size) + offset', as represented
+     in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
+
+     - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
+     `*(-8 + 3 - 1 + (void *) $eax)'.  */
+
+  while (current_state != DONE)
+    {
+      switch (current_state)
+	{
+	case TRIPLET:
+	  if (i386_stap_parse_special_token_triplet (gdbarch, p))
+	    return 1;
+	  break;
+
+	case THREE_ARG_DISPLACEMENT:
+	  if (i386_stap_parse_special_token_three_arg_disp (gdbarch, p))
+	    return 1;
 	  break;
-	    }
 	}
 
       /* Advancing to the next state.  */

-=-=- git diff -b -=-=-

I tested this on Fedora 18 x86_64, everything is OK.

OK to apply?

-- 
Sergio

2013-12-29  Sergio Durigan Junior  <sergiodj@redhat.com>

	* i386-tdep.c (i386_stap_parse_special_token_triplet): New
	function, with code from i386_stap_parse_special_token.
	(i386_stap_parse_special_token_three_arg_disp): Likewise.
	(i386_stap_parse_special_token): Move code to the two functions
	above; simplify it.

diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 4f86f0c..1a435c1 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -3605,311 +3605,338 @@ i386_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
 	  || (*s == '%' && isalpha (s[1]))); /* Register access.  */
 }
 
-/* Implementation of `gdbarch_stap_parse_special_token', as defined in
-   gdbarch.h.  */
+/* Helper function for i386_stap_parse_special_token.
 
-int
-i386_stap_parse_special_token (struct gdbarch *gdbarch,
-			       struct stap_parse_info *p)
+   This function parses operands of the form `-8+3+1(%rbp)', which
+   must be interpreted as `*(-8 + 3 - 1 + (void *) $eax)'.
+
+   Return 1 if the operand was parsed successfully, zero
+   otherwise.  */
+
+static int
+i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
+				       struct stap_parse_info *p)
 {
-  /* In order to parse special tokens, we use a state-machine that go
-     through every known token and try to get a match.  */
-  enum
+  const char *s = p->arg;
+
+  if (isdigit (*s) || *s == '-' || *s == '+')
     {
-      TRIPLET,
-      THREE_ARG_DISPLACEMENT,
-      DONE
-    } current_state;
+      int got_minus[3];
+      int i;
+      long displacements[3];
+      const char *start;
+      char *regname;
+      int len;
+      struct stoken str;
+      char *endp;
+
+      got_minus[0] = 0;
+      if (*s == '+')
+	++s;
+      else if (*s == '-')
+	{
+	  ++s;
+	  got_minus[0] = 1;
+	}
 
-  current_state = TRIPLET;
+      displacements[0] = strtol (s, &endp, 10);
+      s = endp;
 
-  /* The special tokens to be parsed here are:
+      if (*s != '+' && *s != '-')
+	{
+	  /* We are not dealing with a triplet.  */
+	  return 0;
+	}
 
-     - `register base + (register index * size) + offset', as represented
-     in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
+      got_minus[1] = 0;
+      if (*s == '+')
+	++s;
+      else
+	{
+	  ++s;
+	  got_minus[1] = 1;
+	}
 
-     - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
-     `*(-8 + 3 - 1 + (void *) $eax)'.  */
+      displacements[1] = strtol (s, &endp, 10);
+      s = endp;
 
-  while (current_state != DONE)
-    {
-      const char *s = p->arg;
+      if (*s != '+' && *s != '-')
+	{
+	  /* We are not dealing with a triplet.  */
+	  return 0;
+	}
 
-      switch (current_state)
+      got_minus[2] = 0;
+      if (*s == '+')
+	++s;
+      else
 	{
-	case TRIPLET:
-	    {
-	      if (isdigit (*s) || *s == '-' || *s == '+')
-		{
-		  int got_minus[3];
-		  int i;
-		  long displacements[3];
-		  const char *start;
-		  char *regname;
-		  int len;
-		  struct stoken str;
-		  char *endp;
-
-		  got_minus[0] = 0;
-		  if (*s == '+')
-		    ++s;
-		  else if (*s == '-')
-		    {
-		      ++s;
-		      got_minus[0] = 1;
-		    }
+	  ++s;
+	  got_minus[2] = 1;
+	}
 
-		  displacements[0] = strtol (s, &endp, 10);
-		  s = endp;
+      displacements[2] = strtol (s, &endp, 10);
+      s = endp;
 
-		  if (*s != '+' && *s != '-')
-		    {
-		      /* We are not dealing with a triplet.  */
-		      break;
-		    }
+      if (*s != '(' || s[1] != '%')
+	return 0;
 
-		  got_minus[1] = 0;
-		  if (*s == '+')
-		    ++s;
-		  else
-		    {
-		      ++s;
-		      got_minus[1] = 1;
-		    }
+      s += 2;
+      start = s;
 
-		  displacements[1] = strtol (s, &endp, 10);
-		  s = endp;
+      while (isalnum (*s))
+	++s;
 
-		  if (*s != '+' && *s != '-')
-		    {
-		      /* We are not dealing with a triplet.  */
-		      break;
-		    }
+      if (*s++ != ')')
+	return 0;
 
-		  got_minus[2] = 0;
-		  if (*s == '+')
-		    ++s;
-		  else
-		    {
-		      ++s;
-		      got_minus[2] = 1;
-		    }
+      len = s - start;
+      regname = alloca (len + 1);
 
-		  displacements[2] = strtol (s, &endp, 10);
-		  s = endp;
+      strncpy (regname, start, len);
+      regname[len] = '\0';
 
-		  if (*s != '(' || s[1] != '%')
-		    break;
+      if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
+	error (_("Invalid register name `%s' on expression `%s'."),
+	       regname, p->saved_arg);
 
-		  s += 2;
-		  start = s;
+      for (i = 0; i < 3; i++)
+	{
+	  write_exp_elt_opcode (OP_LONG);
+	  write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
+	  write_exp_elt_longcst (displacements[i]);
+	  write_exp_elt_opcode (OP_LONG);
+	  if (got_minus[i])
+	    write_exp_elt_opcode (UNOP_NEG);
+	}
 
-		  while (isalnum (*s))
-		    ++s;
+      write_exp_elt_opcode (OP_REGISTER);
+      str.ptr = regname;
+      str.length = len;
+      write_exp_string (str);
+      write_exp_elt_opcode (OP_REGISTER);
 
-		  if (*s++ != ')')
-		    break;
+      write_exp_elt_opcode (UNOP_CAST);
+      write_exp_elt_type (builtin_type (gdbarch)->builtin_data_ptr);
+      write_exp_elt_opcode (UNOP_CAST);
 
-		  len = s - start;
-		  regname = alloca (len + 1);
+      write_exp_elt_opcode (BINOP_ADD);
+      write_exp_elt_opcode (BINOP_ADD);
+      write_exp_elt_opcode (BINOP_ADD);
 
-		  strncpy (regname, start, len);
-		  regname[len] = '\0';
+      write_exp_elt_opcode (UNOP_CAST);
+      write_exp_elt_type (lookup_pointer_type (p->arg_type));
+      write_exp_elt_opcode (UNOP_CAST);
 
-		  if (user_reg_map_name_to_regnum (gdbarch,
-						   regname, len) == -1)
-		    error (_("Invalid register name `%s' "
-			     "on expression `%s'."),
-			   regname, p->saved_arg);
+      write_exp_elt_opcode (UNOP_IND);
 
-		  for (i = 0; i < 3; i++)
-		    {
-		      write_exp_elt_opcode (OP_LONG);
-		      write_exp_elt_type
-			(builtin_type (gdbarch)->builtin_long);
-		      write_exp_elt_longcst (displacements[i]);
-		      write_exp_elt_opcode (OP_LONG);
-		      if (got_minus[i])
-			write_exp_elt_opcode (UNOP_NEG);
-		    }
+      p->arg = s;
 
-		  write_exp_elt_opcode (OP_REGISTER);
-		  str.ptr = regname;
-		  str.length = len;
-		  write_exp_string (str);
-		  write_exp_elt_opcode (OP_REGISTER);
+      return 1;
+    }
 
-		  write_exp_elt_opcode (UNOP_CAST);
-		  write_exp_elt_type (builtin_type (gdbarch)->builtin_data_ptr);
-		  write_exp_elt_opcode (UNOP_CAST);
+  return 0;
+}
 
-		  write_exp_elt_opcode (BINOP_ADD);
-		  write_exp_elt_opcode (BINOP_ADD);
-		  write_exp_elt_opcode (BINOP_ADD);
+/* Helper function for i386_stap_parse_special_token.
 
-		  write_exp_elt_opcode (UNOP_CAST);
-		  write_exp_elt_type (lookup_pointer_type (p->arg_type));
-		  write_exp_elt_opcode (UNOP_CAST);
+   This function parses operands of the form `register base +
+   (register index * size) + offset', as represented in
+   `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
 
-		  write_exp_elt_opcode (UNOP_IND);
+   Return 1 if the operand was parsed successfully, zero
+   otherwise.  */
 
-		  p->arg = s;
+static int
+i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
+					      struct stap_parse_info *p)
+{
+  const char *s = p->arg;
 
-		  return 1;
-		}
-	      break;
-	    }
-	case THREE_ARG_DISPLACEMENT:
-	    {
-	      if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
-		{
-		  int offset_minus = 0;
-		  long offset = 0;
-		  int size_minus = 0;
-		  long size = 0;
-		  const char *start;
-		  char *base;
-		  int len_base;
-		  char *index;
-		  int len_index;
-		  struct stoken base_token, index_token;
-
-		  if (*s == '+')
-		    ++s;
-		  else if (*s == '-')
-		    {
-		      ++s;
-		      offset_minus = 1;
-		    }
+  if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
+    {
+      int offset_minus = 0;
+      long offset = 0;
+      int size_minus = 0;
+      long size = 0;
+      const char *start;
+      char *base;
+      int len_base;
+      char *index;
+      int len_index;
+      struct stoken base_token, index_token;
+
+      if (*s == '+')
+	++s;
+      else if (*s == '-')
+	{
+	  ++s;
+	  offset_minus = 1;
+	}
 
-		  if (offset_minus && !isdigit (*s))
-		    break;
+      if (offset_minus && !isdigit (*s))
+	return 0;
 
-		  if (isdigit (*s))
-		    {
-		      char *endp;
+      if (isdigit (*s))
+	{
+	  char *endp;
 
-		      offset = strtol (s, &endp, 10);
-		      s = endp;
-		    }
+	  offset = strtol (s, &endp, 10);
+	  s = endp;
+	}
 
-		  if (*s != '(' || s[1] != '%')
-		    break;
+      if (*s != '(' || s[1] != '%')
+	return 0;
 
-		  s += 2;
-		  start = s;
+      s += 2;
+      start = s;
 
-		  while (isalnum (*s))
-		    ++s;
+      while (isalnum (*s))
+	++s;
 
-		  if (*s != ',' || s[1] != '%')
-		    break;
+      if (*s != ',' || s[1] != '%')
+	return 0;
 
-		  len_base = s - start;
-		  base = alloca (len_base + 1);
-		  strncpy (base, start, len_base);
-		  base[len_base] = '\0';
+      len_base = s - start;
+      base = alloca (len_base + 1);
+      strncpy (base, start, len_base);
+      base[len_base] = '\0';
 
-		  if (user_reg_map_name_to_regnum (gdbarch,
-						   base, len_base) == -1)
-		    error (_("Invalid register name `%s' "
-			     "on expression `%s'."),
-			   base, p->saved_arg);
+      if (user_reg_map_name_to_regnum (gdbarch, base, len_base) == -1)
+	error (_("Invalid register name `%s' on expression `%s'."),
+	       base, p->saved_arg);
 
-		  s += 2;
-		  start = s;
+      s += 2;
+      start = s;
 
-		  while (isalnum (*s))
-		    ++s;
+      while (isalnum (*s))
+	++s;
 
-		  len_index = s - start;
-		  index = alloca (len_index + 1);
-		  strncpy (index, start, len_index);
-		  index[len_index] = '\0';
+      len_index = s - start;
+      index = alloca (len_index + 1);
+      strncpy (index, start, len_index);
+      index[len_index] = '\0';
 
-		  if (user_reg_map_name_to_regnum (gdbarch,
-						   index, len_index) == -1)
-		    error (_("Invalid register name `%s' "
-			     "on expression `%s'."),
-			   index, p->saved_arg);
+      if (user_reg_map_name_to_regnum (gdbarch, index, len_index) == -1)
+	error (_("Invalid register name `%s' on expression `%s'."),
+	       index, p->saved_arg);
 
-		  if (*s != ',' && *s != ')')
-		    break;
+      if (*s != ',' && *s != ')')
+	return 0;
 
-		  if (*s == ',')
-		    {
-		      char *endp;
+      if (*s == ',')
+	{
+	  char *endp;
 
-		      ++s;
-		      if (*s == '+')
-			++s;
-		      else if (*s == '-')
-			{
-			  ++s;
-			  size_minus = 1;
-			}
+	  ++s;
+	  if (*s == '+')
+	    ++s;
+	  else if (*s == '-')
+	    {
+	      ++s;
+	      size_minus = 1;
+	    }
 
-		      size = strtol (s, &endp, 10);
-		      s = endp;
+	  size = strtol (s, &endp, 10);
+	  s = endp;
 
-		      if (*s != ')')
-			break;
-		    }
+	  if (*s != ')')
+	    return 0;
+	}
 
-		  ++s;
+      ++s;
 
-		  if (offset)
-		    {
-		      write_exp_elt_opcode (OP_LONG);
-		      write_exp_elt_type
-			(builtin_type (gdbarch)->builtin_long);
-		      write_exp_elt_longcst (offset);
-		      write_exp_elt_opcode (OP_LONG);
-		      if (offset_minus)
-			write_exp_elt_opcode (UNOP_NEG);
-		    }
+      if (offset)
+	{
+	  write_exp_elt_opcode (OP_LONG);
+	  write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
+	  write_exp_elt_longcst (offset);
+	  write_exp_elt_opcode (OP_LONG);
+	  if (offset_minus)
+	    write_exp_elt_opcode (UNOP_NEG);
+	}
 
-		  write_exp_elt_opcode (OP_REGISTER);
-		  base_token.ptr = base;
-		  base_token.length = len_base;
-		  write_exp_string (base_token);
-		  write_exp_elt_opcode (OP_REGISTER);
+      write_exp_elt_opcode (OP_REGISTER);
+      base_token.ptr = base;
+      base_token.length = len_base;
+      write_exp_string (base_token);
+      write_exp_elt_opcode (OP_REGISTER);
 
-		  if (offset)
-		    write_exp_elt_opcode (BINOP_ADD);
+      if (offset)
+	write_exp_elt_opcode (BINOP_ADD);
 
-		  write_exp_elt_opcode (OP_REGISTER);
-		  index_token.ptr = index;
-		  index_token.length = len_index;
-		  write_exp_string (index_token);
-		  write_exp_elt_opcode (OP_REGISTER);
+      write_exp_elt_opcode (OP_REGISTER);
+      index_token.ptr = index;
+      index_token.length = len_index;
+      write_exp_string (index_token);
+      write_exp_elt_opcode (OP_REGISTER);
 
-		  if (size)
-		    {
-		      write_exp_elt_opcode (OP_LONG);
-		      write_exp_elt_type
-			(builtin_type (gdbarch)->builtin_long);
-		      write_exp_elt_longcst (size);
-		      write_exp_elt_opcode (OP_LONG);
-		      if (size_minus)
-			write_exp_elt_opcode (UNOP_NEG);
-		      write_exp_elt_opcode (BINOP_MUL);
-		    }
+      if (size)
+	{
+	  write_exp_elt_opcode (OP_LONG);
+	  write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
+	  write_exp_elt_longcst (size);
+	  write_exp_elt_opcode (OP_LONG);
+	  if (size_minus)
+	    write_exp_elt_opcode (UNOP_NEG);
+	  write_exp_elt_opcode (BINOP_MUL);
+	}
 
-		  write_exp_elt_opcode (BINOP_ADD);
+      write_exp_elt_opcode (BINOP_ADD);
 
-		  write_exp_elt_opcode (UNOP_CAST);
-		  write_exp_elt_type (lookup_pointer_type (p->arg_type));
-		  write_exp_elt_opcode (UNOP_CAST);
+      write_exp_elt_opcode (UNOP_CAST);
+      write_exp_elt_type (lookup_pointer_type (p->arg_type));
+      write_exp_elt_opcode (UNOP_CAST);
 
-		  write_exp_elt_opcode (UNOP_IND);
+      write_exp_elt_opcode (UNOP_IND);
 
-		  p->arg = s;
+      p->arg = s;
 
-		  return 1;
-		}
-	      break;
-	    }
+      return 1;
+    }
+
+  return 0;
+}
+
+/* Implementation of `gdbarch_stap_parse_special_token', as defined in
+   gdbarch.h.  */
+
+int
+i386_stap_parse_special_token (struct gdbarch *gdbarch,
+			       struct stap_parse_info *p)
+{
+  /* In order to parse special tokens, we use a state-machine that go
+     through every known token and try to get a match.  */
+  enum
+    {
+      TRIPLET,
+      THREE_ARG_DISPLACEMENT,
+      DONE
+    } current_state;
+
+  current_state = TRIPLET;
+
+  /* The special tokens to be parsed here are:
+
+     - `register base + (register index * size) + offset', as represented
+     in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
+
+     - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
+     `*(-8 + 3 - 1 + (void *) $eax)'.  */
+
+  while (current_state != DONE)
+    {
+      switch (current_state)
+	{
+	case TRIPLET:
+	  if (i386_stap_parse_special_token_triplet (gdbarch, p))
+	    return 1;
+	  break;
+
+	case THREE_ARG_DISPLACEMENT:
+	  if (i386_stap_parse_special_token_three_arg_disp (gdbarch, p))
+	    return 1;
+	  break;
 	}
 
       /* Advancing to the next state.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]