/* Generic static probe support for GDB.

   Copyright (C) 2012-2023 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 "gdbsupport/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>
#include "gdbsupport/gdb_optional.h"

/* Class that implements the static probe methods for "any" probe.  */

class any_static_probe_ops : public static_probe_ops
{
public:
  /* See probe.h.  */
  bool is_linespec (const char **linespecp) const override;

  /* See probe.h.  */
  void get_probes (std::vector<std::unique_ptr<probe>> *probesp,
		   struct objfile *objfile) const override;

  /* See probe.h.  */
  const char *type_name () const override;

  /* See probe.h.  */
  std::vector<struct info_probe_column> gen_info_probes_table_header
    () const override;
};

/* Static operations associated with a generic probe.  */

const any_static_probe_ops any_static_probe_ops {};

/* 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 static_probe_ops *spops,
			struct program_space *search_pspace,
			const char *objfile_namestr,
			const char *provider,
			const char *name,
			std::vector<symtab_and_line> *result)
{
  for (objfile *objfile : search_pspace->objfiles ())
    {
      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;

      const std::vector<std::unique_ptr<probe>> &probes
	= objfile->sf->sym_probe_fns->sym_get_probes (objfile);

      for (auto &p : probes)
	{
	  if (spops != &any_static_probe_ops && p->get_static_ops () != spops)
	    continue;

	  if (provider != NULL && p->get_provider () != provider)
	    continue;

	  if (p->get_name () != name)
	    continue;

	  symtab_and_line sal;
	  sal.pc = p->get_relocated_address (objfile);
	  sal.explicit_pc = 1;
	  sal.section = find_pc_overlay (sal.pc);
	  sal.pspace = search_pspace;
	  sal.prob = p.get ();
	  sal.objfile = objfile;

	  result->push_back (std::move (sal));
	}
    }
}

/* See definition in probe.h.  */

std::vector<symtab_and_line>
parse_probes (const location_spec *locspec,
	      struct program_space *search_pspace,
	      struct linespec_result *canonical)
{
  char *arg_end, *arg;
  char *objfile_namestr = NULL, *provider = NULL, *name, *p;
  const char *arg_start, *cs;

  gdb_assert (locspec->type () == PROBE_LOCATION_SPEC);
  arg_start = locspec->to_string ();

