/* SystemTap probe support for GDB.

   Copyright (C) 2012 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "stap-probe.h"
#include "probe.h"
#include "vec.h"
#include "ui-out.h"
#include "objfiles.h"
#include "arch-utils.h"
#include "command.h"
#include "gdbcmd.h"
#include "filenames.h"
#include "value.h"
#include "exceptions.h"
#include "ax.h"
#include "ax-gdb.h"
#include "complaints.h"
#include "cli/cli-utils.h"
#include "linespec.h"
#include "user-regs.h"
#include "parser-defs.h"
#include "language.h"
#include "elf-bfd.h"

#include <ctype.h>

/* The name of the SystemTap section where we will find information about
   the probes.  */

#define STAP_BASE_SECTION_NAME ".stapsdt.base"

/* Forward declaration. */

static const struct probe_ops stap_probe_ops;

/* Should we display debug information for the probe's argument expression
   parsing?  */

static unsigned int stap_expression_debug = 0;

/* The various possibilities of bitness defined for a probe's argument.

   The relationship is:

   - STAP_ARG_BITNESS_UNDEFINED:  The user hasn't specified the bitness.
   - STAP_ARG_BITNESS_32BIT_UNSIGNED:  argument string starts with `4@'.
   - STAP_ARG_BITNESS_32BIT_SIGNED:  argument string starts with `-4@'.
   - STAP_ARG_BITNESS_64BIT_UNSIGNED:  argument string starts with `8@'.
   - STAP_ARG_BITNESS_64BIT_SIGNED:  argument string starts with `-8@'.  */

enum stap_arg_bitness
{
  STAP_ARG_BITNESS_UNDEFINED,
  STAP_ARG_BITNESS_32BIT_UNSIGNED,
  STAP_ARG_BITNESS_32BIT_SIGNED,
  STAP_ARG_BITNESS_64BIT_UNSIGNED,
  STAP_ARG_BITNESS_64BIT_SIGNED,
};

/* The following structure represents a single argument for the probe.  */

struct stap_probe_arg
{
  /* The bitness of this argument.  */
  enum stap_arg_bitness bitness;

  /* The corresponding `struct type *' to the bitness.  */
  struct type *atype;

  /* The argument converted to an internal GDB expression.  */
  struct expression *aexpr;
};

typedef struct stap_probe_arg stap_probe_arg_s;
DEF_VEC_O (stap_probe_arg_s);

struct stap_probe
{
  /* Generic information about the probe.  This shall be the first element
     of this struct, in order to maintain binary compatibility with the
     `struct probe' and be able to fully abstract it.  */
  struct probe p;

  /* If the probe has a semaphore associated, then this is the value of
     it.  */
  CORE_ADDR sem_addr;

  unsigned int args_parsed : 1;
  union
    {
      const char *text;

      /* Information about each argument.  This is an array of `stap_probe_arg',
	 with each entry representing one argument.  */
      VEC (stap_probe_arg_s) *vec;
    }
  args_u;
};

/* When parsing the arguments, we have to establish different precedences
   for the various kinds of asm operators.  This enumeration represents those
   precedences.

   This logic behind this is available at
   <http://sourceware.org/binutils/docs/as/Infix-Ops.html#Infix-Ops>, or using
   the command "info '(as)Infix Ops'".  */

enum stap_operand_prec
{
  /* Lowest precedence, used for non-recognized operands or for the beginning
     of the parsing process.  */
  STAP_OPERAND_PREC_NONE = 0,

  /* Precedence of logical OR.  */
  STAP_OPERAND_PREC_LOGICAL_OR,

  /* Precedence of logical AND.  */
  STAP_OPERAND_PREC_LOGICAL_AND,

  /* Precedence of additive (plus, minus) and comparative (equal, less,
     greater-than, etc) operands.  */
  STAP_OPERAND_PREC_ADD_CMP,

  /* Precedence of bitwise operands (bitwise OR, XOR, bitwise AND,
     logical NOT).  */
  STAP_OPERAND_PREC_BITWISE,

  /* Precedence of multiplicative operands (multiplication, division,
     remainder, left shift and right shift).  */
  STAP_OPERAND_PREC_MUL
};

static void stap_parse_argument_1 (struct stap_parse_info *p, int has_lhs,
				   enum stap_operand_prec prec);

static void stap_parse_argument_conditionally (struct stap_parse_info *p);

/* Returns 1 if *S is an operator, zero otherwise.  */

static int stap_is_operator (const char *op);

static void
show_stapexpressiondebug (struct ui_file *file, int from_tty,
			  struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("SystemTap Probe expression debugging is %s.\n"),
		    value);
}

/* Returns the operator precedence level of OP, or STAP_OPERAND_PREC_NONE
   if the operator code was not recognized.  */

static enum stap_operand_prec
stap_get_operator_prec (enum exp_opcode op)
{
  switch (op)
    {
    case BINOP_LOGICAL_OR:
      return STAP_OPERAND_PREC_LOGICAL_OR;

    case BINOP_LOGICAL_AND:
      return STAP_OPERAND_PREC_LOGICAL_AND;

    case BINOP_ADD:
    case BINOP_SUB:
    case BINOP_EQUAL:
    case BINOP_NOTEQUAL:
    case BINOP_LESS:
    case BINOP_LEQ:
    case BINOP_GTR:
    case BINOP_GEQ:
      return STAP_OPERAND_PREC_ADD_CMP;

    case BINOP_BITWISE_IOR:
    case BINOP_BITWISE_AND:
    case BINOP_BITWISE_XOR:
    case UNOP_LOGICAL_NOT:
      return STAP_OPERAND_PREC_BITWISE;

    case BINOP_MUL:
    case BINOP_DIV:
    case BINOP_REM:
    case BINOP_LSH:
    case BINOP_RSH:
      return STAP_OPERAND_PREC_MUL;

    default:
      return STAP_OPERAND_PREC_NONE;
    }
}

/* Given S, read the operator in it and fills the OP pointer with its code.
   Return 1 on success, zero if the operator was not recognized.  */

