/* Generic static probe support for GDB.

   Copyright (C) 2012-2021 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>
#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 (canon.c_str ());
    }

  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,
  NULL
};


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

}
