/* Generic static probe support for GDB.

   Copyright (C) 2012-2016 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 "probe.h"
#include "command.h"
#include "cli/cli-cmds.h"
#include "cli/cli-utils.h"
#include "objfiles.h"
#include "symtab.h"
#include "progspace.h"
#include "filenames.h"
#include "linespec.h"
#include "gdb_regex.h"
#include "frame.h"
#include "arch-utils.h"
#include "value.h"
#include "ax.h"
#include "ax-gdb.h"
#include "location.h"
#include <ctype.h>
#include <algorithm>

typedef struct bound_probe bound_probe_s;
DEF_VEC_O (bound_probe_s);



/* A helper for parse_probes that decodes a probe specification in
   SEARCH_PSPACE.  It appends matching SALs to RESULT.  */

static void
parse_probes_in_pspace (const struct probe_ops *probe_ops,
			struct program_space *search_pspace,
			const char *objfile_namestr,
			const char *provider,
			const char *name,
			struct symtabs_and_lines *result)
{
  struct objfile *objfile;

  ALL_PSPACE_OBJFILES (search_pspace, objfile)
    {
      VEC (probe_p) *probes;
      struct probe *probe;
      int ix;

      if (!objfile->sf || !objfile->sf->sym_probe_fns)
	continue;

      if (objfile_namestr
	  && FILENAME_CMP (objfile_name (objfile), objfile_namestr) != 0
	  && FILENAME_CMP (lbasename (objfile_name (objfile)),
			   objfile_namestr) != 0)
	continue;

      probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);

      for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
	{
	  struct symtab_and_line *sal;

	  if (probe_ops != &probe_ops_any && probe->pops != probe_ops)
	    continue;

	  if (provider && strcmp (probe->provider, provider) != 0)
	    continue;

	  if (strcmp (probe->name, name) != 0)
	    continue;

	  ++result->nelts;
	  result->sals = XRESIZEVEC (struct symtab_and_line, result->sals,
				     result->nelts);
	  sal = &result->sals[result->nelts - 1];

	  init_sal (sal);

	  sal->pc = get_probe_address (probe, objfile);
	  sal->explicit_pc = 1;
	  sal->section = find_pc_overlay (sal->pc);
	  sal->pspace = search_pspace;
	  sal->probe = probe;
	  sal->objfile = objfile;
	}
    }
}

/* See definition in probe.h.  */

struct symtabs_and_lines
parse_probes (const struct event_location *location,
	      struct program_space *search_pspace,
	      struct linespec_result *canonical)
{
  char *arg_end, *arg;
  char *objfile_namestr = NULL, *provider = NULL, *name, *p;
  struct cleanup *cleanup;
  struct symtabs_and_lines result;
  const struct probe_ops *probe_ops;
  const char *arg_start, *cs;

  result.sals = NULL;
  result.nelts = 0;

  gdb_assert (event_location_type (location) == PROBE_LOCATION);
  arg_start = get_probe_location (location);

  cs = arg_start;
  probe_ops = probe_linespec_to_ops (&cs);
  if (probe_ops == NULL)
    error (_("'%s' is not a probe linespec"), arg_start);

  arg = (char *) cs;
  arg = skip_spaces (arg);
  if (!*arg)
    error (_("argument to `%s' missing"), arg_start);

  arg_end = skip_to_space (arg);

  /* We make a copy here so we can write over parts with impunity.  */
  arg = savestring (arg, arg_end - arg);
  cleanup = make_cleanup (xfree, arg);

  /* Extract each word from the argument, separated by ":"s.  */
  p = strchr (arg, ':');
  if (p == NULL)
    {
      /* This is `-p name'.  */
      name = arg;
    }
  else
    {
      char *hold = p + 1;

      *p = '\0';
      p = strchr (hold, ':');
      if (p == NULL)
	{
	  /* This is `-p provider:name'.  */
	  provider = arg;
	  name = hold;
	}
      else
	{
	  /* This is `-p objfile:provider:name'.  */
	  *p = '\0';
	  objfile_namestr = arg;
	  provider = hold;
	  name = p + 1;
	}
    }