  cs = arg_start;
  const static_probe_ops *spops = probe_linespec_to_static_ops (&cs);
  if (spops == 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.  */
  std::string copy (arg, arg_end - arg);
  arg = &copy[0];

  /* 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"));

  std::vector<symtab_and_line> result;
  if (search_pspace != NULL)
    {
      parse_probes_in_pspace (spops, search_pspace, objfile_namestr,
			      provider, name, &result);
    }
  else
    {
      for (struct program_space *pspace : program_spaces)
	parse_probes_in_pspace (spops, pspace, objfile_namestr,
				provider, name, &result);
    }

  if (result.empty ())
    {
      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)
    {
      std::string canon (arg_start, arg_end - arg_start);
      canonical->special_display = 1;
      canonical->pre_expanded = 1;
      canonical->locspec = new_probe_location_spec (std::move (canon));
    }

  return result;
}

/* See definition in probe.h.  */

std::vector<probe *>
find_probes_in_objfile (struct objfile *objfile, const char *provider,
			const char *name)
{
  std::vector<probe *> result;

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

  const std::vector<std::unique_ptr<probe>> &probes
    = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
  for (auto &p : probes)
    {
      if (p->get_provider () != provider)
	continue;

      if (p->get_name () != name)
	continue;

      result.push_back (p.get ());
    }

  return result;
}

/* See definition in probe.h.  */

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

  result.objfile = NULL;
  result.prob = NULL;

  for (objfile *objfile : current_program_space->objfiles ())
    {
      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.  */
      const std::vector<std::unique_ptr<probe>> &probes
	= objfile->sf->sym_probe_fns->sym_get_probes (objfile);
      for (auto &p : probes)
	if (p->get_relocated_address (objfile) == pc)
	  {
	    result.objfile = objfile;
	    result.prob = p.get ();
	    return result;
	  }
    }

  return result;
}



/* Make a vector of probes matching OBJNAME, PROVIDER, and PROBE_NAME.
   If SPOPS is not &any_static_probe_ops, only probes related to this
   specific static probe ops will match.  Each argument is a regexp,
   or NULL, which matches anything.  */

static std::vector<bound_probe>
collect_probes (const std::string &objname, const std::string &provider,
		const std::string &probe_name, const static_probe_ops *spops)
{
  std::vector<bound_probe> result;
  gdb::optional<compiled_regex> obj_pat, prov_pat, probe_pat;

  if (!provider.empty ())
    prov_pat.emplace (provider.c_str (), REG_NOSUB,
		      _("Invalid provider regexp"));
  if (!probe_name.empty ())
    probe_pat.emplace (probe_name.c_str (), REG_NOSUB,
		       _("Invalid probe regexp"));
  if (!objname.empty ())
    obj_pat.emplace (objname.c_str (), REG_NOSUB,
		     _("Invalid object file regexp"));

  for (objfile *objfile : current_program_space->objfiles ())
    {
      if (! objfile->sf || ! objfile->sf->sym_probe_fns)
	continue;

      if (obj_pat)
	{
	  if (obj_pat->exec (objfile_name (objfile), 0, NULL, 0) != 0)
	    continue;
	}

      const std::vector<std::unique_ptr<probe>> &probes
	= objfile->sf->sym_probe_fns->sym_get_probes (objfile);

      for (auto &p : probes)
	{
	  if (spops != &any_static_probe_ops && p->get_static_ops () != spops)
	    continue;

	  if (prov_pat
	      && prov_pat->exec (p->get_provider ().c_str (), 0, NULL, 0) != 0)
	    continue;

	  if (probe_pat
	      && probe_pat->exec (p->get_name ().c_str (), 0, NULL, 0) != 0)
	    continue;

	  result.emplace_back (p.get (), objfile);
	}
    }

  return result;
}

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

static bool
compare_probes (const bound_probe &a, const bound_probe &b)
{
  int v;

  v = a.prob->get_provider ().compare (b.prob->get_provider ());
  if (v != 0)
    return v < 0;

  v = a.prob->get_name ().compare (b.prob->get_name ());
  if (v != 0)
    return v < 0;

  if (a.prob->get_address () != b.prob->get_address ())
    return a.prob->get_address () < b.prob->get_address ();

  return strcmp (objfile_name (a.objfile), objfile_name (b.objfile)) < 0;
}

/* 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 (const std::vector<bound_probe> &probes,
			      const static_probe_ops *spops)
{
  /* `headings' refers to the names of the columns when printing `info
     probes'.  */
  gdb_assert (spops != NULL);

  std::vector<struct info_probe_column> headings
    = spops->gen_info_probes_table_header ();