static enum exp_opcode
stap_get_opcode (const char **s)
{
  const char c = **s;
  enum exp_opcode op;

  *s += 1;

  switch (c)
    {
    case '*':
      op = BINOP_MUL;
      break;

    case '/':
      op = BINOP_DIV;
      break;

    case '%':
      op = BINOP_REM;
    break;

    case '<':
      op = BINOP_LESS;
      if (**s == '<')
	{
	  *s += 1;
	  op = BINOP_LSH;
	}
      else if (**s == '=')
	{
	  *s += 1;
	  op = BINOP_LEQ;
	}
      else if (**s == '>')
	{
	  *s += 1;
	  op = BINOP_NOTEQUAL;
	}
    break;

    case '>':
      op = BINOP_GTR;
      if (**s == '>')
	{
	  *s += 1;
	  op = BINOP_RSH;
	}
      else if (**s == '=')
	{
	  *s += 1;
	  op = BINOP_GEQ;
	}
    break;

    case '|':
      op = BINOP_BITWISE_IOR;
      if (**s == '|')
	{
	  *s += 1;
	  op = BINOP_LOGICAL_OR;
	}
    break;

    case '&':
      op = BINOP_BITWISE_AND;
      if (**s == '&')
	{
	  *s += 1;
	  op = BINOP_LOGICAL_AND;
	}
    break;

    case '^':
      op = BINOP_BITWISE_XOR;
      break;

    case '!':
      op = UNOP_LOGICAL_NOT;
      break;

    case '+':
      op = BINOP_ADD;
      break;

    case '-':
      op = BINOP_SUB;
      break;

    case '=':
      gdb_assert (**s == '=');
      op = BINOP_EQUAL;
      break;

    default:
      internal_error (__FILE__, __LINE__,
		      _("Invalid opcode in expression `%s' for SystemTap"
			"probe"), *s);
    }

  return op;
}

/* Given the bitness of the argument, represented by B, return the
   corresponding `struct type *'.  */

static struct type *
stap_get_expected_argument_type (struct gdbarch *gdbarch,
				 enum stap_arg_bitness b)
{
  switch (b)
    {
    case STAP_ARG_BITNESS_UNDEFINED:
      if (gdbarch_addr_bit (gdbarch) == 32)
	return builtin_type (gdbarch)->builtin_uint32;
      else
	return builtin_type (gdbarch)->builtin_uint64;

    case STAP_ARG_BITNESS_32BIT_SIGNED:
      return builtin_type (gdbarch)->builtin_int32;

    case STAP_ARG_BITNESS_32BIT_UNSIGNED:
      return builtin_type (gdbarch)->builtin_uint32;

    case STAP_ARG_BITNESS_64BIT_SIGNED:
      return builtin_type (gdbarch)->builtin_int64;

    case STAP_ARG_BITNESS_64BIT_UNSIGNED:
      return builtin_type (gdbarch)->builtin_uint64;

    default:
      internal_error (__FILE__, __LINE__,
		      _("Undefined bitness for probe."));
      break;
    }
}

/* Function responsible for parsing a register operand according to
   SystemTap parlance.  Assuming:

   RP  = register prefix
   RS  = register suffix
   RIP = register indirection prefix
   RIS = register indirection suffix
   
   Then a register operand can be:
   
   [RIP] [RP] REGISTER [RS] [RIS]

   This function takes care of a register's indirection, displacement and
   direct access.  It also takes into consideration the fact that some
   registers are named differently inside and outside GDB, e.g., PPC's
   general-purpose registers are represented by integers in the assembly
   language (e.g., `15' is the 15th general-purpose register), but inside
   GDB they have a prefix (the letter `r') appended.  */