  if (*name == '\0')
    error (_("no probe name specified"));
  if (provider && *provider == '\0')
    error (_("invalid provider name"));
  if (objfile_namestr && *objfile_namestr == '\0')
    error (_("invalid objfile name"));

  if (search_pspace != NULL)
    {
      parse_probes_in_pspace (probe_ops, search_pspace, objfile_namestr,
			      provider, name, &result);
    }
  else
    {
      struct program_space *pspace;

      ALL_PSPACES (pspace)
	parse_probes_in_pspace (probe_ops, pspace, objfile_namestr,
				provider, name, &result);
    }

  if (result.nelts == 0)
    {
      throw_error (NOT_FOUND_ERROR,
		   _("No probe matching objfile=`%s', provider=`%s', name=`%s'"),
		   objfile_namestr ? objfile_namestr : _("<any>"),
		   provider ? provider : _("<any>"),
		   name);
    }

  if (canonical)
    {
      char *canon;

      canon = savestring (arg_start, arg_end - arg_start);
      make_cleanup (xfree, canon);
      canonical->special_display = 1;
      canonical->pre_expanded = 1;
      canonical->location = new_probe_location (canon);
    }

  do_cleanups (cleanup);

  return result;
}

/* See definition in probe.h.  */

VEC (probe_p) *
find_probes_in_objfile (struct objfile *objfile, const char *provider,
			const char *name)
{
  VEC (probe_p) *probes, *result = NULL;
  int ix;
  struct probe *probe;

  if (!objfile->sf || !objfile->sf->sym_probe_fns)
    return NULL;

  probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
  for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
    {
      if (strcmp (probe->provider, provider) != 0)
	continue;

      if (strcmp (probe->name, name) != 0)
	continue;

      VEC_safe_push (probe_p, result, probe);
    }

  return result;
}

/* See definition in probe.h.  */

struct bound_probe
find_probe_by_pc (CORE_ADDR pc)
{
  struct objfile *objfile;
  struct bound_probe result;

  result.objfile = NULL;
  result.probe = NULL;

  ALL_OBJFILES (objfile)
  {
    VEC (probe_p) *probes;
    int ix;
    struct probe *probe;

    if (!objfile->sf || !objfile->sf->sym_probe_fns
	|| objfile->sect_index_text == -1)
      continue;

    /* If this proves too inefficient, we can replace with a hash.  */
    probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
    for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
      if (get_probe_address (probe, objfile) == pc)
	{
	  result.objfile = objfile;
	  result.probe = probe;
	  return result;
	}
  }

  return result;
}



/* Make a vector of probes matching OBJNAME, PROVIDER, and PROBE_NAME.
   If POPS is not NULL, only probes of this certain probe_ops will match.
   Each argument is a regexp, or NULL, which matches anything.  */

static VEC (bound_probe_s) *
collect_probes (char *objname, char *provider, char *probe_name,
		const struct probe_ops *pops)
{
  struct objfile *objfile;
  VEC (bound_probe_s) *result = NULL;
  struct cleanup *cleanup, *cleanup_temps;
  regex_t obj_pat, prov_pat, probe_pat;

  cleanup = make_cleanup (VEC_cleanup (bound_probe_s), &result);

  cleanup_temps = make_cleanup (null_cleanup, NULL);
  if (provider != NULL)
    compile_rx_or_error (&prov_pat, provider, _("Invalid provider regexp"));
  if (probe_name != NULL)
    compile_rx_or_error (&probe_pat, probe_name, _("Invalid probe regexp"));
  if (objname != NULL)
    compile_rx_or_error (&obj_pat, objname, _("Invalid object file regexp"));

  ALL_OBJFILES (objfile)
    {
      VEC (probe_p) *probes;
      struct probe *probe;
      int ix;

      if (! objfile->sf || ! objfile->sf->sym_probe_fns)
	continue;

      if (objname)
	{
	  if (regexec (&obj_pat, objfile_name (objfile), 0, NULL, 0) != 0)
	    continue;
	}

      probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);

      for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
	{
	  struct bound_probe bound;

	  if (pops != NULL && probe->pops != pops)
	    continue;

	  if (provider
	      && regexec (&prov_pat, probe->provider, 0, NULL, 0) != 0)
	    continue;

	  if (probe_name
	      && regexec (&probe_pat, probe->name, 0, NULL, 0) != 0)
	    continue;

	  bound.objfile = objfile;
	  bound.probe = probe;
	  VEC_safe_push (bound_probe_s, result, &bound);
	}
    }

  do_cleanups (cleanup_temps);
  discard_cleanups (cleanup);
  return result;
}

