bfd/binutils: support for gdb target descriptions in the core file
[binutils-gdb.git] / gdb / stap-probe.c
index b6de873d2c935a42e21c6b19bcb667a3b5959348..bbdfbcd026737fe6cc763a3bd11851eb1837ec75 100644 (file)
@@ -1,6 +1,6 @@
 /* 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.
 
@@ -20,7 +20,6 @@
 #include "defs.h"
 #include "stap-probe.h"
 #include "probe.h"
-#include "gdbsupport/vec.h"
 #include "ui-out.h"
 #include "objfiles.h"
 #include "arch-utils.h"
@@ -102,6 +101,12 @@ struct stap_probe_arg
 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;
 
@@ -136,7 +141,7 @@ public:
   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;
@@ -838,9 +843,9 @@ stap_parse_register_operand (struct stap_parse_info *p)
    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')
 
@@ -865,7 +870,7 @@ stap_parse_single_operand (struct stap_parse_info *p)
       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.  */
@@ -919,6 +924,8 @@ stap_parse_single_operand (struct stap_parse_info *p)
            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))
@@ -1007,7 +1014,7 @@ stap_parse_argument_conditionally (struct stap_parse_info *p)
 {
   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);
@@ -1022,11 +1029,12 @@ stap_parse_argument_conditionally (struct stap_parse_info *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);
@@ -1062,6 +1070,9 @@ stap_parse_argument_1 (struct stap_parse_info *p, bool has_lhs,
       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.
 
@@ -1099,8 +1110,21 @@ stap_parse_argument_1 (struct stap_parse_info *p, bool has_lhs,
       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.  */
@@ -1125,6 +1149,8 @@ stap_parse_argument_1 (struct stap_parse_info *p, bool has_lhs,
          /* 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);
@@ -1285,8 +1311,7 @@ stap_probe::parse_arguments (struct gdbarch *gdbarch)
 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.  */
@@ -1301,10 +1326,8 @@ stap_probe::get_relocated_address (struct objfile *objfile)
    argument string.  */
 
 unsigned
-stap_probe::get_argument_count (struct frame_info *frame)
+stap_probe::get_argument_count (struct gdbarch *gdbarch)
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
-
   if (!m_have_parsed_args)
     {
       if (this->can_evaluate_arguments ())
@@ -1387,12 +1410,10 @@ struct value *
 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.
@@ -1428,9 +1449,6 @@ stap_modify_semaphore (CORE_ADDR address, int set, struct gdbarch *gdbarch)
   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)
     {
@@ -1438,8 +1456,8 @@ stap_modify_semaphore (CORE_ADDR address, int set, struct gdbarch *gdbarch)
       return;
     }
 
-  value = extract_unsigned_integer (bytes, TYPE_LENGTH (type),
-                                   gdbarch_byte_order (gdbarch));
+  enum bfd_endian byte_order = type_byte_order (type);
+  value = extract_unsigned_integer (bytes, TYPE_LENGTH (type), byte_order);
   /* Note that we explicitly don't worry about overflow or
      underflow.  */
   if (set)
@@ -1447,8 +1465,7 @@ stap_modify_semaphore (CORE_ADDR address, int set, struct gdbarch *gdbarch)
   else
     --value;
 
-  store_unsigned_integer (bytes, TYPE_LENGTH (type),
-                         gdbarch_byte_order (gdbarch), value);
+  store_unsigned_integer (bytes, TYPE_LENGTH (type), byte_order, value);
 
   if (target_write_memory (address, bytes, TYPE_LENGTH (type)) != 0)
     warning (_("Could not write the value of a SystemTap semaphore."));
@@ -1465,6 +1482,8 @@ stap_modify_semaphore (CORE_ADDR address, int set, struct gdbarch *gdbarch)
 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);
 }
 
@@ -1473,6 +1492,8 @@ stap_probe::set_semaphore (struct objfile *objfile, struct gdbarch *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);
 }
 
@@ -1515,7 +1536,7 @@ handle_stap_probe (struct objfile *objfile, struct sdt_note *el,
 {
   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.  */
@@ -1576,19 +1597,6 @@ handle_stap_probe (struct objfile *objfile, struct sdt_note *el,
   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.  */
@@ -1598,13 +1606,16 @@ get_stap_base_address (bfd *obfd, bfd_vma *base)
 {
   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;
     }
 
@@ -1707,8 +1718,9 @@ info_probes_stap_command (const char *arg, int from_tty)
   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);