change probes to be program-space-independent
authorTom Tromey <tromey@redhat.com>
Mon, 2 Dec 2013 20:58:59 +0000 (13:58 -0700)
committerTom Tromey <tromey@redhat.com>
Mon, 3 Mar 2014 19:47:20 +0000 (12:47 -0700)
This changes the probes to be independent of the program space.

After this, when a probe's address is needed, it is determined by
applying offsets at the point of use.

This introduces a bound_probe object, similar to bound minimal
symbols.  Objects of this type are used when it's necessary to pass a
probe and its corresponding objfile.

This removes the backlink from probe to objfile, which was primarily
used to fetch the architecture to use.

This adds a get_probe_address function which calls a probe method to
compute the probe's relocated address.  Similarly, it adds an objfile
parameter to the semaphore methods so they can do the relocation
properly as well.

2014-03-03  Tom Tromey  <tromey@redhat.com>

* break-catch-throw.c (fetch_probe_arguments): Use bound probes.
* breakpoint.c (create_longjmp_master_breakpoint): Use
get_probe_address.
(add_location_to_breakpoint, bkpt_probe_insert_location)
(bkpt_probe_remove_location): Update.
* breakpoint.h (struct bp_location) <probe>: Now a bound_probe.
* elfread.c (elf_symfile_relocate_probe): Remove.
(elf_probe_fns): Update.
(insert_exception_resume_breakpoint): Change type of "probe"
parameter to bound_probe.
(check_exception_resume): Update.
* objfiles.c (objfile_relocate1): Don't relocate probes.
* probe.c (bound_probe_s): New typedef.
(parse_probes): Use get_probe_address.  Set sal's objfile.
(find_probe_by_pc): Return a bound_probe.
(collect_probes): Return a VEC(bound_probe_s).
(compare_probes): Update.
(gen_ui_out_table_header_info): Change type of "probes"
parameter.  Update.
(info_probes_for_ops): Update.
(get_probe_address): New function.
(probe_safe_evaluate_at_pc): Update.
* probe.h (struct probe_ops) <get_probe_address>: New field.
<set_semaphore, clear_semaphore>: Add objfile parameter.
(struct probe) <objfile>: Remove field.
<arch>: New field.
<address>: Update comment.
(struct bound_probe): New.
(find_probe_by_pc): Return a bound_probe.
(get_probe_address): Declare.
* solib-svr4.c (struct probe_and_action) <address>: New field.
(hash_probe_and_action, equal_probe_and_action): Update.
(register_solib_event_probe): Add address parameter.
(solib_event_probe_at): Update.
(svr4_create_probe_breakpoints): Add objfile parameter.  Use
get_probe_address.
* stap-probe.c (struct stap_probe) <sem_addr>: Update comment.
(stap_get_probe_address): New function.
(stap_can_evaluate_probe_arguments, compute_probe_arg)
(compile_probe_arg): Update.
(stap_set_semaphore, stap_clear_semaphore): Compute semaphore's
address.
(handle_stap_probe): Don't relocate the probe.
(stap_relocate): Remove.
(stap_gen_info_probes_table_values): Update.
(stap_probe_ops): Remove stap_relocate.
* symfile-debug.c (debug_sym_relocate_probe): Remove.
(debug_sym_probe_fns): Update.
* symfile.h (struct sym_probe_fns) <sym_relocate_probe>: Remove.
* symtab.c (init_sal): Use memset.
* symtab.h (struct symtab_and_line) <objfile>: New field.
* tracepoint.c (start_tracing, stop_tracing): Update.

16 files changed:
gdb/ChangeLog
gdb/break-catch-throw.c
gdb/breakpoint.c
gdb/breakpoint.h
gdb/elfread.c
gdb/infrun.c
gdb/objfiles.c
gdb/probe.c
gdb/probe.h
gdb/solib-svr4.c
gdb/stap-probe.c
gdb/symfile-debug.c
gdb/symfile.h
gdb/symtab.c
gdb/symtab.h
gdb/tracepoint.c

index e58a42d49ec9b1b85fe0ecb0ce187a1d81c0c451..963ca04ac6066b16ff21ae7ff87a81607254ef14 100644 (file)
@@ -1,3 +1,58 @@
+2014-03-03  Tom Tromey  <tromey@redhat.com>
+
+       * break-catch-throw.c (fetch_probe_arguments): Use bound probes.
+       * breakpoint.c (create_longjmp_master_breakpoint): Use
+       get_probe_address.
+       (add_location_to_breakpoint, bkpt_probe_insert_location)
+       (bkpt_probe_remove_location): Update.
+       * breakpoint.h (struct bp_location) <probe>: Now a bound_probe.
+       * elfread.c (elf_symfile_relocate_probe): Remove.
+       (elf_probe_fns): Update.
+       (insert_exception_resume_breakpoint): Change type of "probe"
+       parameter to bound_probe.
+       (check_exception_resume): Update.
+       * objfiles.c (objfile_relocate1): Don't relocate probes.
+       * probe.c (bound_probe_s): New typedef.
+       (parse_probes): Use get_probe_address.  Set sal's objfile.
+       (find_probe_by_pc): Return a bound_probe.
+       (collect_probes): Return a VEC(bound_probe_s).
+       (compare_probes): Update.
+       (gen_ui_out_table_header_info): Change type of "probes"
+       parameter.  Update.
+       (info_probes_for_ops): Update.
+       (get_probe_address): New function.
+       (probe_safe_evaluate_at_pc): Update.
+       * probe.h (struct probe_ops) <get_probe_address>: New field.
+       <set_semaphore, clear_semaphore>: Add objfile parameter.
+       (struct probe) <objfile>: Remove field.
+       <arch>: New field.
+       <address>: Update comment.
+       (struct bound_probe): New.
+       (find_probe_by_pc): Return a bound_probe.
+       (get_probe_address): Declare.
+       * solib-svr4.c (struct probe_and_action) <address>: New field.
+       (hash_probe_and_action, equal_probe_and_action): Update.
+       (register_solib_event_probe): Add address parameter.
+       (solib_event_probe_at): Update.
+       (svr4_create_probe_breakpoints): Add objfile parameter.  Use
+       get_probe_address.
+       * stap-probe.c (struct stap_probe) <sem_addr>: Update comment.
+       (stap_get_probe_address): New function.
+       (stap_can_evaluate_probe_arguments, compute_probe_arg)
+       (compile_probe_arg): Update.
+       (stap_set_semaphore, stap_clear_semaphore): Compute semaphore's
+       address.
+       (handle_stap_probe): Don't relocate the probe.
+       (stap_relocate): Remove.
+       (stap_gen_info_probes_table_values): Update.
+       (stap_probe_ops): Remove stap_relocate.
+       * symfile-debug.c (debug_sym_relocate_probe): Remove.
+       (debug_sym_probe_fns): Update.
+       * symfile.h (struct sym_probe_fns) <sym_relocate_probe>: Remove.
+       * symtab.c (init_sal): Use memset.
+       * symtab.h (struct symtab_and_line) <objfile>: New field.
+       * tracepoint.c (start_tracing, stop_tracing): Update.
+
 2014-03-03  Tom Tromey  <tromey@redhat.com>
 
        * probe.h (parse_probes, find_probe_by_pc)