static void
stap_parse_register_operand (struct stap_parse_info *p)
{
  /* Simple flag to indicate whether we have seen a minus signal before
     certain number.  */
  int got_minus = 0;

  /* Flags to indicate whether this register access is being displaced and/or
     indirected.  */
  int disp_p = 0, indirect_p = 0;
  struct gdbarch *gdbarch = p->gdbarch;

  /* Needed to generate the register name as a part of an expression.  */
  struct stoken str;

  /* Variables used to extract the register name from the probe's
     argument.  */
  const char *start;
  char *regname;
  int len;

  /* Prefixes for the parser.  */
  const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch);
  const char *reg_ind_prefix
    = gdbarch_stap_register_indirection_prefix (gdbarch);
  const char *gdb_reg_prefix = gdbarch_stap_gdb_register_prefix (gdbarch);
  int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0;
  int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0;
  int gdb_reg_prefix_len = gdb_reg_prefix ? strlen (gdb_reg_prefix) : 0;

  /* Suffixes for the parser.  */
  const char *reg_suffix = gdbarch_stap_register_suffix (gdbarch);
  const char *reg_ind_suffix
    = gdbarch_stap_register_indirection_suffix (gdbarch);
  const char *gdb_reg_suffix = gdbarch_stap_gdb_register_suffix (gdbarch);
  int reg_suffix_len = reg_suffix ? strlen (reg_suffix) : 0;
  int reg_ind_suffix_len = reg_ind_suffix ? strlen (reg_ind_suffix) : 0;
  int gdb_reg_suffix_len = gdb_reg_suffix ? strlen (gdb_reg_suffix) : 0;

  /* Checking for a displacement argument.  */
  if (*p->arg == '+')
    {
      /* If it's a plus sign, we don't need to do anything, just advance the
	 pointer.  */
      ++p->arg;
    }

  if (*p->arg == '-')
    {
      got_minus = 1;
      ++p->arg;
    }

  if (isdigit (*p->arg))
    {
      /* The value of the displacement.  */
      long displacement;

      disp_p = 1;
      displacement = strtol (p->arg, (char **) &p->arg, 10);

      /* Generating the expression for the displacement.  */
      write_exp_elt_opcode (OP_LONG);
      write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
      write_exp_elt_longcst (displacement);
      write_exp_elt_opcode (OP_LONG);
      if (got_minus)
	write_exp_elt_opcode (UNOP_NEG);
    }

  /* Getting rid of register indirection prefix.  */
  if (reg_ind_prefix
      && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0)
    {
      indirect_p = 1;
      p->arg += reg_ind_prefix_len;
    }

  if (disp_p && !indirect_p)
    error (_("Invalid register displacement syntax on expression `%s'."),
	   p->saved_arg);

  /* Getting rid of register prefix.  */
  if (reg_prefix && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0)
    p->arg += reg_prefix_len;

  /* Now we should have only the register name.  Let's extract it and get
     the associated number.  */
  start = p->arg;

  /* We assume the register name is composed by letters and numbers.  */
  while (isalnum (*p->arg))
    ++p->arg;

  len = p->arg - start;

  regname = alloca (len + gdb_reg_prefix_len + gdb_reg_suffix_len + 1);
  regname[0] = '\0';

  /* We only add the GDB's register prefix/suffix if we are dealing with
     a numeric register.  */
  if (gdb_reg_prefix && isdigit (*start))
    {
      strncpy (regname, gdb_reg_prefix, gdb_reg_prefix_len);
      strncpy (regname + gdb_reg_prefix_len, start, len);

      if (gdb_reg_suffix)
	strncpy (regname + gdb_reg_prefix_len + len,
		 gdb_reg_suffix, gdb_reg_suffix_len);

      len += gdb_reg_prefix_len + gdb_reg_suffix_len;
    }
  else
    strncpy (regname, start, len);

  regname[len] = '\0';

  /* Is this a valid register name?  */
  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 (OP_REGISTER);
  str.ptr = regname;
  str.length = len;
  write_exp_string (str);
  write_exp_elt_opcode (OP_REGISTER);

  if (indirect_p)
    {
      if (disp_p)
	write_exp_elt_opcode (BINOP_ADD);

      /* Casting to the expected type.  */
      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);
    }

  /* Getting rid of the register name suffix.  */
  if (reg_suffix)
    {
      if (strncmp (p->arg, reg_suffix, reg_suffix_len) != 0)
	error (_("Missing register name suffix `%s' on expression `%s'."),
	       reg_suffix, p->saved_arg);

      p->arg += reg_suffix_len;
    }

  /* Getting rid of the register indirection suffix.  */
  if (indirect_p && reg_ind_suffix)
    {
      if (strncmp (p->arg, reg_ind_suffix, reg_ind_suffix_len) != 0)
	error (_("Missing indirection suffix `%s' on expression `%s'."),
	       reg_ind_suffix, p->saved_arg);

      p->arg += reg_ind_suffix_len;
    }
}

/* This function is responsible for parsing a single operand.

   A single operand can be:

      - an unary operation (e.g., `-5', `~2', or even with subexpressions
        like `-(2 + 1)')
      - a register displacement, which will be treated as a register
        operand (e.g., `-4(%eax)' on x86)
      - a numeric constant, or
      - a register operand (see function `stap_parse_register_operand')

   The function also calls special-handling functions to deal with
   unrecognized operands, allowing arch-specific parsers to be
   created.  */

static void
stap_parse_single_operand (struct stap_parse_info *p)
{
  struct gdbarch *gdbarch = p->gdbarch;

  /* Prefixes for the parser.  */
  const char *const_prefix = gdbarch_stap_integer_prefix (gdbarch);
  const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch);
  const char *reg_ind_prefix
    = gdbarch_stap_register_indirection_prefix (gdbarch);
  int const_prefix_len = const_prefix ? strlen (const_prefix) : 0;
  int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0;
  int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0;

  /* Suffixes for the parser.  */
  const char *const_suffix = gdbarch_stap_integer_suffix (gdbarch);
  int const_suffix_len = const_suffix ? strlen (const_suffix) : 0;

  /* We first try to parse this token as a "special token".  */
  if (gdbarch_stap_parse_special_token_p (gdbarch))
    {
      int ret = gdbarch_stap_parse_special_token (gdbarch, p);

      if (ret)
	{
	  /* If the return value of the above function is not zero,
	     it means it successfully parsed the special token.

	     If it is NULL, we try to parse it using our method.  */
	  return;
	}
    }

  if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+')
    {
      char c = *p->arg;
      int number;

      /* We use this variable to do a lookahead.  */
      const char *tmp = p->arg;

      ++tmp;

      /* This is an unary operation.  Here is a list of allowed tokens
	 here:

	 - numeric literal;
	 - number (from register displacement)
	 - subexpression (beginning with `(')

	 We handle the register displacement here, and the other cases
	 recursively.  */
      if (p->inside_paren_p)
	tmp = skip_spaces_const (tmp);

      if (isdigit (*tmp))
	number = strtol (tmp, (char **) &tmp, 10);

      if (!reg_ind_prefix
	  || strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0)
	{
	  /* This is not a displacement.  We skip the operator, and deal
	     with it later.  */
	  ++p->arg;
	  stap_parse_argument_conditionally (p);
	  if (c == '-')
	    write_exp_elt_opcode (UNOP_NEG);
	  else if (c == '~')
	    write_exp_elt_opcode (UNOP_COMPLEMENT);
	}
      else
	{
	  /* If we are here, it means it is a displacement.  The only
	     operations allowed here are `-' and `+'.  */
	  if (c == '~')
	    error (_("Invalid operator `%c' for register displacement "
		     "on expression `%s'."), c, p->saved_arg);

	  stap_parse_register_operand (p);
	}
    }
  else if (isdigit (*p->arg))
    {
      /* A temporary variable, needed for lookahead.  */
      const char *tmp = p->arg;
      long number;

      /* We can be dealing with a numeric constant (if `const_prefix' is
	 NULL), or with a register displacement.  */
      number = strtol (tmp, (char **) &tmp, 10);

      if (p->inside_paren_p)
	tmp = skip_spaces_const (tmp);
      if (!const_prefix && reg_ind_prefix
	  && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0)
	{
	  /* We are dealing with a numeric constant.  */
	  write_exp_elt_opcode (OP_LONG);
	  write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
	  write_exp_elt_longcst (number);
	  write_exp_elt_opcode (OP_LONG);

	  p->arg = tmp;

	  if (const_suffix)
	    {
	      if (strncmp (p->arg, const_suffix, const_suffix_len) == 0)
		p->arg += const_suffix_len;
	      else
		error (_("Invalid constant suffix on expression `%s'."),
		       p->saved_arg);
	    }
	}
      else if (reg_ind_prefix
	       && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) == 0)
	stap_parse_register_operand (p);
      else
	error (_("Unknown numeric token on expression `%s'."),
	       p->saved_arg);
    }
  else if (const_prefix
	   && strncmp (p->arg, const_prefix, const_prefix_len) == 0)
    {
      /* We are dealing with a numeric constant.  */
      long number;

      p->arg += const_prefix_len;
      number = strtol (p->arg, (char **) &p->arg, 10);

      write_exp_elt_opcode (OP_LONG);
      write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
      write_exp_elt_longcst (number);
      write_exp_elt_opcode (OP_LONG);

      if (const_suffix)
	{
	  if (strncmp (p->arg, const_suffix, const_suffix_len) == 0)
	    p->arg += const_suffix_len;
	  else
	    error (_("Invalid constant suffix on expression `%s'."),
		   p->saved_arg);
	}
    }
  else if ((reg_prefix
	    && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0)
	   || (reg_ind_prefix
	       && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0))
    stap_parse_register_operand (p);
  else
    error (_("Operator `%c' not recognized on expression `%s'."),
	   *p->arg, p->saved_arg);
}

