Convert probes to type-safe registry API
authorTom Tromey <tom@tromey.com>
Wed, 1 May 2019 05:47:54 +0000 (23:47 -0600)
committerTom Tromey <tom@tromey.com>
Wed, 8 May 2019 22:01:51 +0000 (16:01 -0600)
This changes the probes code in elfread.c to use the type-safe
registry API.  While doing this, I saw that the caller of get_probes
owns the probes, so I went through the code and changed the vectors to
store unique_ptrs, making the ownership relationship more clear.

gdb/ChangeLog
2019-05-08  Tom Tromey  <tom@tromey.com>

* symfile.h (struct sym_probe_fns) <sym_get_probes>: Change type.
* symfile-debug.c (debug_sym_get_probes): Change type.
* stap-probe.c (handle_stap_probe):
(stap_static_probe_ops::get_probes): Change type.
* probe.h (class static_probe_ops) <get_probes>: Change type.
* probe.c (class any_static_probe_ops) <get_probes>: Change type.
(parse_probes_in_pspace): Update.
(find_probes_in_objfile, find_probe_by_pc, collect_probes):
Update.
(any_static_probe_ops::get_probes): Change type.
* elfread.c (elfread_data): New typedef.
(probe_key): Change type.
(elf_get_probes): Likewise.  Update.
(probe_key_free): Remove.
(_initialize_elfread): Update.
* dtrace-probe.c (class dtrace_static_probe_ops) <get_probes>:
Change type.
(dtrace_process_dof_probe, dtrace_process_dof)
(dtrace_static_probe_ops::get_probe): Change type.

gdb/ChangeLog
gdb/dtrace-probe.c
gdb/elfread.c
gdb/probe.c
gdb/probe.h
gdb/stap-probe.c
gdb/symfile-debug.c
gdb/symfile.h

index 22b1afecf4ef76405864753b3bfaf61e477158ac..bf44b765ad2efcf81e997c9b3487cf4fbdbd4d73 100644 (file)
@@ -1,3 +1,25 @@
+2019-05-08  Tom Tromey  <tom@tromey.com>
+
+       * symfile.h (struct sym_probe_fns) <sym_get_probes>: Change type.
+       * symfile-debug.c (debug_sym_get_probes): Change type.
+       * stap-probe.c (handle_stap_probe):
+       (stap_static_probe_ops::get_probes): Change type.
+       * probe.h (class static_probe_ops) <get_probes>: Change type.
+       * probe.c (class any_static_probe_ops) <get_probes>: Change type.
+       (parse_probes_in_pspace): Update.
+       (find_probes_in_objfile, find_probe_by_pc, collect_probes):
+       Update.
+       (any_static_probe_ops::get_probes): Change type.
+       * elfread.c (elfread_data): New typedef.
+       (probe_key): Change type.
+       (elf_get_probes): Likewise.  Update.
+       (probe_key_free): Remove.
+       (_initialize_elfread): Update.
+       * dtrace-probe.c (class dtrace_static_probe_ops) <get_probes>:
+       Change type.
+       (dtrace_process_dof_probe, dtrace_process_dof)
+       (dtrace_static_probe_ops::get_probe): Change type.
+
 2019-05-08  Tom Tromey  <tom@tromey.com>
 
        * xcoffread.c (struct xcoff_symfile_info): Rename from
index a51f35800ab7ab388b90eb0375b97f8f5efcef9e..52973784e9aa2353fd855481683883762c8dfb9f 100644 (file)
@@ -81,7 +81,7 @@ public:
   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.  */
@@ -380,7 +380,7 @@ struct dtrace_dof_probe
 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,
@@ -507,7 +507,7 @@ dtrace_process_dof_probe (struct objfile *objfile,
                                            std::move (enablers_copy));
 
       /* Successfully created probe.  */
-      probesp->push_back (ret);
+      probesp->emplace_back (ret);
     }
 }
 
@@ -518,7 +518,8 @@ dtrace_process_dof_probe (struct objfile *objfile,
 
 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 dtrace_dof_sect *section;
@@ -833,8 +834,9 @@ dtrace_static_probe_ops::is_linespec (const char **linespecp) const
 /* 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;
index 55a16bb2f8e1e5a08bc37c4b2d22df549b2ba4a4..deee6f0baab5b59727700080793d51e9a5484e1e 100644 (file)
@@ -64,9 +64,13 @@ struct elfinfo
     asection *mdebugsect;      /* Section pointer for .mdebug section */
   };
 
+/* Type for per-BFD data.  */
+
+typedef std::vector<std::unique_ptr<probe>> elfread_data;
+
 /* Per-BFD data for probe info.  */
 