/* A qsort comparison function for bound_probe_s objects.  */

static int
compare_probes (const void *a, const void *b)
{
  const struct bound_probe *pa = (const struct bound_probe *) a;
  const struct bound_probe *pb = (const struct bound_probe *) b;
  int v;

  v = strcmp (pa->probe->provider, pb->probe->provider);
  if (v)
    return v;

  v = strcmp (pa->probe->name, pb->probe->name);
  if (v)
    return v;

  if (pa->probe->address < pb->probe->address)
    return -1;
  if (pa->probe->address > pb->probe->address)
    return 1;

  return strcmp (objfile_name (pa->objfile), objfile_name (pb->objfile));
}

/* Helper function that generate entries in the ui_out table being
   crafted by `info_probes_for_ops'.  */

static void
gen_ui_out_table_header_info (VEC (bound_probe_s) *probes,
			      const struct probe_ops *p)
{
  /* `headings' refers to the names of the columns when printing `info
     probes'.  */
  VEC (info_probe_column_s) *headings = NULL;
  struct cleanup *c;
  info_probe_column_s *column;
  size_t headings_size;
  int ix;

  gdb_assert (p != NULL);

  if (p->gen_info_probes_table_header == NULL
      && p->gen_info_probes_table_values == NULL)
    return;

  gdb_assert (p->gen_info_probes_table_header != NULL
	      && p->gen_info_probes_table_values != NULL);

  c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
  p->gen_info_probes_table_header (&headings);

  headings_size = VEC_length (info_probe_column_s, headings);

  for (ix = 0;
       VEC_iterate (info_probe_column_s, headings, ix, column);
       ++ix)
    {
      struct bound_probe *probe;
      int jx;
      size_t size_max = strlen (column->print_name);

      for (jx = 0; VEC_iterate (bound_probe_s, probes, jx, probe); ++jx)
	{
	  /* `probe_fields' refers to the values of each new field that this
	     probe will display.  */
	  VEC (const_char_ptr) *probe_fields = NULL;
	  struct cleanup *c2;
	  const char *val;
	  int kx;

	  if (probe->probe->pops != p)
	    continue;

	  c2 = make_cleanup (VEC_cleanup (const_char_ptr), &probe_fields);
	  p->gen_info_probes_table_values (probe->probe, &probe_fields);

	  gdb_assert (VEC_length (const_char_ptr, probe_fields)
		      == headings_size);

	  for (kx = 0; VEC_iterate (const_char_ptr, probe_fields, kx, val);
	       ++kx)
	    {
	      /* It is valid to have a NULL value here, which means that the
		 backend does not have something to write and this particular
		 field should be skipped.  */
	      if (val == NULL)
		continue;

	      size_max = std::max (strlen (val), size_max);
	    }
	  do_cleanups (c2);
	}

      ui_out_table_header (current_uiout, size_max, ui_left,
			   column->field_name, column->print_name);
    }

  do_cleanups (c);
}

/* Helper function to print not-applicable strings for all the extra
   columns defined in a probe_ops.  */

