From: Tom Tromey Date: Mon, 2 Dec 2013 20:58:59 +0000 (-0700) Subject: change probes to be program-space-independent X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=729662a5221eaee2b3cd71d79afb3f612c4df904;p=binutils-gdb.git 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 * 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) : 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) : New field. : Add objfile parameter. (struct probe) : Remove field. : New field.
: 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)
: 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) : 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) : Remove. * symtab.c (init_sal): Use memset. * symtab.h (struct symtab_and_line) : New field. * tracepoint.c (start_tracing, stop_tracing): Update. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e58a42d49ec..963ca04ac60 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,58 @@ +2014-03-03 Tom Tromey + + * 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) : 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) : New field. + : Add objfile parameter. + (struct probe) : Remove field. + : New field. +
: 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)
: 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) : 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) : Remove. + * symtab.c (init_sal): Use memset. + * symtab.h (struct symtab_and_line) : New field. + * tracepoint.c (start_tracing, stop_tracing): Update. + 2014-03-03 Tom Tromey * probe.h (parse_probes, find_probe_by_pc) diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c index 5191a90dafa..72834902f0c 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 488064d95e2..2f2c6252202 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 4be9f231fa7..3c1fdfea9d3 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 88fb01809c7..79936d0ae1d 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 c57c6b38515..b7c09692ac5 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 83b89610389..e212c7055c6 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 3b0bd2839c4..623f65cb051 100644 --- a/gdb/probe.c +++ b/gdb/probe.c @@ -33,6 +33,9 @@ #include "arch-utils.h" #include +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 38cc95018ee..aa8aba8ea68 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 4c94f9f1b85..0da5692494c 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 3064614a805..6bb73232d50 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 e8491c8f501..170ba3a8f12 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 614af3c21c3..8e2569da7ab 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 e267823bd30..66d16247ee2 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 ef145d9f428..fbe58689c12 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 08541c5cc65..1ff1bda56d8 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); } }