/* This function parses an argument conditionally, based on single or
   non-single operands.  A non-single operand would be a parenthesized
   expression (e.g., `(2 + 1)'), and a single operand is anything that
   starts with `-', `~', `+' (i.e., unary operators), a digit, or
   something recognized by `gdbarch_stap_is_single_operand'.  */

static void
stap_parse_argument_conditionally (struct stap_parse_info *p)
{
  if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+' /* Unary.  */
      || isdigit (*p->arg)
      || gdbarch_stap_is_single_operand (p->gdbarch, p->arg))
    stap_parse_single_operand (p);
  else if (*p->arg == '(')
    {
      /* We are dealing with a parenthesized operand.  It means we
	 have to parse it as it was a separate expression, without
	 left-side or precedence.  */
      ++p->arg;
      p->arg = skip_spaces_const (p->arg);
      ++p->inside_paren_p;

      stap_parse_argument_1 (p, 0, STAP_OPERAND_PREC_NONE);

      --p->inside_paren_p;
      if (*p->arg != ')')
	error (_("Missign close-paren on expression `%s'."),
	       p->saved_arg);

      ++p->arg;
      if (p->inside_paren_p)
	p->arg = skip_spaces_const (p->arg);
    }
  else
    error (_("Cannot parse expression `%s'."), p->saved_arg);
}

/* Helper function for `stap_parse_argument'.  Please, see its comments to
   better understand what this function does.  */

static void
stap_parse_argument_1 (struct stap_parse_info *p, int has_lhs,
		       enum stap_operand_prec prec)
{
  /* This is an operator-precedence parser.

     We work with left- and right-sides of expressions, and
     parse them depending on the precedence of the operators
     we find.  */

  if (p->inside_paren_p)
    p->arg = skip_spaces_const (p->arg);

  if (!has_lhs)
    {
      /* We were called without a left-side, either because this is the
	 first call, or because we were called to parse a parenthesized
	 expression.  It doesn't really matter; we have to parse the
	 left-side in order to continue the process.  */
      stap_parse_argument_conditionally (p);
    }

  /* Start to parse the right-side, and to "join" left and right sides
     depending on the operation specified.

     This loop shall continue until we run out of characters in the input,
     or until we find a close-parenthesis, which means that we've reached
     the end of a sub-expression.  */
  while (p->arg && *p->arg && *p->arg != ')' && !isspace (*p->arg))
    {
      const char *tmp_exp_buf;
      enum exp_opcode opcode;
      enum stap_operand_prec cur_prec;

      if (!stap_is_operator (p->arg))
	error (_("Invalid operator `%c' on expression `%s'."), *p->arg,
	       p->saved_arg);

      /* We have to save the current value of the expression buffer because
	 the `stap_get_opcode' modifies it in order to get the current
	 operator.  If this operator's precedence is lower than PREC, we
	 should return and not advance the expression buffer pointer.  */
      tmp_exp_buf = p->arg;
      opcode = stap_get_opcode (&tmp_exp_buf);

      cur_prec = stap_get_operator_prec (opcode);
      if (cur_prec < prec)
	{
	  /* If the precedence of the operator that we are seeing now is
	     lower than the precedence of the first operator seen before
	     this parsing process began, it means we should stop parsing
	     and return.  */
	  break;
	}

      p->arg = tmp_exp_buf;
      if (p->inside_paren_p)
	p->arg = skip_spaces_const (p->arg);

      /* Parse the right-side of the expression.  */
      stap_parse_argument_conditionally (p);

      /* While we still have operators, try to parse another
	 right-side, but using the current right-side as a left-side.  */
      while (*p->arg && stap_is_operator (p->arg))
	{
	  enum exp_opcode lookahead_opcode;
	  enum stap_operand_prec lookahead_prec;

	  /* Saving the current expression buffer position.  The explanation
	     is the same as above.  */
	  tmp_exp_buf = p->arg;
	  lookahead_opcode = stap_get_opcode (&tmp_exp_buf);
	  lookahead_prec = stap_get_operator_prec (lookahead_opcode);

	  if (lookahead_prec <= prec)
	    {
	      /* If we are dealing with an operator whose precedence is lower
		 than the first one, just abandon the attempt.  */
	      break;
	    }

	  /* Parse the right-side of the expression, but since we already
	     have a left-side at this point, set `has_lhs' to 1.  */
	  stap_parse_argument_1 (p, 1, lookahead_prec);
	}

      write_exp_elt_opcode (opcode);
    }
}

