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:
parent
ff8879201a
commit
729662a522
16 changed files with 256 additions and 178 deletions
|
@ -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)
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
114
gdb/probe.c
114
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. */
|
||||
|
|
49
gdb/probe.h
49
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,
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
10
gdb/symtab.c
10
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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue