/* DTrace probe support for GDB.
- Copyright (C) 2014-2017 Free Software Foundation, Inc.
+ Copyright (C) 2014-2022 Free Software Foundation, Inc.
Contributed by Oracle, Inc.
#include "defs.h"
#include "probe.h"
-#include "vec.h"
#include "elf-bfd.h"
#include "gdbtypes.h"
#include "obstack.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. */
bool is_linespec (const char **linespecp) const override;
/* See probe.h. */
- void get_probes (std::vector<probe *> *probesp,
+ void get_probes (std::vector<std::unique_ptr<probe>> *probesp,
struct objfile *objfile) const override;
/* See probe.h. */
/* DTrace static_probe_ops. */
-const dtrace_static_probe_ops dtrace_static_probe_ops;
+const dtrace_static_probe_ops dtrace_static_probe_ops {};
/* The following structure represents a dtrace probe. */
CORE_ADDR get_relocated_address (struct objfile *objfile) override;
/* See probe.h. */
- unsigned get_argument_count (struct frame_info *frame) override;
+ unsigned get_argument_count (struct gdbarch *gdbarch) override;
/* See probe.h. */
bool can_evaluate_arguments () const override;
struct dtrace_probe_arg *get_arg_by_number (unsigned n,
struct gdbarch *gdbarch);
- /* Build the GDB internal expressiosn that, once evaluated, will
+ /* 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);
static void
dtrace_process_dof_probe (struct objfile *objfile,
struct gdbarch *gdbarch,
- std::vector<probe *> *probesp,
+ std::vector<std::unique_ptr<probe>> *probesp,
struct dtrace_dof_hdr *dof,
struct dtrace_dof_probe *probe,
struct dtrace_dof_provider *provider,
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'. */
+ 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++)
/* 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;
+ struct type *type = builtin_type (gdbarch)->builtin_long;
- TRY
+ try
{
- expression_up expr
- = parse_expression_with_language (type_str.c_str (),
- language_c);
+ expr = parse_expression_with_language (type_str.c_str (),
+ language_c);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
}
- END_CATCH
- if (expr != NULL && expr->elts[0].opcode == OP_TYPE)
- type = expr->elts[1].type;
+ 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::move (enablers_copy));
/* Successfully created probe. */
- probesp->push_back (ret);
+ probesp->emplace_back (ret);
}
}
static void
dtrace_process_dof (asection *sect, struct objfile *objfile,
- std::vector<probe *> *probesp, struct dtrace_dof_hdr *dof)
+ std::vector<std::unique_ptr<probe>> *probesp,
+ struct dtrace_dof_hdr *dof)
{
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
struct dtrace_dof_sect *section;
int i;
return;
invalid_dof_data:
- complaint (&symfile_complaints,
- _("skipping section '%s' which does not contain valid DOF data."),
+ complaint (_("skipping section '%s' which does not contain valid DOF data."),
sect->name);
}
/* 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 (struct dtrace_probe_arg &arg : m_args)
+ for (dtrace_probe_arg &arg : m_args)
{
- struct cleanup *back_to;
- struct parser_state pstate;
-
- /* Initialize the expression buffer in the parser state. The
- language does not matter, since we are using our own
- parser. */
- initialize_expout (&pstate, 10, current_language, gdbarch);
- back_to = make_cleanup (free_current_contents, &pstate.expout);
+ /* 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, &pstate, argc);
-
- discard_cleanups (back_to);
+ 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)
- {
- write_exp_elt_opcode (&pstate, UNOP_CAST);
- write_exp_elt_type (&pstate, arg.type);
- write_exp_elt_opcode (&pstate, UNOP_CAST);
- }
+ op = expr::make_operation<expr::unop_cast_operation> (std::move (op),
+ arg.type);
- reallocate_expout (&pstate);
- arg.expr = expression_up (pstate.expout);
- prefixify_expression (arg.expr.get ());
+ builder.set_operation (std::move (op));
+ arg.expr = builder.release ();
++argc;
}
}
{
struct gdbarch *gdbarch = this->get_gdbarch ();
- for (const struct dtrace_probe_enabler &enabler : m_enablers)
+ for (const dtrace_probe_enabler &enabler : m_enablers)
if (!gdbarch_dtrace_probe_is_enabled (gdbarch, enabler.address))
return false;
CORE_ADDR
dtrace_probe::get_relocated_address (struct objfile *objfile)
{
- return this->get_address () + ANOFFSET (objfile->section_offsets,
- SECT_OFF_DATA (objfile));
+ return this->get_address () + objfile->data_section_offset ();
}
/* Implementation of the get_argument_count method. */
unsigned
-dtrace_probe::get_argument_count (struct frame_info *frame)
+dtrace_probe::get_argument_count (struct gdbarch *gdbarch)
{
return m_args.size ();
}
{
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);
+ return evaluate_expression (arg->expr.get (), arg->type);
}
/* Implementation of the compile_to_ax method. */
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);
+ arg->expr->op->generate_ax (arg->expr.get (), expr, value);
require_rvalue (expr, value);
value->type = arg->type;
/* Enabling a dtrace probe implies patching the text section of the
running process, so make sure the inferior is indeed running. */
- if (ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid == null_ptid)
error (_("No inferior running"));
/* Fast path. */
/* Iterate over all defined enabler in the given probe and enable
them all using the corresponding gdbarch hook. */
- for (const struct dtrace_probe_enabler &enabler : m_enablers)
+ for (const dtrace_probe_enabler &enabler : m_enablers)
if (gdbarch_dtrace_enable_probe_p (gdbarch))
gdbarch_dtrace_enable_probe (gdbarch, enabler.address);
}
/* Disabling a dtrace probe implies patching the text section of the
running process, so make sure the inferior is indeed running. */
- if (ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid == null_ptid)
error (_("No inferior running"));
/* Fast path. */
/* Iterate over all defined enabler in the given probe and disable
them all using the corresponding gdbarch hook. */
- for (struct dtrace_probe_enabler &enabler : m_enablers)
+ for (dtrace_probe_enabler &enabler : m_enablers)
if (gdbarch_dtrace_disable_probe_p (gdbarch))
gdbarch_dtrace_disable_probe (gdbarch, enabler.address);
}
/* Implementation of the get_probes method. */
void
-dtrace_static_probe_ops::get_probes (std::vector<probe *> *probesp,
- struct objfile *objfile) const
+dtrace_static_probe_ops::get_probes
+ (std::vector<std::unique_ptr<probe>> *probesp,
+ struct objfile *objfile) const
{
bfd *abfd = objfile->obfd;
asection *sect = NULL;
/* 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 (&symfile_complaints,
- _("could not obtain the contents of"
+ 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);
-
- dtrace_process_dof (sect, objfile, probesp,
- (struct dtrace_dof_hdr *) dof);
+ bfd_section_name (sect), bfd_get_filename (abfd));
+
xfree (dof);
}
}
info_probes_for_spops (arg, from_tty, &dtrace_static_probe_ops);
}
+void _initialize_dtrace_probe ();
void
-_initialize_dtrace_probe (void)
+_initialize_dtrace_probe ()
{
all_static_probe_ops.push_back (&dtrace_static_probe_ops);