static void
print_ui_out_not_applicables (const struct probe_ops *pops)
{
  struct cleanup *c;
  VEC (info_probe_column_s) *headings = NULL;
  info_probe_column_s *column;
  int ix;

  if (pops->gen_info_probes_table_header == NULL)
    return;

  c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
  pops->gen_info_probes_table_header (&headings);

  for (ix = 0;
       VEC_iterate (info_probe_column_s, headings, ix, column);
       ++ix)
    ui_out_field_string (current_uiout, column->field_name, _("n/a"));

  do_cleanups (c);
}

/* Helper function to print extra information about a probe and an objfile
   represented by PROBE.  */

static void
print_ui_out_info (struct probe *probe)
{
  int ix;
  int j = 0;
  /* `values' refers to the actual values of each new field in the output
     of `info probe'.  `headings' refers to the names of each new field.  */
  VEC (const_char_ptr) *values = NULL;
  VEC (info_probe_column_s) *headings = NULL;
  info_probe_column_s *column;
  struct cleanup *c;

  gdb_assert (probe != NULL);
  gdb_assert (probe->pops != NULL);

  if (probe->pops->gen_info_probes_table_header == NULL
      && probe->pops->gen_info_probes_table_values == NULL)
    return;

  gdb_assert (probe->pops->gen_info_probes_table_header != NULL
	      && probe->pops->gen_info_probes_table_values != NULL);

  c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
  make_cleanup (VEC_cleanup (const_char_ptr), &values);

  probe->pops->gen_info_probes_table_header (&headings);
  probe->pops->gen_info_probes_table_values (probe, &values);

  gdb_assert (VEC_length (info_probe_column_s, headings)
	      == VEC_length (const_char_ptr, values));

  for (ix = 0;
       VEC_iterate (info_probe_column_s, headings, ix, column);
       ++ix)
    {
      const char *val = VEC_index (const_char_ptr, values, j++);

      if (val == NULL)
	ui_out_field_skip (current_uiout, column->field_name);
      else
	ui_out_field_string (current_uiout, column->field_name, val);
    }

  do_cleanups (c);
}

/* Helper function that returns the number of extra fields which POPS will
   need.  */

static int
get_number_extra_fields (const struct probe_ops *pops)
{
  VEC (info_probe_column_s) *headings = NULL;
  struct cleanup *c;
  int n;

  if (pops->gen_info_probes_table_header == NULL)
    return 0;

  c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
  pops->gen_info_probes_table_header (&headings);

  n = VEC_length (info_probe_column_s, headings);

  do_cleanups (c);

  return n;
}

/* Helper function that returns 1 if there is a probe in PROBES
   featuring the given POPS.  It returns 0 otherwise.  */

static int
exists_probe_with_pops (VEC (bound_probe_s) *probes,
			const struct probe_ops *pops)
{
  struct bound_probe *probe;
  int ix;

  for (ix = 0; VEC_iterate (bound_probe_s, probes, ix, probe); ++ix)
    if (probe->probe->pops == pops)
      return 1;

  return 0;
}

/* Helper function that parses a probe linespec of the form [PROVIDER
   [PROBE [OBJNAME]]] from the provided string STR.  */

static void
parse_probe_linespec (const char *str, char **provider,
		      char **probe_name, char **objname)
{
  *probe_name = *objname = NULL;

  *provider = extract_arg_const (&str);
  if (*provider != NULL)
    {
      *probe_name = extract_arg_const (&str);
      if (*probe_name != NULL)
	*objname = extract_arg_const (&str);
    }
}

/* See comment in probe.h.  */

