/* SystemTap probe support for GDB.
- Copyright (C) 2012-2019 Free Software Foundation, Inc.
+ Copyright (C) 2012-2021 Free Software Foundation, Inc.
This file is part of GDB.
class stap_static_probe_ops : public static_probe_ops
{
public:
+ /* We need a user-provided constructor to placate some compilers.
+ See PR build/24937. */
+ stap_static_probe_ops ()
+ {
+ }
+
/* See probe.h. */
bool is_linespec (const char **linespecp) const override;
A single operand can be:
- an unary operation (e.g., `-5', `~2', or even with subexpressions
- like `-(2 + 1)')
+ like `-(2 + 1)')
- a register displacement, which will be treated as a register
- operand (e.g., `-4(%eax)' on x86)
+ operand (e.g., `-4(%eax)' on x86)
- a numeric constant, or
- a register operand (see function `stap_parse_register_operand')
return;
}
- if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+')
+ if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+' || *p->arg == '!')
{
char c = *p->arg;
/* We use this variable to do a lookahead. */
write_exp_elt_opcode (&p->pstate, UNOP_NEG);
else if (c == '~')
write_exp_elt_opcode (&p->pstate, UNOP_COMPLEMENT);
+ else if (c == '!')
+ write_exp_elt_opcode (&p->pstate, UNOP_LOGICAL_NOT);
}
}
else if (isdigit (*p->arg))
{
gdb_assert (gdbarch_stap_is_single_operand_p (p->gdbarch));
- if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+' /* Unary. */
+ if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+' || *p->arg == '!'
|| isdigit (*p->arg)
|| gdbarch_stap_is_single_operand (p->gdbarch, p->arg))
stap_parse_single_operand (p);
stap_parse_argument_1 (p, 0, STAP_OPERAND_PREC_NONE);
- --p->inside_paren_p;
+ p->arg = skip_spaces (p->arg);
if (*p->arg != ')')
- error (_("Missign close-paren on expression `%s'."),
+ error (_("Missing close-parenthesis on expression `%s'."),
p->saved_arg);
+ --p->inside_paren_p;
++p->arg;
if (p->inside_paren_p)
p->arg = skip_spaces (p->arg);
stap_parse_argument_conditionally (p);
}
+ if (p->inside_paren_p)
+ p->arg = skip_spaces (p->arg);
+
/* Start to parse the right-side, and to "join" left and right sides
depending on the operation specified.
if (p->inside_paren_p)
p->arg = skip_spaces (p->arg);
- /* Parse the right-side of the expression. */
+ /* Parse the right-side of the expression.
+
+ We save whether the right-side is a parenthesized
+ subexpression because, if it is, we will have to finish
+ processing this part of the expression before continuing. */
+ bool paren_subexp = *p->arg == '(';
+
stap_parse_argument_conditionally (p);
+ if (p->inside_paren_p)
+ p->arg = skip_spaces (p->arg);
+ if (paren_subexp)
+ {
+ write_exp_elt_opcode (&p->pstate, opcode);
+ continue;
+ }
/* While we still have operators, try to parse another
right-side, but using the current right-side as a left-side. */
/* Parse the right-side of the expression, but since we already
have a left-side at this point, set `has_lhs' to 1. */
stap_parse_argument_1 (p, 1, lookahead_prec);
+ if (p->inside_paren_p)
+ p->arg = skip_spaces (p->arg);
}
write_exp_elt_opcode (&p->pstate, opcode);
static CORE_ADDR
relocate_address (CORE_ADDR address, struct objfile *objfile)
{
- return address + ANOFFSET (objfile->section_offsets,
- SECT_OFF_DATA (objfile));
+ return address + objfile->data_section_offset ();
}
/* Implementation of the get_relocated_address method. */
stap_probe::evaluate_argument (unsigned n, struct frame_info *frame)
{
struct stap_probe_arg *arg;
- int pos = 0;
struct gdbarch *gdbarch = get_frame_arch (frame);
arg = this->get_arg_by_number (n, gdbarch);
- return evaluate_subexp_standard (arg->atype, arg->aexpr.get (), &pos,
- EVAL_NORMAL);
+ return evaluate_expression (arg->aexpr.get (), arg->atype);
}
/* Compile the probe's argument N (indexed from 0) to agent expression.
struct type *type = builtin_type (gdbarch)->builtin_unsigned_short;
ULONGEST value;
- if (address == 0)
- return;
-
/* Swallow errors. */
if (target_read_memory (address, bytes, TYPE_LENGTH (type)) != 0)
{
void
stap_probe::set_semaphore (struct objfile *objfile, struct gdbarch *gdbarch)
{
+ if (m_sem_addr == 0)
+ return;
stap_modify_semaphore (relocate_address (m_sem_addr, objfile), 1, gdbarch);
}
void
stap_probe::clear_semaphore (struct objfile *objfile, struct gdbarch *gdbarch)
{
+ if (m_sem_addr == 0)
+ return;
stap_modify_semaphore (relocate_address (m_sem_addr, objfile), 0, gdbarch);
}
{
bfd *abfd = objfile->obfd;
int size = bfd_get_arch_size (abfd) / 8;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
/* Provider and the name of the probe. */
probesp->emplace_back (ret);
}
-/* Helper function which tries to find the base address of the SystemTap
- base section named STAP_BASE_SECTION_NAME. */
-
-static void
-get_stap_base_address_1 (bfd *abfd, asection *sect, void *obj)
-{
- asection **ret = (asection **) obj;
-
- if ((sect->flags & (SEC_DATA | SEC_ALLOC | SEC_HAS_CONTENTS))
- && sect->name && !strcmp (sect->name, STAP_BASE_SECTION_NAME))
- *ret = sect;
-}
-
/* Helper function which iterates over every section in the BFD file,
trying to find the base address of the SystemTap base section.
Returns 1 if found (setting BASE to the proper value), zero otherwise. */
{
asection *ret = NULL;
- bfd_map_over_sections (obfd, get_stap_base_address_1, (void *) &ret);
+ for (asection *sect : gdb_bfd_sections (obfd))
+ if ((sect->flags & (SEC_DATA | SEC_ALLOC | SEC_HAS_CONTENTS))
+ && sect->name && !strcmp (sect->name, STAP_BASE_SECTION_NAME))
+ ret = sect;
if (ret == NULL)
{
complaint (_("could not obtain base address for "
"SystemTap section on objfile `%s'."),
- obfd->filename);
+ bfd_get_filename (obfd));
return 0;
}
info_probes_for_spops (arg, from_tty, &stap_static_probe_ops);
}
+void _initialize_stap_probe ();
void
-_initialize_stap_probe (void)
+_initialize_stap_probe ()
{
all_static_probe_ops.push_back (&stap_static_probe_ops);