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]

Re: [PATCH] Split i386_stap_parse_special_token into smaller functions


> 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.

Thank you, Sergio. This patch is missing a ChangeLog :).

FWIW, this patch looks good to me, and it is IMO a nice improvement
over the current state. But i386-tdep.c is usually under Mark's
responsibility, so let's give him a little bit of time to reply
as well.

> 
> -=-=- 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.  */

-- 
Joel


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