/* DTrace probe support for GDB.

   Copyright (C) 2014-2019 Free Software Foundation, Inc.

   Contributed by Oracle, 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 "common/vec.h"
#include "elf-bfd.h"
#include "gdbtypes.h"
#include "obstack.h"
#include "objfiles.h"
#include "complaints.h"
#include "value.h"
#include "ax.h"
#include "ax-gdb.h"
#include "language.h"
#include "parser-defs.h"
#include "inferior.h"

/* The type of the ELF sections where we will find the DOF programs
   with information about probes.  */

#ifndef SHT_SUNW_dof
# define SHT_SUNW_dof	0x6ffffff4
#endif

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

struct dtrace_probe_arg
{
  dtrace_probe_arg (struct type *type_, std::string &&type_str_,
		    expression_up &&expr_)
    : type (type_), type_str (std::move (type_str_)),
      expr (std::move (expr_))
  {}

  /* The type of the probe argument.  */
  struct type *type;

  /* A string describing the type.  */
  std::string type_str;

  /* The argument converted to an internal GDB expression.  */
  expression_up expr;
};

/* The following structure represents an enabler for a probe.  */

struct dtrace_probe_enabler
{
  /* Program counter where the is-enabled probe is installed.  The
     contents (nops, whatever...) stored at this address are
     architecture dependent.  */
  CORE_ADDR address;
};

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

class dtrace_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<probe *> *probesp,
		   struct objfile *objfile) const override;

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

  /* See probe.h.  */
  bool can_enable () const override
  {
    return true;
  }

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

/* DTrace static_probe_ops.  */

const dtrace_static_probe_ops dtrace_static_probe_ops {};

/* The following structure represents a dtrace probe.  */

class dtrace_probe : public probe
{
public:
  /* Constructor for dtrace_probe.  */
  dtrace_probe (std::string &&name_, std::string &&provider_, CORE_ADDR address_,
		struct gdbarch *arch_,
		std::vector<struct dtrace_probe_arg> &&args_,
		std::vector<struct dtrace_probe_enabler> &&enablers_)
    : probe (std::move (name_), std::move (provider_), address_, arch_),
      m_args (std::move (args_)),
      m_enablers (std::move (enablers_)),
      m_args_expr_built (false)
  {}

  /* See probe.h.  */
  CORE_ADDR get_relocated_address (struct objfile *objfile) override;

  /* See probe.h.  */
  unsigned get_argument_count (struct frame_info *frame) override;

  /* See probe.h.  */
  bool can_evaluate_arguments () const override;

  /* See probe.h.  */
  struct value *evaluate_argument (unsigned n,
				   struct frame_info *frame) override;

  /* See probe.h.  */
  void compile_to_ax (struct agent_expr *aexpr,
		      struct axs_value *axs_value,
		      unsigned n) override;

  /* See probe.h.  */
  const static_probe_ops *get_static_ops () const override;

  /* See probe.h.  */
  std::vector<const char *> gen_info_probes_table_values () const override;

  /* See probe.h.  */
  void enable () override;

  /* See probe.h.  */
  void disable () override;

  /* Return the Nth argument of the probe.  */
  struct dtrace_probe_arg *get_arg_by_number (unsigned n,
					      struct gdbarch *gdbarch);

  /* Build the GDB internal expressiosn that, once evaluated, will
     calculate the values of the arguments of the probe.  */
  void build_arg_exprs (struct gdbarch *gdbarch);

  /* Determine whether the probe is "enabled" or "disabled".  A
     disabled probe is a probe in which one or more enablers are
     disabled.  */
  bool is_enabled () const;

private:
  /* A probe can have zero or more arguments.  */
  std::vector<struct dtrace_probe_arg> m_args;

  /* A probe can have zero or more "enablers" associated with it.  */
  std::vector<struct dtrace_probe_enabler> m_enablers;

  /* Whether the expressions for the arguments have been built.  */
  bool m_args_expr_built;
};

/* DOF programs can contain an arbitrary number of sections of 26
   different types.  In order to support DTrace USDT probes we only
   need to handle a subset of these section types, fortunately.  These
   section types are defined in the following enumeration.

   See linux/dtrace/dof_defines.h for a complete list of section types
   along with their values.  */

