/* DTrace probe support for GDB.

   Copyright (C) 2014-2021 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 "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"
#include "expop.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<std::unique_ptr<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 gdbarch *gdbarch) 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 expression 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<std::unique_ptr<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 (const gdb_exception_error &ex)
	    {
	    }

	  if (expr != NULL && expr->first_opcode () == OP_TYPE)
	    type = value_type (evaluate_type (expr.get ()));

	  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->emplace_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<std::unique_ptr<probe>> *probesp,
		    struct dtrace_dof_hdr *dof)
{
  struct gdbarch *gdbarch = objfile->arch ();
  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 builder.  The language does not
	 matter, since we are using our own parser.  */
      expr_builder builder (current_language, gdbarch);

      /* The argument value, which is ABI dependent and casted to
	 `long int'.  */
      expr::operation_up op = gdbarch_dtrace_parse_probe_argument (gdbarch,
								   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)
	op = expr::make_operation<expr::unop_cast_operation> (std::move (op),
							      arg.type);

      builder.set_operation (std::move (op));
      arg.expr = builder.release ();
      ++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 () + objfile->data_section_offset ();
}

/* Implementation of the get_argument_count method.  */

unsigned
dtrace_probe::get_argument_count (struct gdbarch *gdbarch)
{
  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;

  arg = this->get_arg_by_number (n, gdbarch);
  return evaluate_expression (arg->expr.get (), arg->type);
}

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

  arg = this->get_arg_by_number (n, expr->gdbarch);
  arg->expr->op->generate_ax (arg->expr.get (), 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<std::unique_ptr<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) && dof != NULL)
	    dtrace_process_dof (sect, objfile, probesp,
				(struct dtrace_dof_hdr *) dof);
	 else
	    complaint (_("could not obtain the contents of"
			 "section '%s' in objfile `%s'."),
		       bfd_section_name (sect), bfd_get_filename (abfd));

	  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
_initialize_dtrace_probe ()
{
  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 ());
}
