/* 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 "gdbsupport/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<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 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<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.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->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 = 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 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'.  */
      gdbarch_dtrace_parse_probe_argument (gdbarch, &builder, 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 (&builder, UNOP_CAST);
	  write_exp_elt_type (&builder, arg.type);
	  write_exp_elt_opcode (&builder, UNOP_CAST);
	}

      arg.expr = builder.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 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;
  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<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'."),
		       sect->name, abfd->filename);

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