This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[FYI v2 2/3] change probes to be program-space-independent


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.
---
 gdb/ChangeLog           |  55 +++++++++++++++++++++++
 gdb/break-catch-throw.c |  18 ++++----
 gdb/breakpoint.c        |  19 +++++---
 gdb/breakpoint.h        |   3 +-
 gdb/elfread.c           |  16 -------
 gdb/infrun.c            |   8 ++--
 gdb/objfiles.c          |   5 ---
 gdb/probe.c             | 114 +++++++++++++++++++++++++++++-------------------
 gdb/probe.h             |  49 ++++++++++++++++-----
 gdb/solib-svr4.c        |  27 +++++++-----
 gdb/stap-probe.c        |  71 +++++++++++++++---------------
 gdb/symfile-debug.c     |  19 --------
 gdb/symfile.h           |   5 ---
 gdb/symtab.c            |  10 +----
 gdb/symtab.h            |   3 ++
 gdb/tracepoint.c        |  12 +++--
 16 files changed, 256 insertions(+), 178 deletions(-)

diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c
index 5191a90..7283490 100644
--- a/gdb/break-catch-throw.c
+++ b/gdb/break-catch-throw.c
@@ -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"));
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 488064d..2f2c625 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -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);
 }
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 4be9f23..3c1fdfe 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -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;
 
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 88fb018..79936d0 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -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.  */
diff --git a/gdb/infrun.c b/gdb/infrun.c
index c57c6b3..b7c0969 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -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;
     }
 
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 83b8961..e212c70 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -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;
 }
diff --git a/gdb/probe.c b/gdb/probe.c
index 3b0bd28..623f65c 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -33,6 +33,9 @@
 #include "arch-utils.h"
 #include <ctype.h>
 
+typedef struct bound_probe bound_probe_s;
+DEF_VEC_O (bound_probe_s);
+
 
 
 /* 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;
 }
 
 
@@ -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.  */
diff --git a/gdb/probe.h b/gdb/probe.h
index 38cc950..aa8aba8 100644
--- a/gdb/probe.h
+++ b/gdb/probe.h
@@ -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,
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 4c94f9f..0da5692 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -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]);
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index 3064614..6bb7323 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -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);
 }
 
 
@@ -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,
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index e8491c8..170ba3a 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -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
 };
 
 /* Debugging version of struct sym_fns.  */
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 614af3c..8e2569d 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -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
diff --git a/gdb/symtab.c b/gdb/symtab.c
index e267823..66d1624 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -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));
 }
 
 
diff --git a/gdb/symtab.h b/gdb/symtab.h
index ef145d9..fbe5868 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -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);
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 08541c5..1ff1bda 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -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);
 	}
     }
 
-- 
1.8.1.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]