enum dtrace_dof_sect_type
{
  /* Null section.  */
  DTRACE_DOF_SECT_TYPE_NONE = 0,
  /* A dof_ecbdesc_t. */
  DTRACE_DOF_SECT_TYPE_ECBDESC = 3,
  /* A string table.  */
  DTRACE_DOF_SECT_TYPE_STRTAB = 8,
  /* A dof_provider_t  */
  DTRACE_DOF_SECT_TYPE_PROVIDER = 15,
  /* Array of dof_probe_t  */
  DTRACE_DOF_SECT_TYPE_PROBES = 16,
  /* An array of probe arg mappings.  */
  DTRACE_DOF_SECT_TYPE_PRARGS = 17,
  /* An array of probe arg offsets.  */
  DTRACE_DOF_SECT_TYPE_PROFFS = 18,
  /* An array of probe is-enabled offsets.  */
  DTRACE_DOF_SECT_TYPE_PRENOFFS = 26
};

/* The following collection of data structures map the structure of
   DOF entities.  Again, we only cover the subset of DOF used to
   implement USDT probes.

   See linux/dtrace/dof.h header for a complete list of data
   structures.  */

/* Offsets to index the dofh_ident[] array defined below.  */

enum dtrace_dof_ident
{
  /* First byte of the magic number.  */
  DTRACE_DOF_ID_MAG0 = 0,
  /* Second byte of the magic number.  */
  DTRACE_DOF_ID_MAG1 = 1,
  /* Third byte of the magic number.  */
  DTRACE_DOF_ID_MAG2 = 2,
  /* Fourth byte of the magic number.  */
  DTRACE_DOF_ID_MAG3 = 3,
  /* An enum_dof_encoding value.  */
  DTRACE_DOF_ID_ENCODING = 5
};

/* Possible values for dofh_ident[DOF_ID_ENCODING].  */

enum dtrace_dof_encoding
{
  /* The DOF program is little-endian.  */
  DTRACE_DOF_ENCODE_LSB = 1,
  /* The DOF program is big-endian.  */
  DTRACE_DOF_ENCODE_MSB = 2
};

/* A DOF header, which describes the contents of a DOF program: number
   of sections, size, etc.  */

struct dtrace_dof_hdr
{
  /* Identification bytes (see above). */
  uint8_t dofh_ident[16];
  /* File attribute flags (if any). */
  uint32_t dofh_flags;   
  /* Size of file header in bytes. */
  uint32_t dofh_hdrsize; 
  /* Size of section header in bytes. */
  uint32_t dofh_secsize; 
  /* Number of section headers. */
  uint32_t dofh_secnum;  
  /* File offset of section headers. */
  uint64_t dofh_secoff;  
  /* File size of loadable portion. */
  uint64_t dofh_loadsz;  
  /* File size of entire DOF file. */
  uint64_t dofh_filesz;  
  /* Reserved for future use. */
  uint64_t dofh_pad;     
};

/* A DOF section, whose contents depend on its type.  The several
   supported section types are described in the enum
   dtrace_dof_sect_type above.  */

struct dtrace_dof_sect
{
  /* Section type (see the define above). */
  uint32_t dofs_type;
  /* Section data memory alignment. */
  uint32_t dofs_align; 
  /* Section flags (if any). */
  uint32_t dofs_flags; 
  /* Size of section entry (if table). */
  uint32_t dofs_entsize;
  /* DOF + offset points to the section data. */
  uint64_t dofs_offset;
  /* Size of section data in bytes.  */
  uint64_t dofs_size;  
};

/* A DOF provider, which is the provider of a probe.  */

struct dtrace_dof_provider
{
  /* Link to a DTRACE_DOF_SECT_TYPE_STRTAB section. */
  uint32_t dofpv_strtab; 
  /* Link to a DTRACE_DOF_SECT_TYPE_PROBES section. */
  uint32_t dofpv_probes; 
  /* Link to a DTRACE_DOF_SECT_TYPE_PRARGS section. */
  uint32_t dofpv_prargs; 
  /* Link to a DTRACE_DOF_SECT_TYPE_PROFFS section. */
  uint32_t dofpv_proffs; 
  /* Provider name string. */
  uint32_t dofpv_name;   
  /* Provider attributes. */
  uint32_t dofpv_provattr;
  /* Module attributes. */
  uint32_t dofpv_modattr; 
  /* Function attributes. */
  uint32_t dofpv_funcattr;
  /* Name attributes. */
  uint32_t dofpv_nameattr;
  /* Args attributes. */
  uint32_t dofpv_argsattr;
  /* Link to a DTRACE_DOF_SECT_PRENOFFS section. */
  uint32_t dofpv_prenoffs;
};

