From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23953 invoked by alias); 3 Dec 2013 19:47:19 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 23933 invoked by uid 89); 3 Dec 2013 19:47:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.3 required=5.0 tests=AWL,BAYES_50,RDNS_NONE,SPF_HELO_PASS,SPF_PASS autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from Unknown (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 03 Dec 2013 19:47:14 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rB3Jl7BK028593 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 3 Dec 2013 14:47:07 -0500 Received: from barimba.redhat.com (ovpn-113-124.phx2.redhat.com [10.3.113.124]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rB3Jl5IZ006073; Tue, 3 Dec 2013 14:47:06 -0500 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 3/4] change probes to be program-space-independent Date: Tue, 03 Dec 2013 19:47:00 -0000 Message-Id: <1386100019-27379-4-git-send-email-tromey@redhat.com> In-Reply-To: <1386100019-27379-1-git-send-email-tromey@redhat.com> References: <1386100019-27379-1-git-send-email-tromey@redhat.com> X-SW-Source: 2013-12/txt/msg00094.txt.bz2 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. 2013-12-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_parse_probe_arguments): Update. (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. --- gdb/ChangeLog | 56 ++++++++++++++++++++++++ gdb/break-catch-throw.c | 18 ++++---- gdb/breakpoint.c | 19 +++++--- gdb/breakpoint.h | 3 +- gdb/elfread.c | 16 ------- gdb/infrun.c | 8 ++-- gdb/objfiles.c | 5 --- gdb/probe.c | 114 +++++++++++++++++++++++++++++------------------- gdb/probe.h | 49 ++++++++++++++++----- gdb/solib-svr4.c | 27 +++++++----- gdb/stap-probe.c | 73 ++++++++++++++++--------------- gdb/symfile-debug.c | 19 -------- gdb/symfile.h | 5 --- gdb/symtab.c | 10 +---- gdb/symtab.h | 3 ++ gdb/tracepoint.c | 12 +++-- 16 files changed, 258 insertions(+), 179 deletions(-) diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c index 76087d3..9de44d4 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); + n_args = get_probe_argument_count (pc_probe.probe); if (n_args < 2) error (_("C++ exception catchpoint has too few arguments")); if (arg0 != NULL) - *arg0 = evaluate_probe_argument (pc_probe, 0); - *arg1 = evaluate_probe_argument (pc_probe, 1); + *arg0 = evaluate_probe_argument (pc_probe.probe, 0); + *arg1 = evaluate_probe_argument (pc_probe.probe, 1); 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 57c64d8..3ead7cc 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -3271,7 +3271,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"); @@ -3432,7 +3434,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"); @@ -8970,7 +8974,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; @@ -13287,7 +13292,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; @@ -13297,7 +13304,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 be0658f..76cac9c 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; @@ -436,7 +437,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 c347230..dedecf2 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -1516,21 +1516,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. */ @@ -1554,7 +1539,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 3b55583..d79db0a 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -5620,7 +5620,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; @@ -5654,7 +5654,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 @@ -5662,9 +5662,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 ddc4d64..3c2cc77 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -853,11 +853,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 c1e0111..851b547 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) { @@ -640,18 +666,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); + n_args = get_probe_argument_count (probe.probe); if (n >= n_args) return NULL; - return evaluate_probe_argument (probe, n); + return evaluate_probe_argument (probe.probe, n); } /* See comment in probe.h. */ diff --git a/gdb/probe.h b/gdb/probe.h index d116274..9fb9aaf 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. */ @@ -95,13 +96,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. */ @@ -164,10 +167,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; @@ -176,10 +177,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. */ @@ -192,9 +210,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, @@ -219,6 +238,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 eac8793..fea2b24 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -1569,6 +1569,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; }; @@ -1580,7 +1583,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 @@ -1592,14 +1595,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; @@ -1612,11 +1616,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; @@ -1629,12 +1635,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) @@ -1933,7 +1937,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; @@ -1947,8 +1952,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); } } @@ -2033,7 +2040,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 e09d5d6..7f2d45d 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; unsigned int args_parsed : 1; @@ -917,7 +917,7 @@ static void stap_parse_probe_arguments (struct stap_probe *probe) { const char *cur; - struct gdbarch *gdbarch = get_objfile_arch (probe->p.objfile); + struct gdbarch *gdbarch = probe->p.arch; gdb_assert (!probe->args_parsed); cur = probe->args_u.text; @@ -998,6 +998,15 @@ stap_parse_probe_arguments (struct stap_probe *probe) } } +/* 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. */ @@ -1086,7 +1095,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 @@ -1166,7 +1175,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; @@ -1174,10 +1183,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); + n_args = get_probe_argument_count (pc_probe.probe); if (sel == -1) return value_from_longest (builtin_type (arch)->builtin_int, n_args); @@ -1185,7 +1194,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); + return evaluate_probe_argument (pc_probe.probe, sel); } /* This is called to compile one of the $_probe_arg* convenience @@ -1197,7 +1206,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; @@ -1205,10 +1214,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); + n_args = get_probe_argument_count (pc_probe.probe); if (sel == -1) { @@ -1223,7 +1232,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); } @@ -1275,25 +1284,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. */ @@ -1333,7 +1350,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]; @@ -1362,13 +1379,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) - 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. */ @@ -1487,18 +1500,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) - probe->sem_addr += delta; -} - static int stap_probe_is_linespec (const char **linespecp) { @@ -1528,7 +1529,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) val = print_core_address (gdbarch, probe->sem_addr); @@ -1542,7 +1543,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 4534a2a..ac10fa0 100644 --- a/gdb/symfile-debug.c +++ b/gdb/symfile-debug.c @@ -392,28 +392,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 b800385..f8da08c 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -304,11 +304,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 991f56c..0aa77b9 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -941,15 +941,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 d5daed3..6be2f2f 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -1217,6 +1217,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 2ee70b2..e6d1c45 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -1867,8 +1867,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); @@ -1964,8 +1966,10 @@ stop_tracing (char *note) but we don't really care if this semaphore goes out of sync. That's why we are decrementing it here, but not taking care in other places. */ - if (loc->probe != NULL) - loc->probe->pops->clear_semaphore (loc->probe, loc->gdbarch); + if (loc->probe.probe != NULL) + loc->probe.probe->pops->clear_semaphore (loc->probe.probe, + loc->probe.objfile, + loc->gdbarch); } } -- 1.8.1.4