40#include <unordered_map>
41#include "gdbsupport/hash_enum.h"
48#define STAP_BASE_SECTION_NAME ".stapsdt.base"
114 bool is_linespec (
const char **linespecp)
const override;
117 void get_probes (std::vector<std::unique_ptr<probe>> *probesp,
136 stap_probe (std::string &&name_, std::string &&provider_, CORE_ADDR address_,
137 struct gdbarch *arch_, CORE_ADDR sem_addr,
const char *args_text)
138 :
probe (
std::move (name_),
std::move (provider_), address_, arch_),
159 unsigned n)
override;
188 internal_error (_(
"Probe '%s' apparently does not have arguments, but \n"
189 "GDB is requesting its argument number %u anyway. "
190 "This should not happen. Please report this bug."),
194 internal_error (_(
"Probe '%s' has %d arguments, but GDB is requesting\n"
195 "argument %u. This should not happen. Please\n"
269 ATTRIBUTE_UNUSED_RESULT;
282 gdb_printf (file, _(
"SystemTap Probe expression debugging is %s.\n"),
294 case BINOP_LOGICAL_OR:
297 case BINOP_LOGICAL_AND:
310 case BINOP_BITWISE_IOR:
311 case BINOP_BITWISE_AND:
312 case BINOP_BITWISE_XOR:
313 case UNOP_LOGICAL_NOT:
388 op = BINOP_BITWISE_IOR;
392 op = BINOP_LOGICAL_OR;
397 op = BINOP_BITWISE_AND;
401 op = BINOP_LOGICAL_AND;
406 op = BINOP_BITWISE_XOR;
410 op = UNOP_LOGICAL_NOT;
422 gdb_assert (**s ==
'=');
427 error (_(
"Invalid opcode in expression `%s' for SystemTap"
448 return iter->second (std::move (lhs), std::move (rhs));
458 const char *probe_name)
493 error (_(
"Undefined bitness for probe '%s'."), probe_name);
509 const char **r,
const char *
const *prefixes)
511 const char *
const *p;
513 if (prefixes == NULL)
521 for (p = prefixes; *p != NULL; ++p)
522 if (strncasecmp (s, *p, strlen (*p)) == 0)
571 const char *
const *p;
580 return isdigit (*s) > 0;
583 for (p = t; *p != NULL; ++p)
585 size_t len = strlen (*p);
587 if ((len == 0 && isdigit (*s))
588 || (len > 0 && strncasecmp (s, *p, len) == 0))
616 const char **r,
const char *
const *suffixes)
618 const char *
const *p;
621 if (suffixes == NULL)
629 for (p = suffixes; *p != NULL; ++p)
630 if (strncasecmp (s, *p, strlen (*p)) == 0)
705 bool got_minus =
false;
708 bool indirect_p =
false;
715 const char *reg_prefix;
716 const char *reg_ind_prefix;
717 const char *reg_suffix;
718 const char *reg_ind_suffix;
720 using namespace expr;
729 else if (*p->
arg ==
'-')
737 if (isdigit (*p->
arg))
743 displacement = strtol (p->
arg, &endp, 10);
748 displacement = -displacement;
749 disp_op = make_operation<long_const_operation> (long_type, displacement);
756 p->
arg += strlen (reg_ind_prefix);
759 if (disp_op !=
nullptr && !indirect_p)
760 error (_(
"Invalid register displacement syntax on expression `%s'."),
765 p->
arg += strlen (reg_prefix);
772 while (isalnum (*p->
arg))
775 std::string regname (start, p->
arg - start);
779 if (isdigit (*start))
781 if (gdb_reg_prefix != NULL)
782 regname = gdb_reg_prefix + regname;
784 if (gdb_reg_suffix != NULL)
785 regname += gdb_reg_suffix;
793 error (_(
"Invalid register name `%s' on expression `%s'."),
800 std::string newregname
803 if (regname != newregname)
812 internal_error (_(
"Invalid register name '%s' after replacing it"
813 " (previous name was '%s')"),
814 newregname.c_str (), regname.c_str ());
816 regname = std::move (newregname);
820 operation_up reg = make_operation<register_operation> (std::move (regname));
833 reg = make_operation<unop_extract_operation> (std::move (reg),
839 if (disp_op !=
nullptr)
840 reg = make_operation<add_operation> (std::move (disp_op),
845 reg = make_operation<unop_cast_operation> (std::move (reg),
847 reg = make_operation<unop_ind_operation> (std::move (reg));
852 p->
arg += strlen (reg_suffix);
854 error (_(
"Missing register name suffix on expression `%s'."),
862 p->
arg += strlen (reg_ind_suffix);
864 error (_(
"Missing indirection suffix on expression `%s'."),
890 const char *int_prefix = NULL;
892 using namespace expr;
898 if (
token !=
nullptr)
904 if (*p->
arg ==
'-' || *p->
arg ==
'~' || *p->
arg ==
'+' || *p->
arg ==
'!')
908 const char *tmp = p->
arg;
909 bool has_digit =
false;
924 tmp = skip_spaces (tmp);
926 while (isdigit (*tmp))
942 if (c !=
'-' && c !=
'+')
943 error (_(
"Invalid operator `%c' for register displacement "
944 "on expression `%s'."), c, p->
saved_arg);
955 result = make_operation<unary_neg_operation> (std::move (result));
957 result = (make_operation<unary_complement_operation>
958 (std::move (result)));
960 result = (make_operation<unary_logical_not_operation>
961 (std::move (result)));
964 else if (isdigit (*p->
arg))
967 const char *tmp = p->
arg;
973 number = strtol (tmp, &endp, 10);
977 tmp = skip_spaces (tmp);
986 const char *int_suffix;
989 result = make_operation<long_const_operation> (long_type, number);
994 p->
arg += strlen (int_suffix);
996 error (_(
"Invalid constant suffix on expression `%s'."),
1002 error (_(
"Unknown numeric token on expression `%s'."),
1010 const char *int_suffix;
1012 p->
arg += strlen (int_prefix);
1013 number = strtol (p->
arg, &endp, 10);
1016 result = make_operation<long_const_operation> (long_type, number);
1019 p->
arg += strlen (int_suffix);
1021 error (_(
"Invalid constant suffix on expression `%s'."),
1028 error (_(
"Operator `%c' not recognized on expression `%s'."),
1046 if (*p->
arg ==
'-' || *p->
arg ==
'~' || *p->
arg ==
'+' || *p->
arg ==
'!'
1047 || isdigit (*p->
arg)
1050 else if (*p->
arg ==
'(')
1056 p->
arg = skip_spaces (p->
arg);
1061 p->
arg = skip_spaces (p->
arg);
1063 error (_(
"Missing close-parenthesis on expression `%s'."),
1069 p->
arg = skip_spaces (p->
arg);
1072 error (_(
"Cannot parse expression `%s'."), p->
saved_arg);
1091 gdb_assert (p->
arg != NULL);
1094 p->
arg = skip_spaces (p->
arg);
1096 using namespace expr;
1108 p->
arg = skip_spaces (p->
arg);
1116 while (*p->
arg !=
'\0' && *p->
arg !=
')' && !isspace (*p->
arg))
1118 const char *tmp_exp_buf;
1123 error (_(
"Invalid operator `%c' on expression `%s'."), *p->
arg,
1130 tmp_exp_buf = p->
arg;
1134 if (cur_prec < prec)
1143 p->
arg = tmp_exp_buf;
1145 p->
arg = skip_spaces (p->
arg);
1152 bool paren_subexp = *p->
arg ==
'(';
1156 p->
arg = skip_spaces (p->
arg);
1172 tmp_exp_buf = p->
arg;
1176 if (lookahead_prec <= prec)
1188 p->
arg = skip_spaces (p->
arg);
1234 using namespace expr;
1240 result = make_operation<unop_cast_operation> (std::move (result), atype);
1243 p.
arg = skip_spaces (p.
arg);
1260 if (cur == NULL || *cur ==
'\0' || *cur ==
':')
1263 while (*cur !=
'\0')
1266 bool got_minus =
false;
1275 if ((cur[0] ==
'-' && isdigit (cur[1]) && cur[2] ==
'@')
1276 || (isdigit (cur[0]) && cur[1] ==
'@'))
1312 warning (_(
"unrecognized bitness %s%c' for probe `%s'"),
1313 got_minus ?
"`-" :
"`", *cur,
1336 cur = skip_spaces (cur);
1368 static bool have_warned_stap_incomplete =
false;
1370 if (!have_warned_stap_incomplete)
1373"The SystemTap SDT probe support is not fully implemented on this target;\n"
1374"you will not be able to inspect the arguments of the probes.\n"
1375"Please report a bug against GDB requesting a port to this target."));
1376 have_warned_stap_incomplete =
true;
1476 gdb_byte bytes[
sizeof (LONGEST)];
1484 warning (_(
"Could not read the value of a SystemTap semaphore."));
1500 warning (_(
"Could not write the value of a SystemTap semaphore."));
1539std::vector<const char *>
1542 const char *val = NULL;
1547 return std::vector<const char *> { val };
1563 std::vector<std::unique_ptr<probe>> *probesp,
1567 int size = bfd_get_arch_size (abfd) / 8;
1572 const char *provider = (
const char *) &el->data[3 *
size];
1573 const char *
name = ((
const char *)
1574 memchr (provider,
'\0',
1575 (
char *) el->data + el->size - provider));
1579 complaint (_(
"corrupt probe name when reading `%s'"),
1598 address += base - base_ref;
1600 sem_addr += base - base_ref;
1604 const char *probe_args = ((
const char*)
1606 (
char *) el->data + el->size -
name));
1608 if (probe_args != NULL)
1611 if (probe_args == NULL
1612 || (memchr (probe_args,
'\0', (
char *) el->data + el->size -
name)
1613 != el->data + el->size - 1))
1615 complaint (_(
"corrupt probe argument when reading `%s'"),
1626 address,
gdbarch, sem_addr, probe_args);
1629 probesp->emplace_back (ret);
1639 asection *ret = NULL;
1642 if ((sect->flags & (SEC_DATA | SEC_ALLOC | SEC_HAS_CONTENTS))
1648 complaint (_(
"could not obtain base address for "
1649 "SystemTap section on objfile `%s'."),
1650 bfd_get_filename (
obfd));
1665 static const char *
const keywords[] = {
"-pstap",
"-probe-stap", NULL };
1674 (std::vector<std::unique_ptr<probe>> *probesp,
1683 struct sdt_note *iter;
1684 unsigned save_probesp_len = probesp->size ();
1692 if (elf_tdata (
obfd)->sdt_note_head == NULL)
1706 for (iter = elf_tdata (
obfd)->sdt_note_head;
1715 if (save_probesp_len == probesp->size ())
1719 complaint (_(
"could not parse SystemTap probe(s) from inferior"));
1734std::vector<struct info_probe_column>
1740 stap_probe_column.
print_name = _(
"Semaphore");
1742 return std::vector<struct info_probe_column> { stap_probe_column };
1761 _(
"Set SystemTap expression debugging."),
1762 _(
"Show SystemTap expression debugging."),
1763 _(
"When non-zero, the internal representation "
1764 "of SystemTap expressions will be printed."),
1771Show information about SystemTap static probes.\n\
1772Usage: info probes stap [PROVIDER [NAME [OBJECT]]]\n\
1773Each argument is a regular expression, used to select probes.\n\
1774PROVIDER matches probe provider names.\n\
1775NAME matches the probe names.\n\
1776OBJECT matches the executable or shared library name."),
1780 using namespace expr;
1782 stap_maker_map[BINOP_BITWISE_AND] = make_operation<bitwise_and_operation>;
1783 stap_maker_map[BINOP_BITWISE_IOR] = make_operation<bitwise_ior_operation>;
1784 stap_maker_map[BINOP_BITWISE_XOR] = make_operation<bitwise_xor_operation>;
1791 stap_maker_map[BINOP_LOGICAL_AND] = make_operation<logical_and_operation>;
1792 stap_maker_map[BINOP_LOGICAL_OR] = make_operation<logical_or_operation>;
1795 stap_maker_map[BINOP_NOTEQUAL] = make_operation<notequal_operation>;
void require_rvalue(struct agent_expr *ax, struct axs_value *value)
const std::string & get_name() const
CORE_ADDR get_address() const
struct gdbarch * get_gdbarch() const
void parse_arguments(struct gdbarch *gdbarch)
CORE_ADDR get_relocated_address(struct objfile *objfile) override
void compile_to_ax(struct agent_expr *aexpr, struct axs_value *axs_value, unsigned n) override
stap_probe(std::string &&name_, std::string &&provider_, CORE_ADDR address_, struct gdbarch *arch_, CORE_ADDR sem_addr, const char *args_text)
unsigned get_argument_count(struct gdbarch *gdbarch) override
void set_semaphore(struct objfile *objfile, struct gdbarch *gdbarch) override
struct value * evaluate_argument(unsigned n, frame_info_ptr frame) override
std::vector< const char * > gen_info_probes_table_values() const override
void clear_semaphore(struct objfile *objfile, struct gdbarch *gdbarch) override
struct stap_probe_arg * get_arg_by_number(unsigned n, struct gdbarch *gdbarch)
bool can_evaluate_arguments() const override
const char * m_unparsed_args_text
const static_probe_ops * get_static_ops() const override
std::vector< struct stap_probe_arg > m_parsed_args
bool is_linespec(const char **linespecp) const override
const char * type_name() const override
void get_probes(std::vector< std::unique_ptr< probe > > *probesp, struct objfile *objfile) const override
std::vector< struct info_probe_column > gen_info_probes_table_header() const override
struct cmd_list_element * showdebuglist
struct cmd_list_element * setdebuglist
struct cmd_list_element * add_cmd(const char *name, enum command_class theclass, const char *doc, struct cmd_list_element **list)
set_show_commands add_setshow_zuinteger_cmd(const char *name, enum command_class theclass, unsigned int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
#define complaint(FMT,...)
static void store_unsigned_integer(gdb_byte *addr, int len, enum bfd_endian byte_order, ULONGEST val)
CORE_ADDR extract_typed_address(const gdb_byte *buf, struct type *type)
static ULONGEST extract_unsigned_integer(gdb::array_view< const gdb_byte > buf, enum bfd_endian byte_order)
std::unique_ptr< expression > expression_up
struct gdbarch * get_frame_arch(frame_info_ptr this_frame)
static gdb_bfd_section_range gdb_bfd_sections(bfd *abfd)
const char * gdbarch_stap_gdb_register_suffix(struct gdbarch *gdbarch)
const char *const * gdbarch_stap_integer_suffixes(struct gdbarch *gdbarch)
const char * gdbarch_stap_gdb_register_prefix(struct gdbarch *gdbarch)
int gdbarch_addr_bit(struct gdbarch *gdbarch)
struct type * gdbarch_register_type(struct gdbarch *gdbarch, int reg_nr)
const char *const * gdbarch_stap_register_suffixes(struct gdbarch *gdbarch)
bool gdbarch_stap_adjust_register_p(struct gdbarch *gdbarch)
const char *const * gdbarch_stap_register_indirection_suffixes(struct gdbarch *gdbarch)
expr::operation_up gdbarch_stap_parse_special_token(struct gdbarch *gdbarch, struct stap_parse_info *p)
bool gdbarch_stap_parse_special_token_p(struct gdbarch *gdbarch)
const char *const * gdbarch_stap_register_indirection_prefixes(struct gdbarch *gdbarch)
int gdbarch_stap_is_single_operand(struct gdbarch *gdbarch, const char *s)
const char *const * gdbarch_stap_register_prefixes(struct gdbarch *gdbarch)
bool gdbarch_stap_is_single_operand_p(struct gdbarch *gdbarch)
std::string gdbarch_stap_adjust_register(struct gdbarch *gdbarch, struct stap_parse_info *p, const std::string ®name, int regnum)
const char *const * gdbarch_stap_integer_prefixes(struct gdbarch *gdbarch)
enum bfd_endian type_byte_order(const struct type *type)
struct type * lookup_pointer_type(struct type *type)
int is_scalar_type(struct type *type)
const struct builtin_type * builtin_type(struct gdbarch *gdbarch)
const struct language_defn * language_def(enum language lang)
std::unique_ptr< operation > operation_up
const char * objfile_name(const struct objfile *objfile)
void info_probes_for_spops(const char *arg, int from_tty, const static_probe_ops *spops)
int probe_is_linespec_by_keyword(const char **linespecp, const char *const *keywords)
std::vector< const static_probe_ops * > all_static_probe_ops
struct cmd_list_element ** info_probes_cmdlist_get(void)
bool ignore_probe_p(const char *provider, const char *name, const char *objfile_name, const char *type)
expr::operation_up binop_maker_ftype(expr::operation_up &&, expr::operation_up &&)
static bool stap_is_integer_prefix(struct gdbarch *gdbarch, const char *s, const char **r)
static std::unordered_map< exp_opcode, binop_maker_ftype *, gdb::hash_enum< exp_opcode > > stap_maker_map
static enum exp_opcode stap_get_opcode(const char **s)
static expr::operation_up stap_parse_argument_1(struct stap_parse_info *p, expr::operation_up &&lhs, enum stap_operand_prec prec) ATTRIBUTE_UNUSED_RESULT
static bool stap_is_generic_prefix(struct gdbarch *gdbarch, const char *s, const char **r, const char *const *prefixes)
@ STAP_OPERAND_PREC_LOGICAL_AND
@ STAP_OPERAND_PREC_ADD_CMP
@ STAP_OPERAND_PREC_BITWISE
@ STAP_OPERAND_PREC_LOGICAL_OR
static void show_stapexpressiondebug(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
static expression_up stap_parse_argument(const char **arg, struct type *atype, struct gdbarch *gdbarch)
static void handle_stap_probe(struct objfile *objfile, struct sdt_note *el, std::vector< std::unique_ptr< probe > > *probesp, CORE_ADDR base)
static bool stap_generic_check_suffix(struct gdbarch *gdbarch, const char *s, const char **r, const char *const *suffixes)
static void stap_modify_semaphore(CORE_ADDR address, int set, struct gdbarch *gdbarch)
static bool stap_is_register_prefix(struct gdbarch *gdbarch, const char *s, const char **r)
static struct type * stap_get_expected_argument_type(struct gdbarch *gdbarch, enum stap_arg_bitness b, const char *probe_name)
static bool stap_check_register_suffix(struct gdbarch *gdbarch, const char *s, const char **r)
static expr::operation_up stap_parse_single_operand(struct stap_parse_info *p)
static enum stap_operand_prec stap_get_operator_prec(enum exp_opcode op)
static expr::operation_up stap_make_binop(enum exp_opcode opcode, expr::operation_up &&lhs, expr::operation_up &&rhs)
static void info_probes_stap_command(const char *arg, int from_tty)
static bool stap_check_register_indirection_suffix(struct gdbarch *gdbarch, const char *s, const char **r)
static unsigned int stap_expression_debug
const stap_static_probe_ops stap_static_probe_ops
static CORE_ADDR relocate_address(CORE_ADDR address, struct objfile *objfile)
@ STAP_ARG_BITNESS_64BIT_UNSIGNED
@ STAP_ARG_BITNESS_64BIT_SIGNED
@ STAP_ARG_BITNESS_16BIT_SIGNED
@ STAP_ARG_BITNESS_16BIT_UNSIGNED
@ STAP_ARG_BITNESS_UNDEFINED
@ STAP_ARG_BITNESS_32BIT_UNSIGNED
@ STAP_ARG_BITNESS_32BIT_SIGNED
@ STAP_ARG_BITNESS_8BIT_UNSIGNED
@ STAP_ARG_BITNESS_8BIT_SIGNED
static bool stap_is_register_indirection_prefix(struct gdbarch *gdbarch, const char *s, const char **r)
static int get_stap_base_address(bfd *obfd, bfd_vma *base)
#define STAP_BASE_SECTION_NAME
static bool stap_check_integer_suffix(struct gdbarch *gdbarch, const char *s, const char **r)
static expr::operation_up stap_parse_argument_conditionally(struct stap_parse_info *p) ATTRIBUTE_UNUSED_RESULT
static bool stap_is_operator(const char *op)
static expr::operation_up stap_parse_register_operand(struct stap_parse_info *p)
void _initialize_stap_probe()
struct type * builtin_uint16
struct type * builtin_int8
struct type * builtin_long
struct type * builtin_data_ptr
struct type * builtin_uint32
struct type * builtin_uint64
struct type * builtin_int64
struct type * builtin_int32
struct type * builtin_unsigned_short
struct type * builtin_uint8
struct type * builtin_int16
void set_operation(expr::operation_up &&op)
ATTRIBUTE_UNUSED_RESULT expression_up release()
struct objfile * separate_debug_objfile_backlink
struct gdbarch * arch() const
CORE_ADDR text_section_offset() const
struct expr_builder pstate
enum stap_arg_bitness bitness
stap_probe_arg(enum stap_arg_bitness bitness_, struct type *atype_, expression_up &&aexpr_)
struct type * type() const
int target_write_memory(CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
int target_read_memory(CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
int user_reg_map_name_to_regnum(struct gdbarch *gdbarch, const char *name, int len)
const char * print_core_address(struct gdbarch *gdbarch, CORE_ADDR address)
void gdb_printf(struct ui_file *stream, const char *format,...)