/* A set of DOF probes and is-enabled probes sharing a base address
   and several attributes.  The particular locations and attributes of
   each probe are maintained in arrays in several other DOF sections.
   See the comment in dtrace_process_dof_probe for details on how
   these attributes are stored.  */

struct dtrace_dof_probe
{
  /* Probe base address or offset. */
  uint64_t dofpr_addr;   
  /* Probe function string. */
  uint32_t dofpr_func;   
  /* Probe name string. */
  uint32_t dofpr_name;   
  /* Native argument type strings. */
  uint32_t dofpr_nargv;  
  /* Translated argument type strings. */
  uint32_t dofpr_xargv;  
  /* Index of first argument mapping. */
  uint32_t dofpr_argidx; 
  /* Index of first offset entry. */
  uint32_t dofpr_offidx; 
  /* Native argument count. */
  uint8_t  dofpr_nargc;  
  /* Translated argument count. */
  uint8_t  dofpr_xargc;  
  /* Number of offset entries for probe. */
  uint16_t dofpr_noffs;  
  /* Index of first is-enabled offset. */
  uint32_t dofpr_enoffidx;
  /* Number of is-enabled offsets. */
  uint16_t dofpr_nenoffs;
  /* Reserved for future use. */
  uint16_t dofpr_pad1;   
  /* Reserved for future use. */
  uint32_t dofpr_pad2;   
};

/* DOF supports two different encodings: MSB (big-endian) and LSB
   (little-endian).  The encoding is itself encoded in the DOF header.
   The following function returns an unsigned value in the host
   endianness.  */

#define DOF_UINT(dof, field)						\
  extract_unsigned_integer ((gdb_byte *) &(field),			\
			    sizeof ((field)),				\
			    (((dof)->dofh_ident[DTRACE_DOF_ID_ENCODING] \
			      == DTRACE_DOF_ENCODE_MSB)			\
			     ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE))

/* The following macro applies a given byte offset to a DOF (a pointer
   to a dtrace_dof_hdr structure) and returns the resulting
   address.  */

#define DTRACE_DOF_PTR(dof, offset) (&((char *) (dof))[(offset)])

/* The following macro returns a pointer to the beginning of a given
   section in a DOF object.  The section is referred to by its index
   in the sections array.  */

#define DTRACE_DOF_SECT(dof, idx)					\
  ((struct dtrace_dof_sect *)						\
   DTRACE_DOF_PTR ((dof),						\
		   DOF_UINT ((dof), (dof)->dofh_secoff)			\
		   + ((idx) * DOF_UINT ((dof), (dof)->dofh_secsize))))

/* Helper function to examine the probe described by the given PROBE
   and PROVIDER data structures and add it to the PROBESP vector.
   STRTAB, OFFTAB, EOFFTAB and ARGTAB are pointers to tables in the
   DOF program containing the attributes for the probe.  */