-static const struct bfd_data *probe_key = NULL;
+static const struct bfd_key<elfread_data> probe_key;
 
 /* Minimal symbols located at the GOT entries for .plt - that is the real
    pointer where the given entry will jump to.  It gets updated by the real
@@ -1347,43 +1351,24 @@ elf_symfile_init (struct objfile *objfile)
 
 /* Implementation of `sym_get_probes', as documented in symfile.h.  */
 
-static const std::vector<probe *> &
+static const elfread_data &
 elf_get_probes (struct objfile *objfile)
 {
-  std::vector<probe *> *probes_per_bfd;
-
-  /* Have we parsed this objfile's probes already?  */
-  probes_per_bfd = (std::vector<probe *> *) bfd_data (objfile->obfd, probe_key);
+  elfread_data *probes_per_bfd = probe_key.get (objfile->obfd);
 
   if (probes_per_bfd == NULL)
     {
-      probes_per_bfd = new std::vector<probe *>;
+      probes_per_bfd = probe_key.emplace (objfile->obfd);
 
       /* Here we try to gather information about all types of probes from the
         objfile.  */
       for (const static_probe_ops *ops : all_static_probe_ops)
        ops->get_probes (probes_per_bfd, objfile);
-
-      set_bfd_data (objfile->obfd, probe_key, probes_per_bfd);
     }
 
   return *probes_per_bfd;
 }
 
-/* Helper function used to free the space allocated for storing SystemTap
-   probe information.  */
-
-static void
-probe_key_free (bfd *abfd, void *d)
-{
-  std::vector<probe *> *probes = (std::vector<probe *> *) d;
-
-  for (probe *p : *probes)
-    delete p;
-
-  delete probes;
-}
-
 \f
 
 /* Implementation `sym_probe_fns', as documented in symfile.h.  */
@@ -1475,7 +1460,6 @@ static const struct gnu_ifunc_fns elf_gnu_ifunc_fns =
 void
 _initialize_elfread (void)
 {
-  probe_key = register_bfd_data_with_cleanup (NULL, probe_key_free);
   add_symtab_fns (bfd_target_elf_flavour, &elf_sym_fns);
 
   elf_objfile_gnu_ifunc_cache_data = register_objfile_data ();
index b9337a9d19f28af49ed0f8c0338373d5faca3be1..7bc75d8e879bd8cd0932827716cec46c1d13f6d1 100644 (file)
@@ -47,7 +47,7 @@ public:
   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.  */
@@ -84,10 +84,10 @@ parse_probes_in_pspace (const static_probe_ops *spops,
                           objfile_namestr) != 0)
        continue;
 
-      const std::vector<probe *> &probes
+      const std::vector<std::unique_ptr<probe>> &probes
        = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
 