/* Parse a probe's argument.

   Assuming that:

   LP = literal integer prefix
   LS = literal integer suffix

   RP = register prefix
   RS = register suffix

   RIP = register indirection prefix
   RIS = register indirection suffix

   This routine assumes that arguments' tokens are of the form:

   - [LP] NUMBER [LS]
   - [RP] REGISTER [RS]
   - [RIP] [RP] REGISTER [RS] [RIS]
   - If we find a number without LP, we try to parse it as a literal integer
   constant (if LP == NULL), or as a register displacement.
   - We count parenthesis, and only skip whitespaces if we are inside them.
   - If we find an operator, we skip it.

   This function can also call a special function that will try to match
   unknown tokens.  It will return 1 if the argument has been parsed
   successfully, or zero otherwise.  */

static struct expression *
stap_parse_argument (const char **arg, struct type *atype,
		     struct gdbarch *gdbarch)
{
  struct stap_parse_info p;
  struct cleanup *back_to;

  /* We need to initialize the expression buffer, in order to begin
     our parsing efforts.  The language here does not matter, since we
     are using our own parser.  */
  initialize_expout (10, current_language, gdbarch);
  back_to = make_cleanup (free_current_contents, &expout);

  p.saved_arg = *arg;
  p.arg = *arg;
  p.arg_type = atype;
  p.gdbarch = gdbarch;
  p.inside_paren_p = 0;

  stap_parse_argument_1 (&p, 0, STAP_OPERAND_PREC_NONE);

  discard_cleanups (back_to);

  gdb_assert (p.inside_paren_p == 0);

  /* Casting the final expression to the appropriate type.  */
  write_exp_elt_opcode (UNOP_CAST);
  write_exp_elt_type (atype);
  write_exp_elt_opcode (UNOP_CAST);

  reallocate_expout ();

  p.arg = skip_spaces_const (p.arg);
  *arg = p.arg;

  return expout;
}

/* Function which parses an argument string from PROBE, correctly splitting
   the arguments and storing their information in properly ways.

   Consider the following argument string (x86 syntax):

   `4@%eax 4@$10'

   We have two arguments, `%eax' and `$10', both with 32-bit unsigned bitness.
   This function basically handles them, properly filling some structures with
   this information.  */

static void
stap_parse_probe_arguments (struct stap_probe *probe)
{
  const char *cur;
  struct gdbarch *gdbarch = get_objfile_arch (probe->p.objfile);

  gdb_assert (!probe->args_parsed);
  cur = probe->args_u.text;
  probe->args_parsed = 1;
  probe->args_u.vec = NULL;

  if (!cur || !*cur || *cur == ':')
    return;

  while (*cur)
    {
      struct stap_probe_arg arg;
      enum stap_arg_bitness b;
      int got_minus = 0;
      struct expression *expr;

      memset (&arg, 0, sizeof (arg));

      /* We expect to find something like:

	 N@OP

	 Where `N' can be [+,-][4,8].  This is not mandatory, so
	 we check it here.  If we don't find it, go to the next
	 state.  */
      if ((*cur == '-' && cur[1] && cur[2] != '@')
	  && cur[1] != '@')
	arg.bitness = STAP_ARG_BITNESS_UNDEFINED;
      else
	{
	  if (*cur == '-')
	    {
	      /* Discard the `-'.  */
	      ++cur;
	      got_minus = 1;
	    }

	  if (*cur == '4')
	    b = (got_minus ? STAP_ARG_BITNESS_32BIT_SIGNED
		 : STAP_ARG_BITNESS_32BIT_UNSIGNED);
	  else if (*cur == '8')
	    b = (got_minus ? STAP_ARG_BITNESS_64BIT_SIGNED
		 : STAP_ARG_BITNESS_64BIT_UNSIGNED);
	  else
	    {
	      /* We have an error, because we don't expect anything
		 except 4 and 8.  */
	      complaint (&symfile_complaints,
			 _("unrecognized bitness `%c' for probe `%s'"),
			 *cur, probe->p.name);
	      return;
	    }

	  arg.bitness = b;
	  arg.atype = stap_get_expected_argument_type (gdbarch, b);

	  /* Discard the number and the `@' sign.  */
	  cur += 2;
	}

      expr = stap_parse_argument (&cur, arg.atype, gdbarch);

      if (stap_expression_debug)
	dump_raw_expression (expr, gdb_stdlog,
			     "before conversion to prefix form");

      prefixify_expression (expr);

      if (stap_expression_debug)
	dump_prefix_expression (expr, gdb_stdlog);

      arg.aexpr = expr;

      /* Start it over again.  */
      cur = skip_spaces_const (cur);

      VEC_safe_push (stap_probe_arg_s, probe->args_u.vec, &arg);
    }
}

/* Given PROBE, returns the number of arguments present in that probe's
   argument string.  */

static unsigned
stap_get_probe_argument_count (struct probe *probe_generic)
{
  struct stap_probe *probe = (struct stap_probe *) probe_generic;

  gdb_assert (probe_generic->pops == &stap_probe_ops);

  if (!probe->args_parsed)
    stap_parse_probe_arguments (probe);

  gdb_assert (probe->args_parsed);
  return VEC_length (stap_probe_arg_s, probe->args_u.vec);
}

/* Return 1 if OP is a valid operator inside a probe argument, or zero
   otherwise.  */

static int
stap_is_operator (const char *op)
{
  int ret = 1;

  switch (*op)
    {
    case '*':
    case '/':
    case '%':
    case '^':
    case '!':
    case '+':
    case '-':
    case '<':
    case '>':
    case '|':
    case '&':
      break;

    case '=':
      if (op[1] != '=')
	ret = 0;
      break;

    default:
      /* We didn't find any operator.  */
      ret = 0;
    }

  return ret;
}