static void
dtrace_process_dof_probe (struct objfile *objfile,
			  struct gdbarch *gdbarch,
			  std::vector<probe *> *probesp,
			  struct dtrace_dof_hdr *dof,
			  struct dtrace_dof_probe *probe,
			  struct dtrace_dof_provider *provider,
			  char *strtab, char *offtab, char *eofftab,
			  char *argtab, uint64_t strtab_size)
{
  int i, j, num_probes, num_enablers;
  char *p;

  /* Each probe section can define zero or more probes of two
     different types:

     - probe->dofpr_noffs regular probes whose program counters are
       stored in 32bit words starting at probe->dofpr_addr +
       offtab[probe->dofpr_offidx].

     - probe->dofpr_nenoffs is-enabled probes whose program counters
       are stored in 32bit words starting at probe->dofpr_addr +
       eofftab[probe->dofpr_enoffidx].

     However is-enabled probes are not probes per-se, but an
     optimization hack that is implemented in the kernel in a very
     similar way than normal probes.  This is how we support
     is-enabled probes on GDB:

     - Our probes are always DTrace regular probes.

     - Our probes can be associated with zero or more "enablers".  The
       list of enablers is built from the is-enabled probes defined in
       the Probe section.

     - Probes having a non-empty list of enablers can be enabled or
       disabled using the `enable probe' and `disable probe' commands
       respectively.  The `Enabled' column in the output of `info
       probes' will read `yes' if the enablers are activated, `no'
       otherwise.

     - Probes having an empty list of enablers are always enabled.
       The `Enabled' column in the output of `info probes' will
       read `always'.

     It follows that if there are DTrace is-enabled probes defined for
     some provider/name but no DTrace regular probes defined then the
     GDB user wont be able to enable/disable these conditionals.  */

  num_probes = DOF_UINT (dof, probe->dofpr_noffs);
  if (num_probes == 0)
    return;

  /* Build the list of enablers for the probes defined in this Probe
     DOF section.  */
  std::vector<struct dtrace_probe_enabler> enablers;
  num_enablers = DOF_UINT (dof, probe->dofpr_nenoffs);
  for (i = 0; i < num_enablers; i++)
    {
      struct dtrace_probe_enabler enabler;
      uint32_t enabler_offset
	= ((uint32_t *) eofftab)[DOF_UINT (dof, probe->dofpr_enoffidx) + i];

      enabler.address = DOF_UINT (dof, probe->dofpr_addr)
	+ DOF_UINT (dof, enabler_offset);
      enablers.push_back (enabler);
    }

  for (i = 0; i < num_probes; i++)
    {
      uint32_t probe_offset
	= ((uint32_t *) offtab)[DOF_UINT (dof, probe->dofpr_offidx) + i];

      /* Set the provider and the name of the probe.  */
      const char *probe_provider
	= strtab + DOF_UINT (dof, provider->dofpv_name);
      const char *name = strtab + DOF_UINT (dof, probe->dofpr_name);

      /* The probe address.  */
      CORE_ADDR address
	= DOF_UINT (dof, probe->dofpr_addr) + DOF_UINT (dof, probe_offset);

      /* Number of arguments in the probe.  */
      int probe_argc = DOF_UINT (dof, probe->dofpr_nargc);

      /* Store argument type descriptions.  A description of the type
         of the argument is in the (J+1)th null-terminated string
         starting at 'strtab' + 'probe->dofpr_nargv'.  */
      std::vector<struct dtrace_probe_arg> args;
      p = strtab + DOF_UINT (dof, probe->dofpr_nargv);
      for (j = 0; j < probe_argc; j++)
	{
	  expression_up expr;

	  /* Set arg.expr to ensure all fields in expr are initialized and
	     the compiler will not warn when arg is used.  */
	  std::string type_str (p);

	  /* Use strtab_size as a sentinel.  */
	  while (*p++ != '\0' && p - strtab < strtab_size)
	    ;

	  /* Try to parse a type expression from the type string.  If
	     this does not work then we set the type to `long
	     int'.  */
          struct type *type = builtin_type (gdbarch)->builtin_long;

	  TRY
	    {
	      expr = parse_expression_with_language (type_str.c_str (),
						     language_c);
	    }
	  CATCH (ex, RETURN_MASK_ERROR)
	    {
	    }
	  END_CATCH

	  if (expr != NULL && expr.get ()->elts[0].opcode == OP_TYPE)
	    type = expr.get ()->elts[1].type;

	  args.emplace_back (type, std::move (type_str), std::move (expr));
	}

      std::vector<struct dtrace_probe_enabler> enablers_copy = enablers;
      dtrace_probe *ret = new dtrace_probe (std::string (name),
					    std::string (probe_provider),
					    address, gdbarch,
					    std::move (args),
					    std::move (enablers_copy));

      /* Successfully created probe.  */
      probesp->push_back (ret);
    }
}

/* Helper function to collect the probes described in the DOF program
   whose header is pointed by DOF and add them to the PROBESP vector.
   SECT is the ELF section containing the DOF program and OBJFILE is
   its containing object file.  */