void
info_probes_for_ops (const char *arg, int from_tty,
		     const struct probe_ops *pops)
{
  char *provider, *probe_name = NULL, *objname = NULL;
  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
  VEC (bound_probe_s) *probes;
  int i, any_found;
  int ui_out_extra_fields = 0;
  size_t size_addr;
  size_t size_name = strlen ("Name");
  size_t size_objname = strlen ("Object");
  size_t size_provider = strlen ("Provider");
  size_t size_type = strlen ("Type");
  struct bound_probe *probe;
  struct gdbarch *gdbarch = get_current_arch ();

  parse_probe_linespec (arg, &provider, &probe_name, &objname);
  make_cleanup (xfree, provider);
  make_cleanup (xfree, probe_name);
  make_cleanup (xfree, objname);

  probes = collect_probes (objname, provider, probe_name, pops);
  make_cleanup (VEC_cleanup (probe_p), &probes);

  if (pops == NULL)
    {
      const struct probe_ops *po;
      int ix;

      /* If the probe_ops is NULL, it means the user has requested a "simple"
	 `info probes', i.e., she wants to print all information about all
	 probes.  For that, we have to identify how many extra fields we will
	 need to add in the ui_out table.

	 To do that, we iterate over all probe_ops, querying each one about
	 its extra fields, and incrementing `ui_out_extra_fields' to reflect
	 that number.  But note that we ignore the probe_ops for which no probes
	 are defined with the given search criteria.  */

      for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
	if (exists_probe_with_pops (probes, po))
	  ui_out_extra_fields += get_number_extra_fields (po);
    }
  else
    ui_out_extra_fields = get_number_extra_fields (pops);

  make_cleanup_ui_out_table_begin_end (current_uiout,
				       5 + ui_out_extra_fields,
				       VEC_length (bound_probe_s, probes),
				       "StaticProbes");

  if (!VEC_empty (bound_probe_s, probes))
    qsort (VEC_address (bound_probe_s, probes),
	   VEC_length (bound_probe_s, probes),
	   sizeof (bound_probe_s), compare_probes);

  /* What's the size of an address in our architecture?  */
  size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10;

  /* Determining the maximum size of each field (`type', `provider',
     `name' and `objname').  */
  for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
    {
      const char *probe_type = probe->probe->pops->type_name (probe->probe);

      size_type = std::max (strlen (probe_type), size_type);
      size_name = std::max (strlen (probe->probe->name), size_name);
      size_provider = std::max (strlen (probe->probe->provider), size_provider);
      size_objname = std::max (strlen (objfile_name (probe->objfile)),
			       size_objname);
    }

  ui_out_table_header (current_uiout, size_type, ui_left, "type", _("Type"));
  ui_out_table_header (current_uiout, size_provider, ui_left, "provider",
		       _("Provider"));
  ui_out_table_header (current_uiout, size_name, ui_left, "name", _("Name"));
  ui_out_table_header (current_uiout, size_addr, ui_left, "addr", _("Where"));

  if (pops == NULL)
    {
      const struct probe_ops *po;
      int ix;

      /* We have to generate the table header for each new probe type
	 that we will print.  Note that this excludes probe types not
	 having any defined probe with the search criteria.  */
      for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
	if (exists_probe_with_pops (probes, po))
	  gen_ui_out_table_header_info (probes, po);
    }
  else
    gen_ui_out_table_header_info (probes, pops);

  ui_out_table_header (current_uiout, size_objname, ui_left, "object",
		       _("Object"));
  ui_out_table_body (current_uiout);

  for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
    {
      struct cleanup *inner;
      const char *probe_type = probe->probe->pops->type_name (probe->probe);

      inner = make_cleanup_ui_out_tuple_begin_end (current_uiout, "probe");

      ui_out_field_string (current_uiout, "type",probe_type);
      ui_out_field_string (current_uiout, "provider", probe->probe->provider);
      ui_out_field_string (current_uiout, "name", probe->probe->name);
      ui_out_field_core_addr (current_uiout, "addr",
			      probe->probe->arch,
			      get_probe_address (probe->probe, probe->objfile));

      if (pops == NULL)
	{
	  const struct probe_ops *po;
	  int ix;

	  for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po);
	       ++ix)
	    if (probe->probe->pops == po)
	      print_ui_out_info (probe->probe);
	    else if (exists_probe_with_pops (probes, po))
	      print_ui_out_not_applicables (po);
	}
      else
	print_ui_out_info (probe->probe);

      ui_out_field_string (current_uiout, "object",
			   objfile_name (probe->objfile));
      ui_out_text (current_uiout, "\n");

      do_cleanups (inner);
    }

  any_found = !VEC_empty (bound_probe_s, probes);
  do_cleanups (cleanup);

  if (!any_found)
    ui_out_message (current_uiout, _("No probes matched.\n"));
}

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

