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.
This commit is contained in:
Tom Tromey 2013-12-02 13:58:59 -07:00
parent ff8879201a
commit 729662a522
16 changed files with 256 additions and 178 deletions

View 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)

View 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"));

View 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);
}

View 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;

View 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. */

View 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;
}

View 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;
}

View 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);
/* 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. */

View 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,

View 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]);

View 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);
}
@ -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,

View 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
};
/* Debugging version of struct sym_fns. */

View 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

View 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));
}

View 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);

View 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);
}
}