static void
dtrace_process_dof (asection *sect, struct objfile *objfile,
		    std::vector<probe *> *probesp, struct dtrace_dof_hdr *dof)
{
  struct gdbarch *gdbarch = get_objfile_arch (objfile);
  struct dtrace_dof_sect *section;
  int i;

  /* The first step is to check for the DOF magic number.  If no valid
     DOF data is found in the section then a complaint is issued to
     the user and the section skipped.  */
  if (dof->dofh_ident[DTRACE_DOF_ID_MAG0] != 0x7F
      || dof->dofh_ident[DTRACE_DOF_ID_MAG1] != 'D'
      || dof->dofh_ident[DTRACE_DOF_ID_MAG2] != 'O'
      || dof->dofh_ident[DTRACE_DOF_ID_MAG3] != 'F')
    goto invalid_dof_data;

  /* Make sure the encoding mark is either DTRACE_DOF_ENCODE_LSB or
     DTRACE_DOF_ENCODE_MSB.  */
  if (dof->dofh_ident[DTRACE_DOF_ID_ENCODING] != DTRACE_DOF_ENCODE_LSB
      && dof->dofh_ident[DTRACE_DOF_ID_ENCODING] != DTRACE_DOF_ENCODE_MSB)
    goto invalid_dof_data;

  /* Make sure this DOF is not an enabling DOF, i.e. there are no ECB
     Description sections.  */
  section = (struct dtrace_dof_sect *) DTRACE_DOF_PTR (dof,
						       DOF_UINT (dof, dof->dofh_secoff));
  for (i = 0; i < DOF_UINT (dof, dof->dofh_secnum); i++, section++)
    if (section->dofs_type == DTRACE_DOF_SECT_TYPE_ECBDESC)
      return;

  /* Iterate over any section of type Provider and extract the probe
     information from them.  If there are no "provider" sections on
     the DOF then we just return.  */
  section = (struct dtrace_dof_sect *) DTRACE_DOF_PTR (dof,
						       DOF_UINT (dof, dof->dofh_secoff));
  for (i = 0; i < DOF_UINT (dof, dof->dofh_secnum); i++, section++)
    if (DOF_UINT (dof, section->dofs_type) == DTRACE_DOF_SECT_TYPE_PROVIDER)
      {
	struct dtrace_dof_provider *provider = (struct dtrace_dof_provider *)
	  DTRACE_DOF_PTR (dof, DOF_UINT (dof, section->dofs_offset));
	struct dtrace_dof_sect *strtab_s
	  = DTRACE_DOF_SECT (dof, DOF_UINT (dof, provider->dofpv_strtab));
	struct dtrace_dof_sect *probes_s
	  = DTRACE_DOF_SECT (dof, DOF_UINT (dof, provider->dofpv_probes));
	struct dtrace_dof_sect *args_s
	  = DTRACE_DOF_SECT (dof, DOF_UINT (dof, provider->dofpv_prargs));
	struct dtrace_dof_sect *offsets_s
	  = DTRACE_DOF_SECT (dof, DOF_UINT (dof, provider->dofpv_proffs));
	struct dtrace_dof_sect *eoffsets_s
	  = DTRACE_DOF_SECT (dof, DOF_UINT (dof, provider->dofpv_prenoffs));
	char *strtab  = DTRACE_DOF_PTR (dof, DOF_UINT (dof, strtab_s->dofs_offset));
	char *offtab  = DTRACE_DOF_PTR (dof, DOF_UINT (dof, offsets_s->dofs_offset));
	char *eofftab = DTRACE_DOF_PTR (dof, DOF_UINT (dof, eoffsets_s->dofs_offset));
	char *argtab  = DTRACE_DOF_PTR (dof, DOF_UINT (dof, args_s->dofs_offset));
	unsigned int entsize = DOF_UINT (dof, probes_s->dofs_entsize);
	int num_probes;

	if (DOF_UINT (dof, section->dofs_size)
	    < sizeof (struct dtrace_dof_provider))
	  {
	    /* The section is smaller than expected, so do not use it.
	       This has been observed on x86-solaris 10.  */
	    goto invalid_dof_data;
	  }

	/* Very, unlikely, but could crash gdb if not handled
	   properly.  */
	if (entsize == 0)
	  goto invalid_dof_data;

	num_probes = DOF_UINT (dof, probes_s->dofs_size) / entsize;

	for (i = 0; i < num_probes; i++)
	  {
	    struct dtrace_dof_probe *probe = (struct dtrace_dof_probe *)
	      DTRACE_DOF_PTR (dof, DOF_UINT (dof, probes_s->dofs_offset)
			      + (i * DOF_UINT (dof, probes_s->dofs_entsize)));

	    dtrace_process_dof_probe (objfile,
				      gdbarch, probesp,
				      dof, probe,
				      provider, strtab, offtab, eofftab, argtab,
				      DOF_UINT (dof, strtab_s->dofs_size));
	  }
      }

  return;
	  
 invalid_dof_data:
  complaint (_("skipping section '%s' which does not contain valid DOF data."),
	     sect->name);
}

