/* Generic static probe support for GDB.

   Copyright (C) 2012-2022 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 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;
  const char *arg_start, *cs;

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

  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->location = new_probe_location (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 ((const char *) 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 ((const char *) 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 ());
    }
}

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

}