static struct stap_probe_arg *
stap_get_arg (struct stap_probe *probe, unsigned n)
{
  if (!probe->args_parsed)
    stap_parse_probe_arguments (probe);

  return VEC_index (stap_probe_arg_s, probe->args_u.vec, n);
}

/* Evaluate the probe's argument N (indexed from 0), returning a value
   corresponding to it.  Assertion is thrown if N does not exist.  */

static struct value *
stap_evaluate_probe_argument (struct probe *probe_generic, unsigned n)
{
  struct stap_probe *stap_probe = (struct stap_probe *) probe_generic;
  struct stap_probe_arg *arg;
  int pos = 0;

  gdb_assert (probe_generic->pops == &stap_probe_ops);

  arg = stap_get_arg (stap_probe, n);
  return evaluate_subexp_standard (arg->atype, arg->aexpr, &pos, EVAL_NORMAL);
}

/* Compile the probe's argument N (indexed from 0) to agent expression.
   Assertion is thrown if N does not exist.  */

static void
stap_compile_to_ax (struct probe *probe_generic, struct agent_expr *expr,
		    struct axs_value *value, unsigned n)
{
  struct stap_probe *stap_probe = (struct stap_probe *) probe_generic;
  struct stap_probe_arg *arg;
  union exp_element *pc;

  gdb_assert (probe_generic->pops == &stap_probe_ops);

  arg = stap_get_arg (stap_probe, n);

  pc = arg->aexpr->elts;
  gen_expr (arg->aexpr, &pc, expr, value);

  require_rvalue (expr, value);
  value->type = arg->atype;
}

/* Destroy (free) the data related to PROBE.  PROBE memory itself is not feed
   as it is allocated from OBJFILE_OBSTACK.  */

static void
stap_probe_destroy (struct probe *probe_generic)
{
  struct stap_probe *probe = (struct stap_probe *) probe_generic;

  gdb_assert (probe_generic->pops == &stap_probe_ops);

  if (probe->args_parsed)
    {
      struct stap_probe_arg *arg;
      int ix;

      for (ix = 0; VEC_iterate (stap_probe_arg_s, probe->args_u.vec, ix, arg);
	   ++ix)
	xfree (arg->aexpr);
      VEC_free (stap_probe_arg_s, probe->args_u.vec);
    }
}



/* This is called to compute the value of one of the $_probe_arg*
   convenience variables.  */

static struct value *
compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar,
		   void *data)
{
  struct frame_info *frame = get_selected_frame (_("No frame selected"));
  CORE_ADDR pc = get_frame_pc (frame);
  int sel = (int) (uintptr_t) data;
  struct probe *pc_probe;
  const struct sym_probe_fns *pc_probe_fns;
  unsigned n_args;

  /* SEL == -1 means "_probe_argc".  */
  gdb_assert (sel >= -1);

  pc_probe = find_probe_by_pc (pc);
  if (pc_probe == NULL)
    error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc));

  gdb_assert (pc_probe->objfile != NULL);
  gdb_assert (pc_probe->objfile->sf != NULL);
  gdb_assert (pc_probe->objfile->sf->sym_probe_fns != NULL);

  pc_probe_fns = pc_probe->objfile->sf->sym_probe_fns;

  n_args = pc_probe_fns->sym_get_probe_argument_count (pc_probe);
  if (sel == -1)
    return value_from_longest (builtin_type (arch)->builtin_int, n_args);

  if (sel >= n_args)
    error (_("Invalid probe argument %d -- probe has %u arguments available"),
	   sel, n_args);

  return pc_probe_fns->sym_evaluate_probe_argument (pc_probe, sel);
}

/* This is called to compile one of the $_probe_arg* convenience
   variables into an agent expression.  */

static void
compile_probe_arg (struct internalvar *ivar, struct agent_expr *expr,
		   struct axs_value *value, void *data)
{
  CORE_ADDR pc = expr->scope;
  int sel = (int) (uintptr_t) data;
  struct probe *pc_probe;
  const struct sym_probe_fns *pc_probe_fns;
  int n_args;

  /* SEL == -1 means "_probe_argc".  */
  gdb_assert (sel >= -1);

  pc_probe = find_probe_by_pc (pc);
  if (pc_probe == NULL)
    error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc));

  gdb_assert (pc_probe->objfile != NULL);
  gdb_assert (pc_probe->objfile->sf != NULL);
  gdb_assert (pc_probe->objfile->sf->sym_probe_fns != NULL);

  pc_probe_fns = pc_probe->objfile->sf->sym_probe_fns;

  n_args = pc_probe_fns->sym_get_probe_argument_count (pc_probe);

  if (sel == -1)
    {
      value->kind = axs_rvalue;
      value->type = builtin_type (expr->gdbarch)->builtin_int;
      ax_const_l (expr, n_args);
      return;
    }

  gdb_assert (sel >= 0);
  if (sel >= n_args)
    error (_("Invalid probe argument %d -- probe has %d arguments available"),
	   sel, n_args);

  pc_probe_fns->sym_compile_to_ax (pc_probe, expr, value, sel);
}



/* Set or clear a SystemTap semaphore.  ADDRESS is the semaphore's
   address.  SET is zero if the semaphore should be cleared, or one
   if it should be set.  This is a helper function for `stap_semaphore_down'
   and `stap_semaphore_up'.  */

static void
stap_modify_semaphore (CORE_ADDR address, int set, struct gdbarch *gdbarch)
{
  gdb_byte bytes[sizeof (LONGEST)];
  /* The ABI specifies "unsigned short".  */
  struct type *type = builtin_type (gdbarch)->builtin_unsigned_short;
  ULONGEST value;

  if (address == 0)
    return;

  /* Swallow errors.  */
  if (target_read_memory (address, bytes, TYPE_LENGTH (type)) != 0)
    {
      warning (_("Could not read the value of a SystemTap semaphore."));
      return;
    }

  value = extract_unsigned_integer (bytes, TYPE_LENGTH (type),
				    gdbarch_byte_order (gdbarch));
  /* Note that we explicitly don't worry about overflow or
     underflow.  */
  if (set)
    ++value;
  else
    --value;

  store_unsigned_integer (bytes, TYPE_LENGTH (type),
			  gdbarch_byte_order (gdbarch), value);

  if (target_write_memory (address, bytes, TYPE_LENGTH (type)) != 0)
    warning (_("Could not write the value of a SystemTap semaphore."));
}