/* Implementation of 'build_arg_exprs' method.  */

void
dtrace_probe::build_arg_exprs (struct gdbarch *gdbarch)
{
  size_t argc = 0;
  m_args_expr_built = true;

  /* Iterate over the arguments in the probe and build the
     corresponding GDB internal expression that will generate the
     value of the argument when executed at the PC of the probe.  */
  for (dtrace_probe_arg &arg : m_args)
    {
      /* Initialize the expression buffer in the parser state.  The
	 language does not matter, since we are using our own
	 parser.  */
      parser_state pstate (10, current_language, gdbarch);

      /* The argument value, which is ABI dependent and casted to
	 `long int'.  */
      gdbarch_dtrace_parse_probe_argument (gdbarch, &pstate, argc);

      /* Casting to the expected type, but only if the type was
	 recognized at probe load time.  Otherwise the argument will
	 be evaluated as the long integer passed to the probe.  */
      if (arg.type != NULL)
	{
	  write_exp_elt_opcode (&pstate, UNOP_CAST);
	  write_exp_elt_type (&pstate, arg.type);
	  write_exp_elt_opcode (&pstate, UNOP_CAST);
	}

      arg.expr = pstate.release ();
      prefixify_expression (arg.expr.get ());
      ++argc;
    }
}

/* Implementation of 'get_arg_by_number' method.  */

struct dtrace_probe_arg *
dtrace_probe::get_arg_by_number (unsigned n, struct gdbarch *gdbarch)
{
  if (!m_args_expr_built)
    this->build_arg_exprs (gdbarch);

  if (n > m_args.size ())
    internal_error (__FILE__, __LINE__,
		    _("Probe '%s' has %d arguments, but GDB is requesting\n"
		      "argument %u.  This should not happen.  Please\n"
		      "report this bug."),
		    this->get_name ().c_str (),
		    (int) m_args.size (), n);

  return &m_args[n];
}

/* Implementation of the probe is_enabled method.  */

bool
dtrace_probe::is_enabled () const
{
  struct gdbarch *gdbarch = this->get_gdbarch ();

  for (const dtrace_probe_enabler &enabler : m_enablers)
    if (!gdbarch_dtrace_probe_is_enabled (gdbarch, enabler.address))
      return false;

  return true;
}

/* Implementation of the get_probe_address method.  */

CORE_ADDR
dtrace_probe::get_relocated_address (struct objfile *objfile)
{
  return this->get_address () + ANOFFSET (objfile->section_offsets,
					  SECT_OFF_DATA (objfile));
}

/* Implementation of the get_argument_count method.  */

unsigned
dtrace_probe::get_argument_count (struct frame_info *frame)
{
  return m_args.size ();
}

/* Implementation of the can_evaluate_arguments method.  */

bool
dtrace_probe::can_evaluate_arguments () const
{
  struct gdbarch *gdbarch = this->get_gdbarch ();

  return gdbarch_dtrace_parse_probe_argument_p (gdbarch);
}

/* Implementation of the evaluate_argument method.  */

struct value *
dtrace_probe::evaluate_argument (unsigned n,
				 struct frame_info *frame)
{
  struct gdbarch *gdbarch = this->get_gdbarch ();
  struct dtrace_probe_arg *arg;
  int pos = 0;

  arg = this->get_arg_by_number (n, gdbarch);
  return evaluate_subexp_standard (arg->type, arg->expr.get (), &pos,
				   EVAL_NORMAL);
}

/* Implementation of the compile_to_ax method.  */