  for (const info_probe_column &column : headings)
    {
      size_t size_max = strlen (column.print_name);

      for (const bound_probe &probe : probes)
	{
	  /* `probe_fields' refers to the values of each new field that this
	     probe will display.  */

	  if (probe.prob->get_static_ops () != spops)
	    continue;

	  std::vector<const char *> probe_fields
	    = probe.prob->gen_info_probes_table_values ();

	  gdb_assert (probe_fields.size () == headings.size ());

	  for (const char *val : probe_fields)
	    {
	      /* 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);
	    }
	}

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

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

static void
print_ui_out_not_applicables (const static_probe_ops *spops)
{
   std::vector<struct info_probe_column> headings
     = spops->gen_info_probes_table_header ();

  for (const info_probe_column &column : headings)
    current_uiout->field_string (column.field_name, _("n/a"));
}

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

static void
print_ui_out_info (probe *probe)
{
  /* `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.  */
  gdb_assert (probe != NULL);
  std::vector<struct info_probe_column> headings
    = probe->get_static_ops ()->gen_info_probes_table_header ();
  std::vector<const char *> values
    = probe->gen_info_probes_table_values ();

  gdb_assert (headings.size () == values.size ());

  for (int ix = 0; ix < headings.size (); ++ix)
    {
      struct info_probe_column column = headings[ix];
      const char *val = values[ix];

      if (val == NULL)
	current_uiout->field_skip (column.field_name);
      else
	current_uiout->field_string (column.field_name, val);
    }
}

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

static int
get_number_extra_fields (const static_probe_ops *spops)
{
  return spops->gen_info_probes_table_header ().size ();
}

/* Helper function that returns true if there is a probe in PROBES
   featuring the given SPOPS.  It returns false otherwise.  */

static bool
exists_probe_with_spops (const std::vector<bound_probe> &probes,
			 const static_probe_ops *spops)
{
  for (const bound_probe &probe : probes)
    if (probe.prob->get_static_ops () == spops)
      return true;

  return false;
}

/* 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, std::string *provider,
		      std::string *probe_name, std::string *objname)
{
  *probe_name = *objname = "";

  *provider = extract_arg (&str);
  if (!provider->empty ())
    {
      *probe_name = extract_arg (&str);
      if (!probe_name->empty ())
	*objname = extract_arg (&str);
    }
}

/* See comment in probe.h.  */

void
info_probes_for_spops (const char *arg, int from_tty,
		       const static_probe_ops *spops)
{
  std::string provider, probe_name, objname;
  int 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 gdbarch *gdbarch = get_current_arch ();

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

  std::vector<bound_probe> probes
    = collect_probes (objname, provider, probe_name, spops);

  if (spops == &any_static_probe_ops)
    {
      /* If SPOPS is &any_static_probe_ops, 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 static_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 static_probe_ops for which no probes are
	 defined with the given search criteria.  */

      for (const static_probe_ops *po : all_static_probe_ops)
	if (exists_probe_with_spops (probes, po))
	  ui_out_extra_fields += get_number_extra_fields (po);
    }
  else
    ui_out_extra_fields = get_number_extra_fields (spops);

  {
    ui_out_emit_table table_emitter (current_uiout,
				     5 + ui_out_extra_fields,
				     probes.size (), "StaticProbes");

    std::sort (probes.begin (), probes.end (), 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 (const bound_probe &probe : probes)
      {
	const char *probe_type = probe.prob->get_static_ops ()->type_name ();

	size_type = std::max (strlen (probe_type), size_type);
	size_name = std::max (probe.prob->get_name ().size (), size_name);
	size_provider = std::max (probe.prob->get_provider ().size (),
				  size_provider);
	size_objname = std::max (strlen (objfile_name (probe.objfile)),
				 size_objname);
      }

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

    if (spops == &any_static_probe_ops)
      {
	/* 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 (const static_probe_ops *po : all_static_probe_ops)
	  if (exists_probe_with_spops (probes, po))
	    gen_ui_out_table_header_info (probes, po);
      }
    else
      gen_ui_out_table_header_info (probes, spops);

    current_uiout->table_header (size_objname, ui_left, "object", _("Object"));
    current_uiout->table_body ();

    for (const bound_probe &probe : probes)
      {
	const char *probe_type = probe.prob->get_static_ops ()->type_name ();

	ui_out_emit_tuple tuple_emitter (current_uiout, "probe");

	current_uiout->field_string ("type", probe_type);
	current_uiout->field_string ("provider", probe.prob->get_provider ());
	current_uiout->field_string ("name", probe.prob->get_name ());
	current_uiout->field_core_addr ("addr", probe.prob->get_gdbarch (),
					probe.prob->get_relocated_address
					(probe.objfile));

	if (spops == &any_static_probe_ops)
	  {
	    for (const static_probe_ops *po : all_static_probe_ops)
	      {
		if (probe.prob->get_static_ops () == po)
		  print_ui_out_info (probe.prob);
		else if (exists_probe_with_spops (probes, po))
		  print_ui_out_not_applicables (po);
	      }
	  }
	else
	  print_ui_out_info (probe.prob);

	current_uiout->field_string ("object",
				     objfile_name (probe.objfile));
	current_uiout->text ("\n");
      }

    any_found = !probes.empty ();
  }

  if (!any_found)
    current_uiout->message (_("No probes matched.\n"));
}

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

static void
info_probes_command (const char *arg, int from_tty)
{
  info_probes_for_spops (arg, from_tty, &any_static_probe_ops);
}

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

static void
enable_probes_command (const char *arg, int from_tty)
{
  std::string provider, probe_name, objname;

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

  std::vector<bound_probe> probes
    = collect_probes (objname, provider, probe_name, &any_static_probe_ops);
  if (probes.empty ())
    {
      current_uiout->message (_("No probes matched.\n"));
      return;
    }

  /* Enable the selected probes, provided their backends support the
     notion of enabling a probe.  */
  for (const bound_probe &probe: probes)
    {
      if (probe.prob->get_static_ops ()->can_enable ())
	{
	  probe.prob->enable ();
	  current_uiout->message (_("Probe %s:%s enabled.\n"),
				  probe.prob->get_provider ().c_str (),
				  probe.prob->get_name ().c_str ());
	}
      else
	current_uiout->message (_("Probe %s:%s cannot be enabled.\n"),
				probe.prob->get_provider ().c_str (),
				probe.prob->get_name ().c_str ());
    }
}

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

static void
disable_probes_command (const char *arg, int from_tty)
{
  std::string provider, probe_name, objname;

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

  std::vector<bound_probe> probes
    = collect_probes (objname, provider, probe_name, &any_static_probe_ops);
  if (probes.empty ())
    {
      current_uiout->message (_("No probes matched.\n"));
      return;
    }

  /* Disable the selected probes, provided their backends support the
     notion of enabling a probe.  */
  for (const bound_probe &probe : probes)
    {
      if (probe.prob->get_static_ops ()->can_enable ())
	{
	  probe.prob->disable ();
	  current_uiout->message (_("Probe %s:%s disabled.\n"),
				  probe.prob->get_provider ().c_str (),
				  probe.prob->get_name ().c_str ());
	}
      else
	current_uiout->message (_("Probe %s:%s cannot be disabled.\n"),
				probe.prob->get_provider ().c_str (),
				probe.prob->get_name ().c_str ());
    }
}

static bool ignore_probes_p = false;
static bool ignore_probes_idx = 0;
static bool ignore_probes_verbose_p;
static gdb::optional<compiled_regex> ignore_probes_prov_pat[2];
static gdb::optional<compiled_regex> ignore_probes_name_pat[2];
static gdb::optional<compiled_regex> ignore_probes_obj_pat[2];

/* See comments in probe.h.  */

bool
ignore_probe_p (const char *provider, const char *name,
		const char *objfile_name, const char *type)
{
  if (!ignore_probes_p)
    return false;

  gdb::optional<compiled_regex> &re_prov
    = ignore_probes_prov_pat[ignore_probes_idx];
  gdb::optional<compiled_regex> &re_name
    = ignore_probes_name_pat[ignore_probes_idx];
  gdb::optional<compiled_regex> &re_obj
    = ignore_probes_obj_pat[ignore_probes_idx];

  bool res
    = ((!re_prov
	|| re_prov->exec (provider, 0, NULL, 0) == 0)
       && (!re_name
	   || re_name->exec (name, 0, NULL, 0) == 0)
       && (!re_obj
	   || re_obj->exec (objfile_name, 0, NULL, 0) == 0));

  if (res && ignore_probes_verbose_p)
    gdb_printf (gdb_stdlog, _("Ignoring %s probe %s %s in %s.\n"),
		type, provider, name, objfile_name);

  return res;
}

/* Implementation of the `maintenance ignore-probes' command.  */

static void
ignore_probes_command (const char *arg, int from_tty)
{
  std::string ignore_provider, ignore_probe_name, ignore_objname;

  bool verbose_p = false;
  if (arg != nullptr)
    {
      const char *idx = arg;
      std::string s = extract_arg (&idx);

      if (strcmp (s.c_str (), "-reset") == 0)
	{
	  if (*idx != '\0')
	    error (_("-reset: no arguments allowed"));

	  ignore_probes_p = false;
	  gdb_printf (gdb_stdout, _("ignore-probes filter has been reset\n"));
	  return;
	}

      if (strcmp (s.c_str (), "-verbose") == 0
	  || strcmp (s.c_str (), "-v") == 0)
	{
	  verbose_p = true;
	  arg = idx;
	}
    }

  parse_probe_linespec (arg, &ignore_provider, &ignore_probe_name,
			&ignore_objname);

  /* Parse the regular expressions, making sure that the old regular
     expressions are still valid if an exception is throw.  */
  int new_ignore_probes_idx = 1 - ignore_probes_idx;
  gdb::optional<compiled_regex> &re_prov
    = ignore_probes_prov_pat[new_ignore_probes_idx];
  gdb::optional<compiled_regex> &re_name
    = ignore_probes_name_pat[new_ignore_probes_idx];
  gdb::optional<compiled_regex> &re_obj
    = ignore_probes_obj_pat[new_ignore_probes_idx];
  re_prov.reset ();
  re_name.reset ();
  re_obj.reset ();
  if (!ignore_provider.empty ())
    re_prov.emplace (ignore_provider.c_str (), REG_NOSUB,
		     _("Invalid provider regexp"));
  if (!ignore_probe_name.empty ())
    re_name.emplace (ignore_probe_name.c_str (), REG_NOSUB,
		     _("Invalid probe regexp"));
  if (!ignore_objname.empty ())
    re_obj.emplace (ignore_objname.c_str (), REG_NOSUB,
		    _("Invalid object file regexp"));
  ignore_probes_idx = new_ignore_probes_idx;

  ignore_probes_p = true;
  ignore_probes_verbose_p = verbose_p;
  gdb_printf (gdb_stdout, _("ignore-probes filter has been set to:\n"));
  gdb_printf (gdb_stdout, _("PROVIDER: '%s'\n"), ignore_provider.c_str ());
  gdb_printf (gdb_stdout, _("PROBE_NAME: '%s'\n"), ignore_probe_name.c_str ());
  gdb_printf (gdb_stdout, _("OBJNAME: '%s'\n"), ignore_objname.c_str ());
}

/* See comments in probe.h.  */

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

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

  n_args = probe.prob->get_argument_count (get_frame_arch (frame));
  if (n >= n_args)
    return NULL;

  return probe.prob->evaluate_argument (n, frame);
}

/* See comment in probe.h.  */

const struct static_probe_ops *
probe_linespec_to_static_ops (const char **linespecp)
{
  for (const static_probe_ops *ops : all_static_probe_ops)
    if (ops->is_linespec (linespecp))
      return 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.  */

bool
any_static_probe_ops::is_linespec (const char **linespecp) const
{
  static const char *const keywords[] = { "-p", "-probe", NULL };

  return probe_is_linespec_by_keyword (linespecp, keywords);
}

/* Implementation of 'get_probes' method.  */

void
any_static_probe_ops::get_probes (std::vector<std::unique_ptr<probe>> *probesp,
				  struct objfile *objfile) const
{
  /* No probes can be provided by this dummy backend.  */
}

/* Implementation of the 'type_name' method.  */

const char *
any_static_probe_ops::type_name () const
{
  return NULL;
}

/* Implementation of the 'gen_info_probes_table_header' method.  */

std::vector<struct info_probe_column>
any_static_probe_ops::gen_info_probes_table_header () const
{
  return std::vector<struct info_probe_column> ();
}

/* 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, 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)
{
  frame_info_ptr 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;
  unsigned n_args;

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

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

  n_args = pc_probe.prob->get_argument_count (arch);
  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.prob->evaluate_argument (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;
  int n_args;

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

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

  n_args = pc_probe.prob->get_argument_count (expr->gdbarch);

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

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


std::vector<const static_probe_ops *> all_static_probe_ops;

void _initialize_probe ();
void
_initialize_probe ()
{
  all_static_probe_ops.push_back (&any_static_probe_ops);

  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);

  add_cmd ("ignore-probes", class_maintenance, ignore_probes_command, _("\
Ignore probes.\n\
Usage: maintenance ignore-probes [-v|-verbose] [PROVIDER [NAME [OBJECT]]]\n\
       maintenance ignore-probes -reset\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 ignore\n\
all defined probes.  To reset the ignore-probes filter, use the -reset form.\n\
Only supported for SystemTap probes."),
	   &maintenancelist);
}