-      for (probe *p : probes)
+      for (auto &p : probes)
        {
          if (spops != &any_static_probe_ops && p->get_static_ops () != spops)
            continue;
@@ -103,7 +103,7 @@ parse_probes_in_pspace (const static_probe_ops *spops,
          sal.explicit_pc = 1;
          sal.section = find_pc_overlay (sal.pc);
          sal.pspace = search_pspace;
-         sal.prob = p;
+         sal.prob = p.get ();
          sal.objfile = objfile;
 
          result->push_back (std::move (sal));
@@ -223,9 +223,9 @@ find_probes_in_objfile (struct objfile *objfile, const char *provider,
   if (!objfile->sf || !objfile->sf->sym_probe_fns)
     return result;
 
-  const std::vector<probe *> &probes
+  const std::vector<std::unique_ptr<probe>> &probes
     = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
-  for (probe *p : probes)
+  for (auto &p : probes)
     {
       if (p->get_provider () != provider)
        continue;
@@ -233,7 +233,7 @@ find_probes_in_objfile (struct objfile *objfile, const char *provider,
       if (p->get_name () != name)
        continue;
 
-      result.push_back (p);
+      result.push_back (p.get ());
     }
 
   return result;
@@ -256,13 +256,13 @@ find_probe_by_pc (CORE_ADDR pc)
        continue;
 
       /* If this proves too inefficient, we can replace with a hash.  */
-      const std::vector<probe *> &probes
+      const std::vector<std::unique_ptr<probe>> &probes
        = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
-      for (probe *p : probes)
+      for (auto &p : probes)
        if (p->get_relocated_address (objfile) == pc)
          {
            result.objfile = objfile;
-           result.prob = p;
+           result.prob = p.get ();
            return result;
          }
     }
@@ -305,10 +305,10 @@ collect_probes (const std::string &objname, const std::string &provider,
            continue;
        }
 
-      const std::vector<probe *> &probes
+      const std::vector<std::unique_ptr<probe>> &probes
        = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
 
-      for (probe *p : probes)
+      for (auto &p : probes)
        {
          if (spops != &any_static_probe_ops && p->get_static_ops () != spops)
            continue;
@@ -321,7 +321,7 @@ collect_probes (const std::string &objname, const std::string &provider,
              && probe_pat->exec (p->get_name ().c_str (), 0, NULL, 0) != 0)
            continue;
 
-         result.emplace_back (p, objfile);
+         result.emplace_back (p.get (), objfile);
        }
     }
 
@@ -750,7 +750,7 @@ any_static_probe_ops::is_linespec (const char **linespecp) const
 /* Implementation of 'get_probes' method.  */
 
 void
-any_static_probe_ops::get_probes (std::vector<probe *> *probesp,
+any_static_probe_ops::get_probes (std::vector<std::unique_ptr<probe>> *probesp,
                                  struct objfile *objfile) const
 {
   /* No probes can be provided by this dummy backend.  */
index 2f665e3a6581e8b0a0726f2f55fef2acc493d50f..5c83f49471485dcaaedd304abd6478b166a44fc7 100644 (file)
@@ -62,7 +62,7 @@ public:
   virtual bool is_linespec (const char **linespecp) const = 0;
 
   /* Function that should fill PROBES with known probes from OBJFILE.  */
-  virtual void get_probes (std::vector<probe *> *probes,
+  virtual void get_probes (std::vector<std::unique_ptr<probe>> *probes,
                            struct objfile *objfile) const = 0;
 
   /* Return a pointer to a name identifying the probe type.  This is
index 24b2b78a9037dfce9437ca3f2fe491983f7605fe..e70940c4878b578d499a56944e0220c294f1c46b 100644 (file)
@@ -106,7 +106,7 @@ public:
   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.  */
@@ -1497,7 +1497,8 @@ stap_probe::gen_info_probes_table_values () const
 
 static void
 handle_stap_probe (struct objfile *objfile, struct sdt_note *el,
-                  std::vector<probe *> *probesp, CORE_ADDR base)
+                  std::vector<std::unique_ptr<probe>> *probesp,
+                  CORE_ADDR base)
 {
   bfd *abfd = objfile->obfd;
   int size = bfd_get_arch_size (abfd) / 8;
@@ -1561,7 +1562,7 @@ handle_stap_probe (struct objfile *objfile, struct sdt_note *el,
                                    address, gdbarch, sem_addr, probe_args);
 
   /* Successfully created probe.  */
-  probesp->push_back (ret);
+  probesp->emplace_back (ret);
 }
 
 /* Helper function which tries to find the base address of the SystemTap
@@ -1615,8 +1616,9 @@ stap_static_probe_ops::is_linespec (const char **linespecp) const
 /* Implementation of the 'get_probes' method.  */
 
 void
-stap_static_probe_ops::get_probes (std::vector<probe *> *probesp,
-                                  struct objfile *objfile) const
+stap_static_probe_ops::get_probes
+  (std::vector<std::unique_ptr<probe>> *probesp,
+   struct objfile *objfile) const
 {
   /* If we are here, then this is the first time we are parsing the
      SystemTap probe's information.  We basically have to count how many
index 8266ecbabf0523090dfd7c21867ee3d14ba2e778..0f9da66e536fab169e68fdd06545a6deead170eb 100644 (file)
@@ -382,13 +382,13 @@ static const struct quick_symbol_functions debug_sym_quick_functions =
 \f
 /* Debugging version of struct sym_probe_fns.  */
 
-static const std::vector<probe *> &
+static const std::vector<std::unique_ptr<probe>> &
 debug_sym_get_probes (struct objfile *objfile)
 {
   const struct debug_sym_fns_data *debug_data
     = symfile_debug_objfile_data_key.get (objfile);
 
-  const std::vector<probe *> &retval
+  const std::vector<std::unique_ptr<probe>> &retval
     = debug_data->real_sf->sym_probe_fns->sym_get_probes (objfile);
 
   fprintf_filtered (gdb_stdlog,
index a873dfe9451b2370e96dc0667a8250d963b7ad4f..daddd2e21abe55134815871637849a46764e4b2f 100644 (file)
@@ -292,7 +292,8 @@ struct quick_symbol_functions
 struct sym_probe_fns
 {
   /* If non-NULL, return a reference to vector of probe objects.  */
-  const std::vector<probe *> &(*sym_get_probes) (struct objfile *);
+  const std::vector<std::unique_ptr<probe>> &(*sym_get_probes)
+    (struct objfile *);
 };
 
 /* Structure to keep track of symbol reading functions for various