static void
info_probes_command (char *arg, int from_tty)
{
  info_probes_for_ops (arg, from_tty, NULL);
}

/* Implementation of the `enable probes' command.  */

static void
enable_probes_command (char *arg, int from_tty)
{
  char *provider, *probe_name = NULL, *objname = NULL;
  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
  VEC (bound_probe_s) *probes;
  struct bound_probe *probe;
  int i;

  parse_probe_linespec ((const char *) arg, &provider, &probe_name, &objname);
  make_cleanup (xfree, provider);
  make_cleanup (xfree, probe_name);
  make_cleanup (xfree, objname);

  probes = collect_probes (objname, provider, probe_name, NULL);
  if (VEC_empty (bound_probe_s, probes))
    {
      ui_out_message (current_uiout, _("No probes matched.\n"));
      do_cleanups (cleanup);
      return;
    }

  /* Enable the selected probes, provided their backends support the
     notion of enabling a probe.  */
  for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
    {
      const struct probe_ops *pops = probe->probe->pops;

      if (pops->enable_probe != NULL)
	{
	  pops->enable_probe (probe->probe);
	  ui_out_message (current_uiout,
			  _("Probe %s:%s enabled.\n"),
			  probe->probe->provider, probe->probe->name);
	}
      else
	ui_out_message (current_uiout,
			_("Probe %s:%s cannot be enabled.\n"),
			probe->probe->provider, probe->probe->name);
    }

  do_cleanups (cleanup);
}

/* Implementation of the `disable probes' command.  */

static void
disable_probes_command (char *arg, int from_tty)
{
  char *provider, *probe_name = NULL, *objname = NULL;
  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
  VEC (bound_probe_s) *probes;
  struct bound_probe *probe;
  int i;

  parse_probe_linespec ((const char *) arg, &provider, &probe_name, &objname);
  make_cleanup (xfree, provider);
  make_cleanup (xfree, probe_name);
  make_cleanup (xfree, objname);

  probes = collect_probes (objname, provider, probe_name, NULL /* pops */);
  if (VEC_empty (bound_probe_s, probes))
    {
      ui_out_message (current_uiout, _("No probes matched.\n"));
      do_cleanups (cleanup);
      return;
    }

  /* Disable the selected probes, provided their backends support the
     notion of enabling a probe.  */
  for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
    {
      const struct probe_ops *pops = probe->probe->pops;

      if (pops->disable_probe != NULL)
	{
	  pops->disable_probe (probe->probe);
	  ui_out_message (current_uiout,
			  _("Probe %s:%s disabled.\n"),
			  probe->probe->provider, probe->probe->name);
	}
      else
	ui_out_message (current_uiout,
			_("Probe %s:%s cannot be disabled.\n"),
			probe->probe->provider, probe->probe->name);
    }

  do_cleanups (cleanup);
}

/* See comments in probe.h.  */

CORE_ADDR
get_probe_address (struct probe *probe, struct objfile *objfile)
{
  return probe->pops->get_probe_address (probe, objfile);
}

/* See comments in probe.h.  */

unsigned
get_probe_argument_count (struct probe *probe, struct frame_info *frame)
{
  return probe->pops->get_probe_argument_count (probe, frame);
}

/* See comments in probe.h.  */

int
can_evaluate_probe_arguments (struct probe *probe)
{
  return probe->pops->can_evaluate_probe_arguments (probe);
}

/* See comments in probe.h.  */

struct value *
evaluate_probe_argument (struct probe *probe, unsigned n,
			 struct frame_info *frame)
{
  return probe->pops->evaluate_probe_argument (probe, n, frame);
}

