This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[FYI v2 2/3] change probes to be program-space-independent
- From: Tom Tromey <tromey at redhat dot com>
- To: gdb-patches at sourceware dot org
- Cc: Tom Tromey <tromey at redhat dot com>
- Date: Mon, 3 Mar 2014 13:11:00 -0700
- Subject: [FYI v2 2/3] change probes to be program-space-independent
- Authentication-results: sourceware.org; auth=none
- References: <1393877461-28758-1-git-send-email-tromey at redhat dot com>
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