void
dtrace_probe::compile_to_ax (struct agent_expr *expr, struct axs_value *value,
			     unsigned n)
{
  struct dtrace_probe_arg *arg;
  union exp_element *pc;

  arg = this->get_arg_by_number (n, expr->gdbarch);

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

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

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

const static_probe_ops *
dtrace_probe::get_static_ops () const
{
  return &dtrace_static_probe_ops;
}

/* Implementation of the gen_info_probes_table_values method.  */

std::vector<const char *>
dtrace_probe::gen_info_probes_table_values () const
{
  const char *val = NULL;

  if (m_enablers.empty ())
    val = "always";
  else if (!gdbarch_dtrace_probe_is_enabled_p (this->get_gdbarch ()))
    val = "unknown";
  else if (this->is_enabled ())
    val = "yes";
  else
    val = "no";

  return std::vector<const char *> { val };
}

/* Implementation of the enable method.  */

void
dtrace_probe::enable ()
{
  struct gdbarch *gdbarch = this->get_gdbarch ();

  /* Enabling a dtrace probe implies patching the text section of the
     running process, so make sure the inferior is indeed running.  */
  if (inferior_ptid == null_ptid)
    error (_("No inferior running"));

  /* Fast path.  */
  if (this->is_enabled ())
    return;

  /* Iterate over all defined enabler in the given probe and enable
     them all using the corresponding gdbarch hook.  */
  for (const dtrace_probe_enabler &enabler : m_enablers)
    if (gdbarch_dtrace_enable_probe_p (gdbarch))
      gdbarch_dtrace_enable_probe (gdbarch, enabler.address);
}


/* Implementation of the disable_probe method.  */

void
dtrace_probe::disable ()
{
  struct gdbarch *gdbarch = this->get_gdbarch ();

  /* Disabling a dtrace probe implies patching the text section of the
     running process, so make sure the inferior is indeed running.  */
  if (inferior_ptid == null_ptid)
    error (_("No inferior running"));

  /* Fast path.  */
  if (!this->is_enabled ())
    return;

  /* Are we trying to disable a probe that does not have any enabler
     associated?  */
  if (m_enablers.empty ())
    error (_("Probe %s:%s cannot be disabled: no enablers."),
	   this->get_provider ().c_str (), this->get_name ().c_str ());

  /* Iterate over all defined enabler in the given probe and disable
     them all using the corresponding gdbarch hook.  */
  for (dtrace_probe_enabler &enabler : m_enablers)
    if (gdbarch_dtrace_disable_probe_p (gdbarch))
      gdbarch_dtrace_disable_probe (gdbarch, enabler.address);
}

/* Implementation of the is_linespec method.  */

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

  return probe_is_linespec_by_keyword (linespecp, keywords);
}

/* Implementation of the get_probes method.  */

void
dtrace_static_probe_ops::get_probes (std::vector<probe *> *probesp,
				     struct objfile *objfile) const
{
  bfd *abfd = objfile->obfd;
  asection *sect = NULL;

  /* Do nothing in case this is a .debug file, instead of the objfile
     itself.  */
  if (objfile->separate_debug_objfile_backlink != NULL)
    return;

  /* Iterate over the sections in OBJFILE looking for DTrace
     information.  */
  for (sect = abfd->sections; sect != NULL; sect = sect->next)
    {
      if (elf_section_data (sect)->this_hdr.sh_type == SHT_SUNW_dof)
	{
	  bfd_byte *dof;

	  /* Read the contents of the DOF section and then process it to
	     extract the information of any probe defined into it.  */
	  if (!bfd_malloc_and_get_section (abfd, sect, &dof))
	    complaint (_("could not obtain the contents of"
			 "section '%s' in objfile `%s'."),
		       sect->name, abfd->filename);
      
	  dtrace_process_dof (sect, objfile, probesp,
			      (struct dtrace_dof_hdr *) dof);
	  xfree (dof);
	}
    }
}

/* Implementation of the type_name method.  */

const char *
dtrace_static_probe_ops::type_name () const
{
  return "dtrace";
}

/* Implementation of the gen_info_probes_table_header method.  */

std::vector<struct info_probe_column>
dtrace_static_probe_ops::gen_info_probes_table_header () const
{
  struct info_probe_column dtrace_probe_column;

  dtrace_probe_column.field_name = "enabled";
  dtrace_probe_column.print_name = _("Enabled");

  return std::vector<struct info_probe_column> { dtrace_probe_column };
}

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

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

void
_initialize_dtrace_probe (void)
{
  all_static_probe_ops.push_back (&dtrace_static_probe_ops);

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