/* Set a SystemTap semaphore.  SEM is the semaphore's address.  Semaphores
   act as reference counters, so calls to this function must be paired with
   calls to `stap_semaphore_down'.

   This function and `stap_semaphore_down' race with another tool changing
   the probes, but that is too rare to care.  */

static void
stap_set_semaphore (struct probe *probe_generic, struct gdbarch *gdbarch)
{
  struct stap_probe *probe = (struct stap_probe *) probe_generic;

  gdb_assert (probe_generic->pops == &stap_probe_ops);

  stap_modify_semaphore (probe->sem_addr, 1, gdbarch);
}

/* Clear a SystemTap semaphore.  SEM is the semaphore's address.  */

static void
stap_clear_semaphore (struct probe *probe_generic, struct gdbarch *gdbarch)
{
  struct stap_probe *probe = (struct stap_probe *) probe_generic;

  gdb_assert (probe_generic->pops == &stap_probe_ops);

  stap_modify_semaphore (probe->sem_addr, 0, gdbarch);
}

/* Implementation of `$_probe_arg*' set of variables.  */

static const struct internalvar_funcs probe_funcs =
{
  compute_probe_arg,
  compile_probe_arg,
  NULL
};

/* Helper function that parses the information contained in a
   SystemTap's probe.  Basically, the information consists in:

   - Probe's PC address;
   - Link-time section address of `.stapsdt.base' section;
   - Link-time address of the semaphore variable, or ZERO if the
     probe doesn't have an associated semaphore;
   - Probe's provider name;
   - Probe's name;
   - Probe's argument format
   
   This function returns 1 if the handling was successful, and zero
   otherwise.  */

static void
handle_stap_probe (struct objfile *objfile, struct sdt_note *el,
		   VEC (probe_p) **probesp, CORE_ADDR base)
{
  bfd *abfd = objfile->obfd;
  int size = bfd_get_arch_size (abfd) / 8;
  struct gdbarch *gdbarch = get_objfile_arch (objfile);
  struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
  CORE_ADDR base_ref;
  const char *probe_args = NULL;
  struct stap_probe *ret;

  ret = obstack_alloc (&objfile->objfile_obstack, sizeof (*ret));
  ret->p.pops = &stap_probe_ops;
  ret->p.objfile = objfile;

  /* Provider and the name of the probe.  */
  ret->p.provider = &el->data[3 * size];
  ret->p.name = memchr (ret->p.provider, '\0',
			(char *) el->data + el->size - ret->p.provider);
  /* Making sure there is a name.  */
  if (!ret->p.name)
    {
      complaint (&symfile_complaints, _("corrupt probe name when "
					"reading `%s'"), objfile->name);

      /* There is no way to use a probe without a name or a provider, so
	 returning zero here makes sense.  */
      return;
    }
  else
    ++ret->p.name;

  /* Retrieving the probe's address.  */
  ret->p.address = extract_typed_address (&el->data[0], ptr_type);

  /* Link-time sh_addr of `.stapsdt.base' section.  */
  base_ref = extract_typed_address (&el->data[size], ptr_type);

  /* Semaphore address.  */
  ret->sem_addr = extract_typed_address (&el->data[2 * size], ptr_type);

  ret->p.address += (ANOFFSET (objfile->section_offsets,
			       SECT_OFF_TEXT (objfile))
		     + base - base_ref);
  if (ret->sem_addr)
    ret->sem_addr += (ANOFFSET (objfile->section_offsets,
				SECT_OFF_DATA (objfile))
		      + base - base_ref);

  /* Arguments.  We can only extract the argument format if there is a valid
     name for this probe.  */
  probe_args = memchr (ret->p.name, '\0',
		       (char *) el->data + el->size - ret->p.name);

  if (probe_args != NULL)
    ++probe_args;

  if (probe_args == NULL || (memchr (probe_args, '\0',
				     (char *) el->data + el->size - ret->p.name)
			     != el->data + el->size - 1))
    {
      complaint (&symfile_complaints, _("corrupt probe argument when "
					"reading `%s'"), objfile->name);
      /* If the argument string is NULL, it means some problem happened with
	 it.  So we return 0.  */
      return;
    }

  ret->args_parsed = 0;
  ret->args_u.text = (void *) probe_args;

  /* Successfully created probe.  */
  VEC_safe_push (probe_p, *probesp, (struct probe *) ret);
}

/* Helper function which tries to find the base address of the SystemTap
   base section named STAP_BASE_SECTION_NAME.  */

static void
get_stap_base_address_1 (bfd *abfd, asection *sect, void *obj)
{
  asection **ret = obj;

  if ((sect->flags & (SEC_DATA | SEC_ALLOC | SEC_HAS_CONTENTS))
      && sect->name && !strcmp (sect->name, STAP_BASE_SECTION_NAME))
    *ret = sect;
}

/* Helper function which iterates over every section in the BFD file,
   trying to find the base address of the SystemTap base section.
   Returns 1 if found (setting BASE to the proper value), zero otherwise.  */

static int
get_stap_base_address (bfd *obfd, bfd_vma *base)
{
  asection *ret = NULL;

  bfd_map_over_sections (obfd, get_stap_base_address_1, (void *) &ret);

  if (!ret)
    {
      complaint (&symfile_complaints, _("could not obtain base address for "
					"SystemTap section on objfile `%s'."),
		 obfd->filename);
      return 0;
    }

  if (base)
    *base = ret->vma;

  return 1;
}

/* Helper function for `elf_get_probes', which gathers information about all
   SystemTap probes from OBJFILE.  */