index 5191a90dafac37ba043861dacd3b8f95a6b448ab..72834902f0ca6a0d827223cf7b7297a0995f0a84 100644 (file)
@@ -106,25 +106,25 @@ fetch_probe_arguments (struct value **arg0, struct value **arg1)
 {
   struct frame_info *frame = get_selected_frame (_("No frame selected"));
   CORE_ADDR pc = get_frame_pc (frame);
-  struct probe *pc_probe;
+  struct bound_probe pc_probe;
   const struct sym_probe_fns *pc_probe_fns;
   unsigned n_args;
 
   pc_probe = find_probe_by_pc (pc);
-  if (pc_probe == NULL
-      || strcmp (pc_probe->provider, "libstdcxx") != 0
-      || (strcmp (pc_probe->name, "catch") != 0
-         && strcmp (pc_probe->name, "throw") != 0
-         && strcmp (pc_probe->name, "rethrow") != 0))
+  if (pc_probe.probe == NULL
+      || strcmp (pc_probe.probe->provider, "libstdcxx") != 0
+      || (strcmp (pc_probe.probe->name, "catch") != 0
+         && strcmp (pc_probe.probe->name, "throw") != 0
+         && strcmp (pc_probe.probe->name, "rethrow") != 0))
     error (_("not stopped at a C++ exception catchpoint"));
 
-  n_args = get_probe_argument_count (pc_probe, frame);
+  n_args = get_probe_argument_count (pc_probe.probe, frame);
   if (n_args < 2)
     error (_("C++ exception catchpoint has too few arguments"));
 
   if (arg0 != NULL)
-    *arg0 = evaluate_probe_argument (pc_probe, 0, frame);
-  *arg1 = evaluate_probe_argument (pc_probe, 1, frame);
+    *arg0 = evaluate_probe_argument (pc_probe.probe, 0, frame);
+  *arg1 = evaluate_probe_argument (pc_probe.probe, 1, frame);
 
   if ((arg0 != NULL && *arg0 == NULL) || *arg1 == NULL)
     error (_("error computing probe argument at c++ exception catchpoint"));
index 488064d95e29d2c11e646c04ea3766986fe35a27..2f2c6252202ad4b794fe6747e2923eabbaa6773f 100644 (file)
@@ -3323,7 +3323,9 @@ create_longjmp_master_breakpoint (void)
            {
              struct breakpoint *b;
 
-             b = create_internal_breakpoint (gdbarch, probe->address,
+             b = create_internal_breakpoint (gdbarch,
+                                             get_probe_address (probe,
+                                                                objfile),
                                              bp_longjmp_master,
                                              &internal_breakpoint_ops);
              b->addr_string = xstrdup ("-probe-stap libc:longjmp");
@@ -3484,7 +3486,9 @@ create_exception_master_breakpoint (void)
            {
              struct breakpoint *b;
 
-             b = create_internal_breakpoint (gdbarch, probe->address,
+             b = create_internal_breakpoint (gdbarch,
+                                             get_probe_address (probe,
+                                                                objfile),
                                              bp_exception_master,
                                              &internal_breakpoint_ops);
              b->addr_string = xstrdup ("-probe-stap libgcc:unwind");
@@ -9023,7 +9027,8 @@ add_location_to_breakpoint (struct breakpoint *b,
   loc->requested_address = sal->pc;
   loc->address = adjusted_address;
   loc->pspace = sal->pspace;
-  loc->probe = sal->probe;
+  loc->probe.probe = sal->probe;
+  loc->probe.objfile = sal->objfile;
   gdb_assert (loc->pspace != NULL);
   loc->section = sal->section;
   loc->gdbarch = loc_gdbarch;
@@ -13340,7 +13345,9 @@ bkpt_probe_insert_location (struct bp_location *bl)
     {
       /* The insertion was successful, now let's set the probe's semaphore
         if needed.  */
-      bl->probe->pops->set_semaphore (bl->probe, bl->gdbarch);
+      bl->probe.probe->pops->set_semaphore (bl->probe.probe,
+                                           bl->probe.objfile,
+                                           bl->gdbarch);
     }
 
   return v;
@@ -13350,7 +13357,9 @@ static int
 bkpt_probe_remove_location (struct bp_location *bl)
 {
   /* Let's clear the semaphore before removing the location.  */
-  bl->probe->pops->clear_semaphore (bl->probe, bl->gdbarch);
+  bl->probe.probe->pops->clear_semaphore (bl->probe.probe,
+                                         bl->probe.objfile,
+                                         bl->gdbarch);
 
   return bkpt_remove_location (bl);
 }
index 4be9f231fa729df917414b5a21e98933abe10724..3c1fdfea9d376f575f5d2e5fa8e570b28aa1e960 100644 (file)
@@ -25,6 +25,7 @@
 #include "ax.h"
 #include "command.h"
 #include "break-common.h"
+#include "probe.h"
 
 struct value;
 struct block;
@@ -437,7 +438,7 @@ struct bp_location
 
   /* If the location comes from a probe point, this is the probe associated
      with it.  */
-  struct probe *probe;
+  struct bound_probe probe;
 
   char *function_name;
 
index 88fb01809c7d31f05f13dc6015121eb416b079fe..79936d0ae1d39286aece499852b6d895db704216 100644 (file)
@@ -1524,21 +1524,6 @@ elf_get_probes (struct objfile *objfile)
   return probes_per_objfile;
 }
 
-/* Implementation of `sym_relocate_probe', as documented in symfile.h.  */
-
-static void
-elf_symfile_relocate_probe (struct objfile *objfile,
-                           const struct section_offsets *new_offsets,
-                           const struct section_offsets *delta)
-{
-  int ix;
-  VEC (probe_p) *probes = objfile_data (objfile, probe_key);
-  struct probe *probe;
-
-  for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
-    probe->pops->relocate (probe, ANOFFSET (delta, SECT_OFF_TEXT (objfile)));
-}
-
 /* Helper function used to free the space allocated for storing SystemTap
    probe information.  */
 
@@ -1562,7 +1547,6 @@ probe_key_free (struct objfile *objfile, void *d)
 static const struct sym_probe_fns elf_probe_fns =
 {
   elf_get_probes,                  /* sym_get_probes */
-  elf_symfile_relocate_probe,      /* sym_relocate_probe */
 };
 
 /* Register that we are able to handle ELF object file formats.  */
index c57c6b3851524de2a4913925575b06e98b55c9cd..b7c09692ac53f39b3440304cea8f5c1423e3e71a 100644 (file)
@@ -5651,7 +5651,7 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
 
 static void
 insert_exception_resume_from_probe (struct thread_info *tp,
-                                   const struct probe *probe,
+                                   const struct bound_probe *probe,
                                    struct frame_info *frame)
 {
   struct value *arg_value;
@@ -5685,7 +5685,7 @@ check_exception_resume (struct execution_control_state *ecs,
                        struct frame_info *frame)
 {
   volatile struct gdb_exception e;
-  const struct probe *probe;
+  struct bound_probe probe;
   struct symbol *func;
 
   /* First see if this exception unwinding breakpoint was set via a
@@ -5693,9 +5693,9 @@ check_exception_resume (struct execution_control_state *ecs,
      CFA and the HANDLER.  We ignore the CFA, extract the handler, and
      set a breakpoint there.  */
   probe = find_probe_by_pc (get_frame_pc (frame));
-  if (probe)
+  if (probe.probe)
     {
-      insert_exception_resume_from_probe (ecs->event_thread, probe, frame);
+      insert_exception_resume_from_probe (ecs->event_thread, &probe, frame);
       return;
     }
 
index 83b896103892772690a1d9ade88a4c6219a2a55e..e212c7055c6ed60afd72cddff698d13f4b653b00 100644 (file)
@@ -820,11 +820,6 @@ objfile_relocate1 (struct objfile *objfile,
                                obj_section_addr (s));
     }
 
-  /* Relocating probes.  */
-  if (objfile->sf && objfile->sf->sym_probe_fns)
-    objfile->sf->sym_probe_fns->sym_relocate_probe (objfile,
-                                                   new_offsets, delta);
-
   /* Data changed.  */
   return 1;
 }
index 3b0bd2839c482ee3f495ee77eb47f072cda5870b..623f65cb05176d129a09c7b3156c206019ce9193 100644 (file)
@@ -33,6 +33,9 @@
 #include "arch-utils.h"
 #include <ctype.h>
 
+typedef struct bound_probe bound_probe_s;
+DEF_VEC_O (bound_probe_s);
+
 \f
 
 /* See definition in probe.h.  */
@@ -144,11 +147,12 @@ parse_probes (char **argptr, struct linespec_result *canonical)
 
            init_sal (sal);
 
-           sal->pc = probe->address;
+           sal->pc = get_probe_address (probe, objfile);
            sal->explicit_pc = 1;
            sal->section = find_pc_overlay (sal->pc);
            sal->pspace = pspace;
            sal->probe = probe;
+           sal->objfile = objfile;
          }
       }
 
@@ -204,10 +208,14 @@ find_probes_in_objfile (struct objfile *objfile, const char *provider,
 
 /* See definition in probe.h.  */
 
-struct probe *
+struct bound_probe
 find_probe_by_pc (CORE_ADDR pc)
 {
   struct objfile *objfile;
+  struct bound_probe result;
+
+  result.objfile = NULL;
+  result.probe = NULL;
 
   ALL_OBJFILES (objfile)
   {
@@ -215,17 +223,22 @@ find_probe_by_pc (CORE_ADDR pc)
     int ix;
     struct probe *probe;
 
-    if (!objfile->sf || !objfile->sf->sym_probe_fns)
+    if (!objfile->sf || !objfile->sf->sym_probe_fns
+       || objfile->sect_index_text == -1)
       continue;
 
     /* If this proves too inefficient, we can replace with a hash.  */
     probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
     for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
-      if (probe->address == pc)
-       return probe;
+      if (get_probe_address (probe, objfile) == pc)
+       {
+         result.objfile = objfile;
+         result.probe = probe;
+         return result;
+       }
   }
 
-  return NULL;
+  return result;
 }
 
 \f
@@ -234,16 +247,16 @@ find_probe_by_pc (CORE_ADDR pc)
    If POPS is not NULL, only probes of this certain probe_ops will match.
    Each argument is a regexp, or NULL, which matches anything.  */
 
-static VEC (probe_p) *
+static VEC (bound_probe_s) *
 collect_probes (char *objname, char *provider, char *probe_name,
                const struct probe_ops *pops)
 {
   struct objfile *objfile;
-  VEC (probe_p) *result = NULL;
+  VEC (bound_probe_s) *result = NULL;
   struct cleanup *cleanup, *cleanup_temps;
   regex_t obj_pat, prov_pat, probe_pat;
 
-  cleanup = make_cleanup (VEC_cleanup (probe_p), &result);
+  cleanup = make_cleanup (VEC_cleanup (bound_probe_s), &result);
 
   cleanup_temps = make_cleanup (null_cleanup, NULL);
   if (provider != NULL)
@@ -272,6 +285,8 @@ collect_probes (char *objname, char *provider, char *probe_name,
 
       for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
        {
+         struct bound_probe bound;
+
          if (pops != NULL && probe->pops != pops)
            continue;
 
@@ -283,7 +298,9 @@ collect_probes (char *objname, char *provider, char *probe_name,
              && regexec (&probe_pat, probe->name, 0, NULL, 0) != 0)
            continue;
 
-         VEC_safe_push (probe_p, result, probe);
+         bound.objfile = objfile;
+         bound.probe = probe;
+         VEC_safe_push (bound_probe_s, result, &bound);
        }
     }
 
@@ -292,26 +309,26 @@ collect_probes (char *objname, char *provider, char *probe_name,
   return result;
 }
 
-/* A qsort comparison function for probe_p objects.  */
+/* A qsort comparison function for bound_probe_s objects.  */
 
 static int
 compare_probes (const void *a, const void *b)
 {
-  const struct probe *pa = *((const struct probe **) a);
-  const struct probe *pb = *((const struct probe **) b);
+  const struct bound_probe *pa = (const struct bound_probe *) a;
+  const struct bound_probe *pb = (const struct bound_probe *) b;
   int v;
 
-  v = strcmp (pa->provider, pb->provider);
+  v = strcmp (pa->probe->provider, pb->probe->provider);
   if (v)
     return v;
 
-  v = strcmp (pa->name, pb->name);
+  v = strcmp (pa->probe->name, pb->probe->name);
   if (v)
     return v;
 
-  if (pa->address < pb->address)
+  if (pa->probe->address < pb->probe->address)
     return -1;
-  if (pa->address > pb->address)
+  if (pa->probe->address > pb->probe->address)
     return 1;
 
   return strcmp (objfile_name (pa->objfile), objfile_name (pb->objfile));
@@ -321,7 +338,7 @@ compare_probes (const void *a, const void *b)
    crafted by `info_probes_for_ops'.  */
 
 static void
-gen_ui_out_table_header_info (VEC (probe_p) *probes,
+gen_ui_out_table_header_info (VEC (bound_probe_s) *probes,
                              const struct probe_ops *p)
 {
   /* `headings' refers to the names of the columns when printing `info
@@ -350,11 +367,11 @@ gen_ui_out_table_header_info (VEC (probe_p) *probes,
        VEC_iterate (info_probe_column_s, headings, ix, column);
        ++ix)
     {
-      struct probe *probe;
+      struct bound_probe *probe;
       int jx;
       size_t size_max = strlen (column->print_name);
 
-      for (jx = 0; VEC_iterate (probe_p, probes, jx, probe); ++jx)
+      for (jx = 0; VEC_iterate (bound_probe_s, probes, jx, probe); ++jx)
        {
          /* `probe_fields' refers to the values of each new field that this
             probe will display.  */
@@ -363,11 +380,11 @@ gen_ui_out_table_header_info (VEC (probe_p) *probes,
          const char *val;
          int kx;
 
-         if (probe->pops != p)
+         if (probe->probe->pops != p)
            continue;
 
          c2 = make_cleanup (VEC_cleanup (const_char_ptr), &probe_fields);
-         p->gen_info_probes_table_values (probe, &probe_fields);
+         p->gen_info_probes_table_values (probe->probe, &probe_fields);
 
          gdb_assert (VEC_length (const_char_ptr, probe_fields)
                      == headings_size);
@@ -472,14 +489,14 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
 {
   char *provider, *probe_name = NULL, *objname = NULL;
   struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
-  VEC (probe_p) *probes;
+  VEC (bound_probe_s) *probes;
   int i, any_found;
   int ui_out_extra_fields = 0;
   size_t size_addr;
   size_t size_name = strlen ("Name");
   size_t size_objname = strlen ("Object");
   size_t size_provider = strlen ("Provider");
-  struct probe *probe;
+  struct bound_probe *probe;
   struct gdbarch *gdbarch = get_current_arch ();
 
   /* Do we have a `provider:probe:objfile' style of linespec?  */
@@ -523,22 +540,23 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
   make_cleanup (VEC_cleanup (probe_p), &probes);
   make_cleanup_ui_out_table_begin_end (current_uiout,
                                       4 + ui_out_extra_fields,
-                                      VEC_length (probe_p, probes),
+                                      VEC_length (bound_probe_s, probes),
                                       "StaticProbes");
 
-  if (!VEC_empty (probe_p, probes))
-    qsort (VEC_address (probe_p, probes), VEC_length (probe_p, probes),
-          sizeof (probe_p), compare_probes);
+  if (!VEC_empty (bound_probe_s, probes))
+    qsort (VEC_address (bound_probe_s, probes),
+          VEC_length (bound_probe_s, probes),
+          sizeof (bound_probe_s), compare_probes);
 
   /* What's the size of an address in our architecture?  */
   size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10;
 
   /* Determining the maximum size of each field (`provider', `name' and
      `objname').  */
-  for (i = 0; VEC_iterate (probe_p, probes, i, probe); ++i)
+  for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
     {
-      size_name = max (strlen (probe->name), size_name);
-      size_provider = max (strlen (probe->provider), size_provider);
+      size_name = max (strlen (probe->probe->name), size_name);
+      size_provider = max (strlen (probe->probe->provider), size_provider);
       size_objname = max (strlen (objfile_name (probe->objfile)), size_objname);
     }
 
@@ -564,17 +582,17 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
                       _("Object"));
   ui_out_table_body (current_uiout);
 
-  for (i = 0; VEC_iterate (probe_p, probes, i, probe); ++i)
+  for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
     {
       struct cleanup *inner;
 
       inner = make_cleanup_ui_out_tuple_begin_end (current_uiout, "probe");
 
-      ui_out_field_string (current_uiout, "provider", probe->provider);
-      ui_out_field_string (current_uiout, "name", probe->name);
+      ui_out_field_string (current_uiout, "provider", probe->probe->provider);
+      ui_out_field_string (current_uiout, "name", probe->probe->name);
       ui_out_field_core_addr (current_uiout, "addr",
-                             get_objfile_arch (probe->objfile),
-                             probe->address);
+                             probe->probe->arch,
+                             get_probe_address (probe->probe, probe->objfile));
 
       if (pops == NULL)
        {
@@ -583,11 +601,11 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
 
          for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po);
               ++ix)
-           if (probe->pops == po)
-             print_ui_out_info (probe);
+           if (probe->probe->pops == po)
+             print_ui_out_info (probe->probe);
        }
       else
-       print_ui_out_info (probe);
+       print_ui_out_info (probe->probe);
 
       ui_out_field_string (current_uiout, "object",
                           objfile_name (probe->objfile));
@@ -596,7 +614,7 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
       do_cleanups (inner);
     }
 
-  any_found = !VEC_empty (probe_p, probes);
+  any_found = !VEC_empty (bound_probe_s, probes);
   do_cleanups (cleanup);
 
   if (!any_found)
@@ -613,6 +631,14 @@ info_probes_command (char *arg, int from_tty)
 
 /* See comments in probe.h.  */
 
+CORE_ADDR
+get_probe_address (struct probe *probe, struct objfile *objfile)
+{
+  return probe->pops->get_probe_address (probe, objfile);
+}
+
+/* See comments in probe.h.  */
+
 unsigned
 get_probe_argument_count (struct probe *probe, struct frame_info *frame)
 {
@@ -641,18 +667,18 @@ evaluate_probe_argument (struct probe *probe, unsigned n,
 struct value *
 probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n)
 {
-  struct probe *probe;
+  struct bound_probe probe;
   unsigned n_args;
 
   probe = find_probe_by_pc (get_frame_pc (frame));
-  if (!probe)
+  if (!probe.probe)
     return NULL;
 
-  n_args = get_probe_argument_count (probe, frame);
+  n_args = get_probe_argument_count (probe.probe, frame);
   if (n >= n_args)
     return NULL;
 
-  return evaluate_probe_argument (probe, n, frame);
+  return evaluate_probe_argument (probe.probe, n, frame);
 }
 
 /* See comment in probe.h.  */
index 38cc95018ee3e1a6ca09f2a00f31b5f45aee6be6..aa8aba8ea6838d9a19d99239a7516636a9114e14 100644 (file)
@@ -64,10 +64,11 @@ struct probe_ops
 
     void (*get_probes) (VEC (probe_p) **probes, struct objfile *objfile);
 
-    /* Function used to relocate addresses from PROBE according to some DELTA
-       provided.  */
+    /* Compute the probe's relocated address.  OBJFILE is the objfile
+       in which the probe originated.  */
 
-    void (*relocate) (struct probe *probe, CORE_ADDR delta);
+    CORE_ADDR (*get_probe_address) (struct probe *probe,
+                                   struct objfile *objfile);
 
     /* Return the number of arguments of PROBE.  */
 
@@ -97,13 +98,15 @@ struct probe_ops
        sense if the probe has a concept of semaphore associated to a
        probe.  */
 
-    void (*set_semaphore) (struct probe *probe, struct gdbarch *gdbarch);
+    void (*set_semaphore) (struct probe *probe, struct objfile *objfile,
+                          struct gdbarch *gdbarch);
 
     /* Clear the semaphore associated with the PROBE.  This function only
        makes sense if the probe has a concept of semaphore associated to
        a probe.  */
 
-    void (*clear_semaphore) (struct probe *probe, struct gdbarch *gdbarch);
+    void (*clear_semaphore) (struct probe *probe, struct objfile *objfile,
+                            struct gdbarch *gdbarch);
 
     /* Function called to destroy PROBE's specific data.  This function
        shall not free PROBE itself.  */
@@ -166,10 +169,8 @@ struct probe
     /* The operations associated with this probe.  */
     const struct probe_ops *pops;
 
-    /* The objfile which contains this probe.  Even if the probe is also
-       present in a separate debug objfile, this variable always points to
-       the non-separate debug objfile.  */
-    struct objfile *objfile;
+    /* The probe's architecture.  */
+    struct gdbarch *arch;
 
     /* The name of the probe.  */
     const char *name;
@@ -178,10 +179,27 @@ struct probe
        the objfile which contains the probe.  */
     const char *provider;
 
-    /* The address where the probe is inserted.  */
+    /* The address where the probe is inserted, relative to
+       SECT_OFF_TEXT.  */
     CORE_ADDR address;
   };
 
+/* A bound probe holds a pointer to a probe and a pointer to the
+   probe's defining objfile.  This is needed because probes are
+   independent of the program space and thus require relocation at
+   their point of use.  */
+
+struct bound_probe
+  {
+    /* The probe.  */
+
+    struct probe *probe;
+
+    /* The objfile in which the probe originated.  */
+
+    struct objfile *objfile;
+  };
+
 /* A helper for linespec that decodes a probe specification.  It returns a
    symtabs_and_lines object and updates *ARGPTR or throws an error.  */
 
@@ -194,9 +212,10 @@ extern struct symtabs_and_lines parse_probes (char **argptr,
 extern void register_probe_ops (struct probe *probe);
 
 /* Given a PC, find an associated probe.  If a probe is found, return
-   it.  If no probe is found, return NULL.  */
+   it.  If no probe is found, return a bound probe whose fields are
+   both NULL.  */
 
-extern struct probe *find_probe_by_pc (CORE_ADDR pc);
+extern struct bound_probe find_probe_by_pc (CORE_ADDR pc);
 
 /* Search OBJFILE for a probe with the given PROVIDER, NAME.  Return a
    VEC of all probes that were found.  If no matching probe is found,
@@ -221,6 +240,12 @@ extern void info_probes_for_ops (char *arg, int from_tty,
 
 extern struct cmd_list_element **info_probes_cmdlist_get (void);
 
+/* Compute the probe's relocated address.  OBJFILE is the objfile in
+   which the probe originated.  */
+
+extern CORE_ADDR get_probe_address (struct probe *probe,
+                                   struct objfile *objfile);
+
 /* Return the argument count of the specified probe.  */
 
 extern unsigned get_probe_argument_count (struct probe *probe,
index 4c94f9f1b85a30ef6d97c859d652fb73a6ec2997..0da5692494c19d61caf2195f3374c2349bb3b1ab 100644 (file)
@@ -1568,6 +1568,9 @@ struct probe_and_action
   /* The probe.  */
   struct probe *probe;
 
+  /* The relocated address of the probe.  */
+  CORE_ADDR address;
+
   /* The action.  */
   enum probe_action action;
 };
@@ -1579,7 +1582,7 @@ hash_probe_and_action (const void *p)
 {
   const struct probe_and_action *pa = p;
 
-  return (hashval_t) pa->probe->address;
+  return (hashval_t) pa->address;
 }
 
 /* Returns non-zero if the probe_and_actions referenced by p1 and p2
@@ -1591,14 +1594,15 @@ equal_probe_and_action (const void *p1, const void *p2)
   const struct probe_and_action *pa1 = p1;
   const struct probe_and_action *pa2 = p2;
 
-  return pa1->probe->address == pa2->probe->address;
+  return pa1->address == pa2->address;
 }
 
 /* Register a solib event probe and its associated action in the
    probes table.  */
 
 static void
-register_solib_event_probe (struct probe *probe, enum probe_action action)
+register_solib_event_probe (struct probe *probe, CORE_ADDR address,
+                           enum probe_action action)
 {
   struct svr4_info *info = get_svr4_info ();
   struct probe_and_action lookup, *pa;
@@ -1611,11 +1615,13 @@ register_solib_event_probe (struct probe *probe, enum probe_action action)
                                            xfree, xcalloc, xfree);
 
   lookup.probe = probe;
+  lookup.address = address;
   slot = htab_find_slot (info->probes_table, &lookup, INSERT);
   gdb_assert (*slot == HTAB_EMPTY_ENTRY);
 
   pa = XCNEW (struct probe_and_action);
   pa->probe = probe;
+  pa->address = address;
   pa->action = action;
 
   *slot = pa;
@@ -1628,12 +1634,10 @@ register_solib_event_probe (struct probe *probe, enum probe_action action)
 static struct probe_and_action *
 solib_event_probe_at (struct svr4_info *info, CORE_ADDR address)
 {
-  struct probe lookup_probe;
   struct probe_and_action lookup;
   void **slot;
 
-  lookup_probe.address = address;
-  lookup.probe = &lookup_probe;
+  lookup.address = address;
   slot = htab_find_slot (info->probes_table, &lookup, NO_INSERT);
 
   if (slot == NULL)
@@ -1934,7 +1938,8 @@ svr4_update_solib_event_breakpoints (void)
 
 static void
 svr4_create_probe_breakpoints (struct gdbarch *gdbarch,
-                              VEC (probe_p) **probes)
+                              VEC (probe_p) **probes,
+                              struct objfile *objfile)
 {
   int i;
 
@@ -1948,8 +1953,10 @@ svr4_create_probe_breakpoints (struct gdbarch *gdbarch,
           VEC_iterate (probe_p, probes[i], ix, probe);
           ++ix)
        {
-         create_solib_event_breakpoint (gdbarch, probe->address);
-         register_solib_event_probe (probe, action);
+         CORE_ADDR address = get_probe_address (probe, objfile);
+
+         create_solib_event_breakpoint (gdbarch, address);
+         register_solib_event_probe (probe, address, action);
        }
     }
 
@@ -2034,7 +2041,7 @@ svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch,
            }
 
          if (all_probes_found)
-           svr4_create_probe_breakpoints (gdbarch, probes);
+           svr4_create_probe_breakpoints (gdbarch, probes, os->objfile);
 
          for (i = 0; i < NUM_PROBES; i++)
            VEC_free (probe_p, probes[i]);
index 3064614a805b14b0798788aaf51fe03ed5767708..6bb73232d5036483abc2541c7db8617ab452e58d 100644 (file)
@@ -99,7 +99,7 @@ struct stap_probe
   struct probe p;
 
   /* If the probe has a semaphore associated, then this is the value of
-     it.  */
+     it, relative to SECT_OFF_DATA.  */
   CORE_ADDR sem_addr;
 
   /* One if the arguments have been parsed.  */
@@ -1151,6 +1151,15 @@ stap_parse_probe_arguments (struct stap_probe *probe, struct gdbarch *gdbarch)
     }
 }
 
+/* Implementation of the get_probe_address method.  */
+
+static CORE_ADDR
+stap_get_probe_address (struct probe *probe, struct objfile *objfile)
+{
+  return probe->address + ANOFFSET (objfile->section_offsets,
+                                   SECT_OFF_DATA (objfile));
+}
+
 /* Given PROBE, returns the number of arguments present in that probe's
    argument string.  */
 
@@ -1241,7 +1250,7 @@ static int
 stap_can_evaluate_probe_arguments (struct probe *probe_generic)
 {
   struct stap_probe *stap_probe = (struct stap_probe *) probe_generic;
-  struct gdbarch *gdbarch = get_objfile_arch (stap_probe->p.objfile);
+  struct gdbarch *gdbarch = stap_probe->p.arch;
 
   /* For SystemTap probes, we have to guarantee that the method
      stap_is_single_operand is defined on gdbarch.  If it is not, then it
@@ -1323,7 +1332,7 @@ compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar,
   struct frame_info *frame = get_selected_frame (_("No frame selected"));
   CORE_ADDR pc = get_frame_pc (frame);
   int sel = (int) (uintptr_t) data;
-  struct probe *pc_probe;
+  struct bound_probe pc_probe;
   const struct sym_probe_fns *pc_probe_fns;
   unsigned n_args;
 
@@ -1331,10 +1340,10 @@ compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar,
   gdb_assert (sel >= -1);
 
   pc_probe = find_probe_by_pc (pc);
-  if (pc_probe == NULL)
+  if (pc_probe.probe == NULL)
     error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc));
 
-  n_args = get_probe_argument_count (pc_probe, frame);
+  n_args = get_probe_argument_count (pc_probe.probe, frame);
   if (sel == -1)
     return value_from_longest (builtin_type (arch)->builtin_int, n_args);
 
@@ -1342,7 +1351,7 @@ compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar,
     error (_("Invalid probe argument %d -- probe has %u arguments available"),
           sel, n_args);
 
-  return evaluate_probe_argument (pc_probe, sel, frame);
+  return evaluate_probe_argument (pc_probe.probe, sel, frame);
 }
 
 /* This is called to compile one of the $_probe_arg* convenience
@@ -1354,7 +1363,7 @@ compile_probe_arg (struct internalvar *ivar, struct agent_expr *expr,
 {
   CORE_ADDR pc = expr->scope;
   int sel = (int) (uintptr_t) data;
-  struct probe *pc_probe;
+  struct bound_probe pc_probe;
   const struct sym_probe_fns *pc_probe_fns;
   int n_args;
   struct frame_info *frame = get_selected_frame (NULL);
@@ -1363,10 +1372,10 @@ compile_probe_arg (struct internalvar *ivar, struct agent_expr *expr,
   gdb_assert (sel >= -1);
 
   pc_probe = find_probe_by_pc (pc);
-  if (pc_probe == NULL)
+  if (pc_probe.probe == NULL)
     error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc));
 
-  n_args = get_probe_argument_count (pc_probe, frame);
+  n_args = get_probe_argument_count (pc_probe.probe, frame);
 
   if (sel == -1)
     {
@@ -1381,7 +1390,7 @@ compile_probe_arg (struct internalvar *ivar, struct agent_expr *expr,
     error (_("Invalid probe argument %d -- probe has %d arguments available"),
           sel, n_args);
 
-  pc_probe->pops->compile_to_ax (pc_probe, expr, value, sel);
+  pc_probe.probe->pops->compile_to_ax (pc_probe.probe, expr, value, sel);
 }
 
 \f
@@ -1433,25 +1442,33 @@ stap_modify_semaphore (CORE_ADDR address, int set, struct gdbarch *gdbarch)
    the probes, but that is too rare to care.  */
 
 static void
-stap_set_semaphore (struct probe *probe_generic, struct gdbarch *gdbarch)
+stap_set_semaphore (struct probe *probe_generic, struct objfile *objfile,
+                   struct gdbarch *gdbarch)
 {
   struct stap_probe *probe = (struct stap_probe *) probe_generic;
+  CORE_ADDR addr;
 
   gdb_assert (probe_generic->pops == &stap_probe_ops);
 
-  stap_modify_semaphore (probe->sem_addr, 1, gdbarch);
+  addr = (probe->sem_addr
+         + ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile)));
+  stap_modify_semaphore (addr, 1, gdbarch);
 }
 
 /* Clear a SystemTap semaphore.  SEM is the semaphore's address.  */
 
 static void
-stap_clear_semaphore (struct probe *probe_generic, struct gdbarch *gdbarch)
+stap_clear_semaphore (struct probe *probe_generic, struct objfile *objfile,
+                     struct gdbarch *gdbarch)
 {
   struct stap_probe *probe = (struct stap_probe *) probe_generic;
+  CORE_ADDR addr;
 
   gdb_assert (probe_generic->pops == &stap_probe_ops);
 
-  stap_modify_semaphore (probe->sem_addr, 0, gdbarch);
+  addr = (probe->sem_addr
+         + ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile)));
+  stap_modify_semaphore (addr, 0, gdbarch);
 }
 
 /* Implementation of `$_probe_arg*' set of variables.  */
@@ -1491,7 +1508,7 @@ handle_stap_probe (struct objfile *objfile, struct sdt_note *el,
 
   ret = obstack_alloc (&objfile->objfile_obstack, sizeof (*ret));
   ret->p.pops = &stap_probe_ops;
-  ret->p.objfile = objfile;
+  ret->p.arch = gdbarch;
 
   /* Provider and the name of the probe.  */
   ret->p.provider = (char *) &el->data[3 * size];
@@ -1520,13 +1537,9 @@ handle_stap_probe (struct objfile *objfile, struct sdt_note *el,
   /* Semaphore address.  */
   ret->sem_addr = extract_typed_address (&el->data[2 * size], ptr_type);
 
-  ret->p.address += (ANOFFSET (objfile->section_offsets,
-                              SECT_OFF_TEXT (objfile))
-                    + base - base_ref);
+  ret->p.address += base - base_ref;
   if (ret->sem_addr != 0)
-    ret->sem_addr += (ANOFFSET (objfile->section_offsets,
-                               SECT_OFF_DATA (objfile))
-                     + base - base_ref);
+    ret->sem_addr += base - base_ref;
 
   /* Arguments.  We can only extract the argument format if there is a valid
      name for this probe.  */
@@ -1647,18 +1660,6 @@ stap_get_probes (VEC (probe_p) **probesp, struct objfile *objfile)
     }
 }
 
-static void
-stap_relocate (struct probe *probe_generic, CORE_ADDR delta)
-{
-  struct stap_probe *probe = (struct stap_probe *) probe_generic;
-
-  gdb_assert (probe_generic->pops == &stap_probe_ops);
-
-  probe->p.address += delta;
-  if (probe->sem_addr != 0)
-    probe->sem_addr += delta;
-}
-
 static int
 stap_probe_is_linespec (const char **linespecp)
 {
@@ -1688,7 +1689,7 @@ stap_gen_info_probes_table_values (struct probe *probe_generic,
 
   gdb_assert (probe_generic->pops == &stap_probe_ops);
 
-  gdbarch = get_objfile_arch (probe->p.objfile);
+  gdbarch = probe->p.arch;
 
   if (probe->sem_addr != 0)
     val = print_core_address (gdbarch, probe->sem_addr);
@@ -1702,7 +1703,7 @@ static const struct probe_ops stap_probe_ops =
 {
   stap_probe_is_linespec,
   stap_get_probes,
-  stap_relocate,
+  stap_get_probe_address,
   stap_get_probe_argument_count,
   stap_can_evaluate_probe_arguments,
   stap_evaluate_probe_argument,
index e8491c8f501b2fac0d4a96b6c88dc4e258306d91..170ba3a8f12824b1ac10e0267ceb35d4ccdf4e8a 100644 (file)
@@ -391,28 +391,9 @@ debug_sym_get_probes (struct objfile *objfile)
   return retval;
 }
 
-static void
-debug_sym_relocate_probe (struct objfile *objfile,
-                         const struct section_offsets *new_offsets,
-                         const struct section_offsets *delta)
-{
-  const struct debug_sym_fns_data *debug_data =
-    objfile_data (objfile, symfile_debug_objfile_data_key);
-
-  fprintf_filtered (gdb_stdlog,
-                   "probes->sym_relocate_probe (%s, %s, %s)\n",
-                   debug_objfile_name (objfile),
-                   host_address_to_string (new_offsets),
-                   host_address_to_string (delta));
-
-  debug_data->real_sf->sym_probe_fns->sym_relocate_probe
-    (objfile, new_offsets, delta);
-}
-
 static const struct sym_probe_fns debug_sym_probe_fns =
 {
   debug_sym_get_probes,
-  debug_sym_relocate_probe
 };
 \f
 /* Debugging version of struct sym_fns.  */
index 614af3c21c3b58b90ce7f9da3eec42876233f684..8e2569da7abb82d63f41a1443e50b9a7a7ecbb37 100644 (file)
@@ -316,11 +316,6 @@ struct sym_probe_fns
      The returned value does not have to be freed and it has lifetime of the
      OBJFILE.  */
   VEC (probe_p) *(*sym_get_probes) (struct objfile *);
-
-  /* Relocate the probe section of OBJFILE.  */
-  void (*sym_relocate_probe) (struct objfile *objfile,
-                             const struct section_offsets *new_offsets,
-                             const struct section_offsets *delta);
 };
 
 /* Structure to keep track of symbol reading functions for various
index e267823bd300bc79b7d7550a92ba83d41320ba9f..66d16247ee262fadb1b2aeb37af85c2218eb60e5 100644 (file)
@@ -993,15 +993,7 @@ symbol_search_name (const struct general_symbol_info *gsymbol)
 void
 init_sal (struct symtab_and_line *sal)
 {
-  sal->pspace = NULL;
-  sal->symtab = 0;
-  sal->section = 0;
-  sal->line = 0;
-  sal->pc = 0;
-  sal->end = 0;
-  sal->explicit_pc = 0;
-  sal->explicit_line = 0;
-  sal->probe = NULL;
+  memset (sal, 0, sizeof (*sal));
 }
 \f
 
index ef145d9f4289e769ed12c925e7de9ca73193a3aa..fbe58689c12d7c7db6225f79791c54edfcf3e3e7 100644 (file)
@@ -1221,6 +1221,9 @@ struct symtab_and_line
 
   /* The probe associated with this symtab_and_line.  */
   struct probe *probe;
+  /* If PROBE is not NULL, then this is the objfile in which the probe
+     originated.  */
+  struct objfile *objfile;
 };
 
 extern void init_sal (struct symtab_and_line *sal);
index 08541c5cc650d03652ce7c416e553e3c7fc69155..1ff1bda56d88cec493bf807ffb7cf24ea8f27a60 100644 (file)
@@ -1860,8 +1860,10 @@ start_tracing (char *notes)
       t->number_on_target = b->number;
 
       for (loc = b->loc; loc; loc = loc->next)
-       if (loc->probe != NULL)
-         loc->probe->pops->set_semaphore (loc->probe, loc->gdbarch);
+       if (loc->probe.probe != NULL)
+         loc->probe.probe->pops->set_semaphore (loc->probe.probe,
+                                                loc->probe.objfile,
+                                                loc->gdbarch);
 
       if (bp_location_downloaded)
        observer_notify_breakpoint_modified (b);
@@ -1957,8 +1959,10 @@ stop_tracing (char *note)
             but we don't really care if this semaphore goes out of sync.
             That's why we are decrementing it here, but not taking care
             in other places.  */
-         if (loc->probe != NULL)
-           loc->probe->pops->clear_semaphore (loc->probe, loc->gdbarch);
+         if (loc->probe.probe != NULL)
+           loc->probe.probe->pops->clear_semaphore (loc->probe.probe,
+                                                    loc->probe.objfile,
+                                                    loc->gdbarch);
        }
     }