/* See comments in probe.h.  */

struct value *
probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n)
{
  struct bound_probe probe;
  unsigned n_args;

  probe = find_probe_by_pc (get_frame_pc (frame));
  if (!probe.probe)
    return NULL;

  n_args = get_probe_argument_count (probe.probe, frame);
  if (n >= n_args)
    return NULL;

  return evaluate_probe_argument (probe.probe, n, frame);
}

/* See comment in probe.h.  */

const struct probe_ops *
probe_linespec_to_ops (const char **linespecp)
{
  int ix;
  const struct probe_ops *probe_ops;

  for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, probe_ops); ix++)
    if (probe_ops->is_linespec (linespecp))
      return probe_ops;

  return NULL;
}

/* See comment in probe.h.  */

int
probe_is_linespec_by_keyword (const char **linespecp, const char *const *keywords)
{
  const char *s = *linespecp;
  const char *const *csp;

  for (csp = keywords; *csp; csp++)
    {
      const char *keyword = *csp;
      size_t len = strlen (keyword);

      if (strncmp (s, keyword, len) == 0 && isspace (s[len]))
	{
	  *linespecp += len + 1;
	  return 1;
	}
    }

  return 0;
}

/* Implementation of `is_linespec' method for `struct probe_ops'.  */

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

  return probe_is_linespec_by_keyword (linespecp, keywords);
}

/* Dummy method used for `probe_ops_any'.  */

static void
probe_any_get_probes (VEC (probe_p) **probesp, struct objfile *objfile)
{
  /* No probes can be provided by this dummy backend.  */
}

/* Operations associated with a generic probe.  */

const struct probe_ops probe_ops_any =
{
  probe_any_is_linespec,
  probe_any_get_probes,
};

/* See comments in probe.h.  */

struct cmd_list_element **
info_probes_cmdlist_get (void)
{
  static struct cmd_list_element *info_probes_cmdlist;

  if (info_probes_cmdlist == NULL)
    add_prefix_cmd ("probes", class_info, info_probes_command,
		    _("\
Show available static probes.\n\
Usage: info probes [all|TYPE [ARGS]]\n\
TYPE specifies the type of the probe, and can be one of the following:\n\
  - stap\n\
If you specify TYPE, there may be additional arguments needed by the\n\
subcommand.\n\
If you do not specify any argument, or specify `all', then the command\n\
will show information about all types of probes."),
		    &info_probes_cmdlist, "info probes ",
		    0/*allow-unknown*/, &infolist);

  return &info_probes_cmdlist;
}



/* 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 bound_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.probe == NULL)
    error (_("No probe at PC %s"), core_addr_to_string (pc));

  n_args = get_probe_argument_count (pc_probe.probe, frame);
  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 evaluate_probe_argument (pc_probe.probe, sel, frame);
}

/* 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 bound_probe pc_probe;
  const struct sym_probe_fns *pc_probe_fns;
  int n_args;
  struct frame_info *frame = get_selected_frame (NULL);

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

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

  n_args = get_probe_argument_count (pc_probe.probe, frame);

  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.probe->pops->compile_to_ax (pc_probe.probe, expr, value, sel);
}

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


VEC (probe_ops_cp) *all_probe_ops;

void _initialize_probe (void);

void
_initialize_probe (void)
{
  VEC_safe_push (probe_ops_cp, all_probe_ops, &probe_ops_any);

  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 ("all", class_info, info_probes_command,
	   _("\
Show information about all type of probes."),
	   info_probes_cmdlist_get ());

  add_cmd ("probes", class_breakpoint, enable_probes_command, _("\
Enable probes.\n\
Usage: enable probes [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.\n\
If you do not specify any argument then the command will enable\n\
all defined probes."),
	   &enablelist);

  add_cmd ("probes", class_breakpoint, disable_probes_command, _("\
Disable probes.\n\
Usage: disable probes [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.\n\
If you do not specify any argument then the command will disable\n\
all defined probes."),
	   &disablelist);

}