static void
stap_get_probes (VEC (probe_p) **probesp, struct objfile *objfile)
{
  /* If we are here, then this is the first time we are parsing the
     SystemTap probe's information.  We basically have to count how many
     probes the objfile has, and then fill in the necessary information
     for each one.  */
  bfd *obfd = objfile->obfd;
  bfd_vma base;
  struct sdt_note *iter;
  unsigned save_probesp_len = VEC_length (probe_p, *probesp);

  if (objfile->separate_debug_objfile_backlink != NULL)
    {
      /* This is a .debug file, not the objfile itself.  */
      return;
    }

  if (!elf_tdata (obfd)->sdt_note_head)
    {
      /* There isn't any probe here.  */
      return;
    }

  if (!get_stap_base_address (obfd, &base))
    {
      /* There was an error finding the base address for the section.
	 Just return NULL.  */
      return;
    }

  /* Parsing each probe's information.  */
  for (iter = elf_tdata (obfd)->sdt_note_head; iter; iter = iter->next)
    {
      /* We first have to handle all the information about the
	 probe which is present in the section.  */
      handle_stap_probe (objfile, iter, probesp, base);
    }

  if (save_probesp_len == VEC_length (probe_p, *probesp))
    {
      /* If we are here, it means we have failed to parse every known
	 probe.  */
      complaint (&symfile_complaints, _("could not parse SystemTap probe(s) "
					"from inferior"));
      return;
    }
}

static void
stap_relocate (struct probe *probe_generic, CORE_ADDR delta)
{
  struct stap_probe *probe = (struct stap_probe *) probe_generic;

  gdb_assert (probe_generic->pops == &stap_probe_ops);

  probe->p.address += delta;
  if (probe->sem_addr)
    probe->sem_addr += delta;
}

static int
stap_probe_is_linespec (const char **linespecp)
{
  static const char *const keywords[] = { "-pstap", "-probe-stap", NULL };

  return probe_is_linespec_by_keyword (linespecp, keywords);
}

static void
stap_gen_info_probes_table_header (VEC (info_probe_column_s) **heads)
{
  info_probe_column_s stap_probe_column;

  stap_probe_column.field_name = "semaphore";
  stap_probe_column.print_name = _("Semaphore");

  VEC_safe_push (info_probe_column_s, *heads, &stap_probe_column);
}

static void
stap_gen_info_probes_table_values (struct probe *probe_generic,
				   VEC (const_char_ptr) **ret)
{
  struct stap_probe *probe = (struct stap_probe *) probe_generic;
  struct gdbarch *gdbarch;
  const char *val = NULL;

  gdb_assert (probe_generic->pops == &stap_probe_ops);

  gdbarch = get_objfile_arch (probe->p.objfile);

  if (probe->sem_addr)
    val = print_core_address (gdbarch, probe->sem_addr);

  VEC_safe_push (const_char_ptr, *ret, val);
}

/* SystemTap probe_ops.  */

static const struct probe_ops stap_probe_ops =
{
  stap_probe_is_linespec,
  stap_get_probes,
  stap_relocate,
  stap_get_probe_argument_count,
  stap_evaluate_probe_argument,
  stap_compile_to_ax,
  stap_set_semaphore,
  stap_clear_semaphore,
  stap_probe_destroy,
  stap_gen_info_probes_table_header,
  stap_gen_info_probes_table_values,
};

/* Implementation of the `info probes stap' command.  */

static void
info_probes_stap_command (char *arg, int from_tty)
{
  info_probes_for_ops (arg, from_tty, &stap_probe_ops);
}

void _initialize_stap_probe (void);

void
_initialize_stap_probe (void)
{
  VEC_safe_push (probe_ops_cp, all_probe_ops, &stap_probe_ops);

  add_setshow_zuinteger_cmd ("stap-expression", class_maintenance,
			     &stap_expression_debug,
			     _("Set SystemTap expression debugging."),
			     _("Show SystemTap expression debugging."),
			     _("When non-zero, the internal representation "
			       "of SystemTap expressions will be printed."),
			     NULL,
			     show_stapexpressiondebug,
			     &setdebuglist, &showdebuglist);

  create_internalvar_type_lazy ("_probe_argc", &probe_funcs,
				(void *) (uintptr_t) -1);
  create_internalvar_type_lazy ("_probe_arg0", &probe_funcs,
				(void *) (uintptr_t) 0);
  create_internalvar_type_lazy ("_probe_arg1", &probe_funcs,
				(void *) (uintptr_t) 1);
  create_internalvar_type_lazy ("_probe_arg2", &probe_funcs,
				(void *) (uintptr_t) 2);
  create_internalvar_type_lazy ("_probe_arg3", &probe_funcs,
				(void *) (uintptr_t) 3);
  create_internalvar_type_lazy ("_probe_arg4", &probe_funcs,
				(void *) (uintptr_t) 4);
  create_internalvar_type_lazy ("_probe_arg5", &probe_funcs,
				(void *) (uintptr_t) 5);
  create_internalvar_type_lazy ("_probe_arg6", &probe_funcs,
				(void *) (uintptr_t) 6);
  create_internalvar_type_lazy ("_probe_arg7", &probe_funcs,
				(void *) (uintptr_t) 7);
  create_internalvar_type_lazy ("_probe_arg8", &probe_funcs,
				(void *) (uintptr_t) 8);
  create_internalvar_type_lazy ("_probe_arg9", &probe_funcs,
				(void *) (uintptr_t) 9);
  create_internalvar_type_lazy ("_probe_arg10", &probe_funcs,
				(void *) (uintptr_t) 10);
  create_internalvar_type_lazy ("_probe_arg11", &probe_funcs,
				(void *) (uintptr_t) 11);

  add_cmd ("stap", class_info, info_probes_stap_command,
	   _("\
Show information about SystemTap static probes.\n\
Usage: info probes stap [PROVIDER [NAME [OBJECT]]]\n\
Each argument is a regular expression, used to select probes.\n\
PROVIDER matches probe provider names.\n\
NAME matches the probe names.\n\
OBJECT matches the executable or shared library name."),
	   info_probes_cmdlist_get ());

}
