]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Incremental breakpoint_re_set for linespec
authorPedro Alves <palves@redhat.com>
Fri, 1 Apr 2016 15:06:18 +0000 (16:06 +0100)
committerPedro Alves <palves@redhat.com>
Mon, 19 Sep 2016 14:44:42 +0000 (15:44 +0100)
When you have a pending breakpoint, the next bottleneck is
breakpoint_re_set again.

  $ time $g --batch -q -ex "run" -ex "c" -iex "set breakpoint pending on" -iex "b mainasdfasdf" --args ./testsuite/outputs/gdb.base/jit/jit-main   ./testsuite/outputs/gdb.base/jit/jit-solib.so 8000
  No symbol table is loaded.  Use the "file" command.
  Breakpoint 1 (mainasdfasdf) pending.
  /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.base/jit-main.c:164: libname = ./testsuite/outputs/gdb.base/jit/jit-solib.so, count = 8000
  [Inferior 1 (process 25753) exited normally]
  The program is not being run.

  real    0m31.738s
  user    0m29.221s
  sys     0m2.827s

This implement per-objfile re-set for linespece-based breakpoints.

- Hoist out plt locations when we find other breakpoint locations

It's what the linespec code does if we let it look up in the whole
program space.

- Check that the sals the linespec code returns match the search scope

- Address locations always use a program_space-wide search scope

- Fix exception.exp - we may only find the probe interface after seeing __cxa_begin_catch on other objfiles

- validate_sals

gdb/ada-lang.c
gdb/break-catch-throw.c
gdb/breakpoint.c
gdb/breakpoint.h
gdb/elfread.c
gdb/linespec.c
gdb/linespec.h
gdb/symtab.h

index 9eda7a84828f414920aa9ecb2a0b9470f523acf4..a13625fa5da60b13f980dd7b9e8e90f9966e9ffd 100644 (file)
@@ -12368,7 +12368,9 @@ create_excep_cond_exprs (struct ada_catchpoint *c,
 
   /* Iterate over all the catchpoint's locations, and parse an
      expression for each.  */
-  for (bl = c->base.loc; bl != NULL; bl = bl->next)
+  for (bl = c->base.loc;
+       bl != NULL && bp_location_matches_search_scope (bl, search_scope);
+       bl = bl->next)
     {
       struct ada_catchpoint_location *ada_loc
        = (struct ada_catchpoint_location *) bl;
index 5ffad947899eb288d032adfb6b8146dc050fea7a..efaad3acbd55daba07e492251acc21581e8c44ba 100644 (file)
@@ -212,8 +212,13 @@ re_set_exception_catchpoint (struct breakpoint *self,
   struct cleanup *cleanup;
   enum exception_event_kind kind = classify_exception_breakpoint (self);
   struct event_location *location;
+  struct sym_search_scope pspace_scope = null_search_scope ();
   struct program_space *filter_pspace = search_scope->pspace;
 
+  /* Re-set in the whole pspace for now.  */
+  pspace_scope.pspace = search_scope->pspace;
+  search_scope = &pspace_scope;
+
   /* We first try to use the probe interface.  */
   TRY
     {
@@ -236,7 +241,7 @@ re_set_exception_catchpoint (struct breakpoint *self,
            = ASTRDUP (exception_functions[kind].function);
          location = new_explicit_location (&explicit_loc);
          cleanup = make_cleanup_delete_event_location (location);
-         self->ops->decode_location (self, location, filter_pspace, &sals);
+         self->ops->decode_location (self, location, search_scope, &sals);
          do_cleanups (cleanup);
        }
       CATCH (ex, RETURN_MASK_ERROR)
@@ -251,7 +256,7 @@ re_set_exception_catchpoint (struct breakpoint *self,
   END_CATCH
 
   cleanup = make_cleanup (xfree, sals.sals);
-  update_breakpoint_locations (self, filter_pspace, sals, sals_end);
+  update_breakpoint_locations (self, search_scope, sals, sals_end);
   do_cleanups (cleanup);
 }
 
index 73295f0b8c7ff672097ac8e528d3362b46460788..afce9d314b016e2d86bc01eb8c11b4223a9694e2 100644 (file)
@@ -126,7 +126,7 @@ static void create_breakpoints_sal_default (struct gdbarch *,
 
 static void decode_location_default (struct breakpoint *b,
                                     const struct event_location *location,
-                                    struct program_space *search_pspace,
+                                    struct sym_search_scope *search_scope,
                                     struct symtabs_and_lines *sals);
 
 static void clear_command (char *, int);
@@ -13051,7 +13051,7 @@ base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
 static void
 base_breakpoint_decode_location (struct breakpoint *b,
                                 const struct event_location *location,
-                                struct program_space *filter_pspace,
+                                struct sym_search_scope *search_scope,
                                 struct symtabs_and_lines *sals)
 {
   internal_error_pure_virtual_called ();
@@ -13301,10 +13301,10 @@ bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
 static void
 bkpt_decode_location (struct breakpoint *b,
                      const struct event_location *location,
-                     struct program_space *search_pspace,
+                     struct sym_search_scope *search_scope,
                      struct symtabs_and_lines *sals)
 {
-  decode_location_default (b, location, search_pspace, sals);
+  decode_location_default (b, location, search_scope, sals);
 }
 
 /* Virtual table for internal breakpoints.  */
@@ -13501,10 +13501,10 @@ bkpt_probe_create_sals_from_location (const struct event_location *location,
 static void
 bkpt_probe_decode_location (struct breakpoint *b,
                            const struct event_location *location,
-                           struct program_space *search_pspace,
+                           struct sym_search_scope *search_scope,
                            struct symtabs_and_lines *sals)
 {
-  *sals = parse_probes (location, search_pspace, NULL);
+  *sals = parse_probes (location, search_scope->pspace, NULL);
   if (!sals->sals)
     error (_("probe not found"));
 }
@@ -13626,10 +13626,10 @@ tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
 static void
 tracepoint_decode_location (struct breakpoint *b,
                            const struct event_location *location,
-                           struct program_space *search_pspace,
+                           struct sym_search_scope *search_scope,
                            struct symtabs_and_lines *sals)
 {
-  decode_location_default (b, location, search_pspace, sals);
+  decode_location_default (b, location, search_scope, sals);
 }
 
 struct breakpoint_ops tracepoint_breakpoint_ops;
@@ -13650,11 +13650,11 @@ tracepoint_probe_create_sals_from_location
 static void
 tracepoint_probe_decode_location (struct breakpoint *b,
                                  const struct event_location *location,
-                                 struct program_space *search_pspace,
+                                 struct sym_search_scope *search_scope,
                                  struct symtabs_and_lines *sals)
 {
   /* We use the same method for breakpoint on probes.  */
-  bkpt_probe_decode_location (b, location, search_pspace, sals);
+  bkpt_probe_decode_location (b, location, search_scope, sals);
 }
 
 static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
@@ -13819,7 +13819,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
 static void
 strace_marker_decode_location (struct breakpoint *b,
                               const struct event_location *location,
-                              struct program_space *search_pspace,
+                              struct sym_search_scope *search_scope,
                               struct symtabs_and_lines *sals)
 {
   struct tracepoint *tp = (struct tracepoint *) b;
@@ -14067,13 +14067,13 @@ bp_location_matches_search_scope (struct bp_location *bl,
    considered.  */
 
 static int
-all_locations_are_pending (struct breakpoint *b, struct program_space *pspace)
+all_locations_are_pending (struct breakpoint *b,
+                          struct sym_search_scope *search_scope)
 {
   struct bp_location *loc;
 
   for (loc = b->loc; loc != NULL; loc = loc->next)
-    if ((pspace == NULL
-        || loc->pspace == pspace)
+    if (bp_location_matches_search_scope (loc, search_scope)
        && !loc->shlib_disabled
        && !loc->pspace->executing_startup)
       return 0;
@@ -14279,19 +14279,84 @@ locations_are_equal (struct bp_location *a, struct bp_location *b)
   return 1;
 }
 
+static int
+msymbol_name_is (struct minimal_symbol *msymbol, const char *function_name)
+{
+  int (*cmp) (const char *, const char *);
+
+  cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
+  if (cmp (MSYMBOL_LINKAGE_NAME (msymbol), function_name) == 0)
+    return 1;
+
+  if (MSYMBOL_MATCHES_SEARCH_NAME (msymbol, function_name))
+    return 1;
+
+  return 0;
+}
+
+static int
+should_hoist_location (struct bp_location *bl,
+                      struct symtabs_and_lines new_sals,
+                      struct sym_search_scope *search_scope)
+{
+  if (bp_location_matches_search_scope (bl, search_scope))
+    return 1;
+
+  /* If the search scope is restricted to an objfile, we may still
+     want to hoist out locations of other objfiles of the search
+     pspace.  */
+  if (search_scope->objfile != NULL
+      && search_scope->pspace == bl->pspace)
+    {
+      /* We've now resolved the location.  Remove previously pending
+        ones.  */
+      if (bl->shlib_disabled)
+       return 1;
+
+      /* If we had a plt symbol set on another objfile, and we now
+        found the matching text symbol, we'll no longer need the plt
+        symbol location.  */
+      if (bl->sal.msymbol != NULL
+         && MSYMBOL_TYPE (bl->sal.msymbol) == mst_solib_trampoline
+         && bl->function_name != NULL)
+       {
+         int i;
+
+         for (i = 0; i < new_sals.nelts; i++)
+           {
+             struct symbol *symbol = new_sals.sals[i].symbol;
+             struct minimal_symbol *msymbol = new_sals.sals[i].msymbol;
+
+             if (symbol != NULL
+                 && SYMBOL_CLASS (symbol) == LOC_BLOCK
+                 && strcmp (SYMBOL_LINKAGE_NAME (symbol), bl->function_name))
+               return 1;
+
+             if (msymbol != NULL
+                 && msymbol_name_is (msymbol, bl->function_name))
+               return 1;
+           }
+       }
+    }
+
+  return 0;
+}
+
 /* Split all locations of B that are bound to PSPACE out of B's
    location list to a separate list and return that list's head.  If
    PSPACE is NULL, hoist out all locations of B.  */
 
 static struct bp_location *
-hoist_existing_locations (struct breakpoint *b, struct program_space *pspace)
+hoist_existing_locations (struct breakpoint *b,
+                         struct symtabs_and_lines new_sals,
+                         struct sym_search_scope *search_scope)
 {
   struct bp_location head;
   struct bp_location *i = b->loc;
   struct bp_location **i_link = &b->loc;
   struct bp_location *hoisted = &head;
 
-  if (pspace == NULL)
+  if (search_scope->pspace == NULL)
     {
       i = b->loc;
       b->loc = NULL;
@@ -14302,7 +14367,7 @@ hoist_existing_locations (struct breakpoint *b, struct program_space *pspace)
 
   while (i != NULL)
     {
-      if (i->pspace == pspace)
+      if (should_hoist_location (i, new_sals, search_scope))
        {
          *i_link = i->next;
          i->next = NULL;
@@ -14325,7 +14390,7 @@ hoist_existing_locations (struct breakpoint *b, struct program_space *pspace)
 
 void
 update_breakpoint_locations (struct breakpoint *b,
-                            struct program_space *filter_pspace,
+                            struct sym_search_scope *search_scope,
                             struct symtabs_and_lines sals,
                             struct symtabs_and_lines sals_end)
 {
@@ -14349,14 +14414,36 @@ update_breakpoint_locations (struct breakpoint *b,
      We'd like to retain the location, so that when the library is
      loaded again, we don't loose the enabled/disabled status of the
      individual locations.  */
-  if (all_locations_are_pending (b, filter_pspace) && sals.nelts == 0)
+  if (all_locations_are_pending (b, search_scope) && sals.nelts == 0)
     return;
 
-  existing_locations = hoist_existing_locations (b, filter_pspace);
+  existing_locations = hoist_existing_locations (b, sals, search_scope);
 
   for (i = 0; i < sals.nelts; ++i)
     {
       struct bp_location *new_loc;
+      struct symtab_and_line *sal = &sals.sals[i];
+      struct minimal_symbol *msymbol = sal->msymbol;
+
+      /* If we found a new location, then we no longer need the one
+        previously set on a plt symbol (usually in the main
+        executable).  */
+      if (msymbol != NULL
+         && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
+       {
+         struct bp_location *bl;
+
+         for (bl = b->loc; bl != NULL; bl = bl->next)
+           {
+             if (bl->pspace == sal->pspace
+                 && bl->function_name != NULL
+                 && msymbol_name_is (msymbol, bl->function_name))
+               break;
+           }
+
+         if (bl != NULL)
+           continue;
+       }
 
       switch_to_program_space_and_thread (sals.sals[i].pspace);
 
@@ -14441,7 +14528,7 @@ update_breakpoint_locations (struct breakpoint *b,
 
 static struct symtabs_and_lines
 location_to_sals (struct breakpoint *b, struct event_location *location,
-                 struct program_space *search_pspace, int *found)
+                 struct sym_search_scope *search_scope, int *found)
 {
   struct symtabs_and_lines sals = {0};
   struct gdb_exception exception = exception_none;
@@ -14450,7 +14537,7 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
 
   TRY
     {
-      b->ops->decode_location (b, location, search_pspace, &sals);
+      b->ops->decode_location (b, location, search_scope, &sals);
     }
   CATCH (e, RETURN_MASK_ERROR)
     {
@@ -14468,8 +14555,7 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
       if (e.error == NOT_FOUND_ERROR
          && (b->condition_not_parsed
              || (b->loc != NULL
-                 && search_pspace != NULL
-                 && b->loc->pspace != search_pspace)
+                 && !bp_location_matches_search_scope (b->loc, search_scope))
              || (b->loc && b->loc->shlib_disabled)
              || (b->loc && b->loc->pspace->executing_startup)
              || b->enable_state == bp_disabled))
@@ -14489,6 +14575,8 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
     }
   END_CATCH
 
+  validate_sals (&sals, search_scope);
+
   if (exception.reason == 0 || exception.error != NOT_FOUND_ERROR)
     {
       int i;
@@ -14539,19 +14627,32 @@ breakpoint_re_set_default (struct breakpoint *b,
   struct symtabs_and_lines sals, sals_end;
   struct symtabs_and_lines expanded = {0};
   struct symtabs_and_lines expanded_end = {0};
-  struct program_space *filter_pspace = search_scope->pspace;
+  struct sym_search_scope pspace_search_scope;
 
-  sals = location_to_sals (b, b->location, filter_pspace, &found);
+  /* These require arbitrary expressions and symbol lookups.  Punt on
+     resetting locations of specific objfiles, and let the parsers see
+     the whole program space.  */
+  if (search_scope->objfile != NULL
+      && event_location_type (b->location) == ADDRESS_LOCATION)
+    {
+      pspace_search_scope = null_search_scope ();
+      pspace_search_scope.pspace = search_scope->pspace;
+      search_scope = &pspace_search_scope;
+    }
+
+  sals = location_to_sals (b, b->location, search_scope, &found);
   if (found)
     {
       make_cleanup (xfree, sals.sals);
       expanded = sals;
     }
 
+  validate_sals (&expanded, search_scope);
+
   if (b->location_range_end != NULL)
     {
-      sals_end = location_to_sals (b, b->location_range_end,
-                                  filter_pspace, &found);
+      sals_end = location_to_sals (b, b->location_range_end, search_scope,
+                                  &found);
       if (found)
        {
          make_cleanup (xfree, sals_end.sals);
@@ -14559,7 +14660,7 @@ breakpoint_re_set_default (struct breakpoint *b,
        }
     }
 
-  update_breakpoint_locations (b, filter_pspace, expanded, expanded_end);
+  update_breakpoint_locations (b, search_scope, expanded, expanded_end);
 }
 
 /* Default method for creating SALs from an address string.  It basically
@@ -14603,13 +14704,13 @@ create_breakpoints_sal_default (struct gdbarch *gdbarch,
 static void
 decode_location_default (struct breakpoint *b,
                         const struct event_location *location,
-                        struct program_space *search_pspace,
+                        struct sym_search_scope *search_scope,
                         struct symtabs_and_lines *sals)
 {
   struct linespec_result canonical;
 
   init_linespec_result (&canonical);
-  decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, search_pspace,
+  decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, search_scope,
                    (struct symtab *) NULL, 0,
                    &canonical, multiple_symbols_all,
                    b->filter);
index 891f7631f59b9e1e6631720549d38ae8803a77d3..9cc33fc7e8cda8a5ad197b03530eb846d9266abc 100644 (file)
@@ -624,7 +624,7 @@ struct breakpoint_ops
      This function is called inside `location_to_sals'.  */
   void (*decode_location) (struct breakpoint *b,
                           const struct event_location *location,
-                          struct program_space *search_pspace,
+                          struct sym_search_scope *search_scope,
                           struct symtabs_and_lines *sals);
 
   /* Return true if this breakpoint explains a signal.  See
@@ -1219,7 +1219,7 @@ extern void init_bp_location (struct bp_location *loc,
                              struct breakpoint *owner);
 
 extern void update_breakpoint_locations (struct breakpoint *b,
-                                        struct program_space *filter_pspace,
+                                        struct sym_search_scope *search_scope,
                                         struct symtabs_and_lines sals,
                                         struct symtabs_and_lines sals_end);
 
index 84355cf032f5f10ea403f4c3e9012ed7bf40a0ef..da0c4c9831e72a1f7178985242e28294bbd25357 100644 (file)
@@ -963,6 +963,7 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
   CORE_ADDR resolved_address, resolved_pc;
   struct symtab_and_line sal;
   struct symtabs_and_lines sals, sals_end;
+  struct sym_search_scope search_scope = null_search_scope ();
 
   gdb_assert (b->type == bp_gnu_ifunc_resolver_return);
 
@@ -1010,7 +1011,8 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
   sals_end.nelts = 0;
 
   b->type = bp_breakpoint;
-  update_breakpoint_locations (b, current_program_space, sals, sals_end);
+  search_scope.pspace = current_program_space;
+  update_breakpoint_locations (b, &search_scope, sals, sals_end);
 }
 
 /* A helper function for elf_symfile_read that reads the minimal
index d449c295a30b0dfa128d98343f591618de6a24d7..0c10f0465940b8d1c3119781b5b63baa9ac12c6a 100644 (file)
 #include "stack.h"
 #include "location.h"
 
+static int search_scope_matches_symbol (struct sym_search_scope *search_scope,
+                                       struct symbol *sym);
+static int search_scope_matches_bound_msymbol
+  (struct sym_search_scope *search_scope,
+   struct bound_minimal_symbol *msym);
+
 typedef struct symbol *symbolp;
 DEF_VEC_P (symbolp);
 
@@ -123,9 +129,8 @@ struct linespec_state
   /* The program space as seen when the module was entered.  */
   struct program_space *program_space;
 
-  /* If not NULL, the search is restricted to just this program
-     space.  */
-  struct program_space *search_pspace;
+  /* Symbol search is restricted to this scope.  */
+  struct sym_search_scope *search_scope;
 
   /* The default symtab to use, if no other symtab is specified.  */
   struct symtab *default_symtab;
@@ -279,7 +284,7 @@ static struct symtabs_and_lines decode_objc (struct linespec_state *self,
                                             const char *arg);
 
 static VEC (symtab_ptr) *symtabs_from_filename (const char *,
-                                               struct program_space *pspace);
+                                               struct sym_search_scope *scope);
 
 static VEC (symbolp) *find_label_symbols (struct linespec_state *self,
                                          VEC (symbolp) *function_symbols,
@@ -301,15 +306,15 @@ static int symbol_to_sal (struct symtab_and_line *result,
 
 static void add_matching_symbols_to_info (const char *name,
                                          struct collect_info *info,
-                                         struct program_space *pspace);
+                                         struct sym_search_scope *scope);
 
-static void add_all_symbol_names_from_pspace (struct collect_info *info,
-                                             struct program_space *pspace,
-                                             VEC (const_char_ptr) *names);
+static void add_all_symbol_names_from_search_scope (struct collect_info *info,
+                                                   struct sym_search_scope *scope,
+                                                   VEC (const_char_ptr) *names);
 
 static VEC (symtab_ptr) *
   collect_symtabs_from_filename (const char *file,
-                                struct program_space *pspace);
+                                struct sym_search_scope *scope);
 
 static void decode_digits_ordinary (struct linespec_state *self,
                                    linespec_p ls,
@@ -970,10 +975,10 @@ iterate_name_matcher (const char *name, void *d)
 }
 
 /* A helper that walks over all matching symtabs in all objfiles and
-   calls CALLBACK for each symbol matching NAME.  If SEARCH_PSPACE is
-   not NULL, then the search is restricted to just that program
-   space.  If INCLUDE_INLINE is nonzero then symbols representing
-   inlined instances of functions will be included in the result.  */
+   calls CALLBACK for each symbol matching NAME.  The search is
+   restricted to SEARCH_SCOPE.  If INCLUDE_INLINE is nonzero then
+   symbols representing inlined instances of functions will be
+   included in the result.  */
 
 static void
 iterate_over_all_matching_symtabs (struct linespec_state *state,
@@ -981,7 +986,7 @@ iterate_over_all_matching_symtabs (struct linespec_state *state,
                                   const domain_enum domain,
                                   symbol_found_callback_ftype *callback,
                                   void *data,
-                                  struct program_space *search_pspace,
+                                  struct sym_search_scope *search_scope,
                                   int include_inline)
 {
   struct objfile *objfile;
@@ -994,16 +999,14 @@ iterate_over_all_matching_symtabs (struct linespec_state *state,
     ? state->language->la_get_symbol_name_cmp (name)
     : strcmp_iw;
 
-  ALL_PSPACES (pspace)
+  ALL_SEARCH_PSPACES (search_scope->pspace, pspace)
   {
-    if (search_pspace != NULL && search_pspace != pspace)
-      continue;
     if (pspace->executing_startup)
       continue;
 
     set_current_program_space (pspace);
 
-    ALL_OBJFILES (objfile)
+    ALL_SEARCH_OBJFILES (pspace, search_scope->objfile, objfile)
     {
       struct compunit_symtab *cu;
 
@@ -1849,7 +1852,7 @@ create_sals_line_offset (struct linespec_state *self,
       VEC_pop (symtab_ptr, ls->file_symtabs);
       VEC_free (symtab_ptr, ls->file_symtabs);
       ls->file_symtabs = collect_symtabs_from_filename (fullname,
-                                                       self->search_pspace);
+                                                       self->search_scope);
       use_default = 1;
     }
 
@@ -2003,6 +2006,9 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
        {
          struct program_space *pspace = SYMTAB_PSPACE (symbol_symtab (sym));
 
+         gdb_assert (search_scope_matches_symbol (state->search_scope,
+                                                  sym));
+
          if (symbol_to_sal (&sal, state->funfirstline, sym)
              && maybe_add_address (state->addr_set, pspace, sal.pc))
            add_sal_to_sals (state, &sals, &sal,
@@ -2028,6 +2034,9 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
 
          for (i = 0; VEC_iterate (symbolp, ls->function_symbols, i, sym); ++i)
            {
+             gdb_assert (search_scope_matches_symbol (state->search_scope,
+                                                      sym));
+
              pspace = SYMTAB_PSPACE (symbol_symtab (sym));
              set_current_program_space (pspace);
              if (symbol_to_sal (&sal, state->funfirstline, sym)
@@ -2049,6 +2058,9 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
                            i, elem);
               ++i)
            {
+             gdb_assert (search_scope_matches_bound_msymbol
+                         (state->search_scope,
+                          elem));
              pspace = elem->objfile->pspace;
              set_current_program_space (pspace);
              minsym_found (state, elem->objfile, elem->minsym, &sals);
@@ -2102,7 +2114,7 @@ convert_explicit_location_to_sals (struct linespec_state *self,
        {
          result->file_symtabs
            = symtabs_from_filename (explicit_loc->source_filename,
-                                    self->search_pspace);
+                                    self->search_scope);
        }
       CATCH (except, RETURN_MASK_ERROR)
        {
@@ -2294,7 +2306,7 @@ parse_linespec (linespec_parser *parser, const char *arg)
        {
          PARSER_RESULT (parser)->file_symtabs
            = symtabs_from_filename (user_filename,
-                                    PARSER_STATE (parser)->search_pspace);
+                                    PARSER_STATE (parser)->search_scope);
        }
       CATCH (ex, RETURN_MASK_ERROR)
        {
@@ -2376,7 +2388,7 @@ parse_linespec (linespec_parser *parser, const char *arg)
 static void
 linespec_state_constructor (struct linespec_state *self,
                            int flags, const struct language_defn *language,
-                           struct program_space *search_pspace,
+                           struct sym_search_scope *search_scope,
                            struct symtab *default_symtab,
                            int default_line,
                            struct linespec_result *canonical)
@@ -2385,7 +2397,8 @@ linespec_state_constructor (struct linespec_state *self,
   self->language = language;
   self->funfirstline = (flags & DECODE_LINE_FUNFIRSTLINE) ? 1 : 0;
   self->list_mode = (flags & DECODE_LINE_LIST_MODE) ? 1 : 0;
-  self->search_pspace = search_pspace;
+  self->search_scope = search_scope;
+  gdb_assert (search_scope != NULL);
   self->default_symtab = default_symtab;
   self->default_line = default_line;
   self->canonical = canonical;
@@ -2400,7 +2413,7 @@ linespec_state_constructor (struct linespec_state *self,
 static void
 linespec_parser_new (linespec_parser *parser,
                     int flags, const struct language_defn *language,
-                    struct program_space *search_pspace,
+                    struct sym_search_scope *search_scope,
                     struct symtab *default_symtab,
                     int default_line,
                     struct linespec_result *canonical)
@@ -2410,7 +2423,7 @@ linespec_parser_new (linespec_parser *parser,
   memset (PARSER_RESULT (parser), 0, sizeof (struct linespec));
   PARSER_EXPLICIT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN;
   linespec_state_constructor (PARSER_STATE (parser), flags, language,
-                             search_pspace,
+                             search_scope,
                              default_symtab, default_line, canonical);
 }
 
@@ -2460,11 +2473,13 @@ linespec_lex_to_end (char **stringp)
   struct cleanup *cleanup;
   linespec_token token;
   const char *orig;
+  struct sym_search_scope search_scope = null_search_scope ();
 
   if (stringp == NULL || *stringp == NULL)
     return;
 
-  linespec_parser_new (&parser, 0, current_language, NULL, NULL, 0, NULL);
+  linespec_parser_new (&parser, 0, current_language, &search_scope,
+                      NULL, 0, NULL);
   cleanup = make_cleanup (linespec_parser_delete, &parser);
   parser.lexer.saved_arg = *stringp;
   PARSER_STREAM (&parser) = orig = *stringp;
@@ -2561,7 +2576,7 @@ event_location_to_sals (linespec_parser *parser,
 
 void
 decode_line_full (const struct event_location *location, int flags,
-                 struct program_space *search_pspace,
+                 struct sym_search_scope *search_scope,
                  struct symtab *default_symtab,
                  int default_line, struct linespec_result *canonical,
                  const char *select_mode,
@@ -2572,6 +2587,10 @@ decode_line_full (const struct event_location *location, int flags,
   VEC (const_char_ptr) *filters = NULL;
   linespec_parser parser;
   struct linespec_state *state;
+  struct sym_search_scope null_scope = null_search_scope ();
+
+  if (search_scope == NULL)
+    search_scope = &null_scope;
 
   gdb_assert (canonical != NULL);
   /* The filter only makes sense for 'all'.  */
@@ -2583,7 +2602,7 @@ decode_line_full (const struct event_location *location, int flags,
   gdb_assert ((flags & DECODE_LINE_LIST_MODE) == 0);
 
   linespec_parser_new (&parser, flags, current_language,
-                      search_pspace, default_symtab,
+                      search_scope, default_symtab,
                       default_line, canonical);
   cleanups = make_cleanup (linespec_parser_delete, &parser);
   save_current_program_space ();
@@ -2594,6 +2613,16 @@ decode_line_full (const struct event_location *location, int flags,
   gdb_assert (result.nelts == 1 || canonical->pre_expanded);
   canonical->pre_expanded = 1;
 
+  validate_sals (&result, search_scope);
+
+  if (VEC_length (linespec_sals, canonical->sals) > 0)
+    {
+      struct linespec_sals *lsal;
+
+      lsal = VEC_index (linespec_sals, canonical->sals, 0);
+      validate_sals (&lsal->sals, search_scope);
+    }
+
   /* Arrange for allocated canonical names to be freed.  */
   if (result.nelts > 0)
     {
@@ -2629,29 +2658,94 @@ decode_line_full (const struct event_location *location, int flags,
   else
     decode_line_2 (state, &result, select_mode);
 
+  validate_sals (&result, search_scope);
+
   do_cleanups (cleanups);
 }
 
+static int
+search_scope_matches_objfile (struct sym_search_scope *search_scope,
+                             struct objfile *objfile)
+{
+  if (search_scope->pspace == NULL)
+    return 1;
+
+  if (search_scope->pspace != objfile->pspace)
+    return 0;
+
+  if (search_scope->objfile != NULL)
+    {
+      struct objfile *parent = search_scope->objfile;
+      struct objfile *iter;
+
+      for (iter = parent;
+          iter;
+          iter = objfile_separate_debug_iterate (parent, iter))
+       if (objfile == iter)
+         return 1;
+    }
+  else
+    return 1;
+
+  return 0;
+}
+
+static int
+search_scope_matches_symbol (struct sym_search_scope *search_scope,
+                            struct symbol *sym)
+{
+  return search_scope_matches_objfile (search_scope,
+                                      SYMTAB_OBJFILE (symbol_symtab (sym)));
+}
+
+static int
+search_scope_matches_bound_msymbol (struct sym_search_scope *search_scope,
+                                   struct bound_minimal_symbol *msym)
+{
+  return search_scope_matches_objfile (search_scope, msym->objfile);
+}
+
+void
+validate_sals (struct symtabs_and_lines *result,
+              struct sym_search_scope *search_scope)
+{
+  int i;
+
+  for (i = 0; i < result->nelts; i++)
+    {
+      struct symtab_and_line *sal = &result->sals[i];
+
+      gdb_assert (search_scope_matches_objfile (search_scope, sal->objfile));
+    }
+}
+
 /* See linespec.h.  */
 
 struct symtabs_and_lines
 decode_line_1 (const struct event_location *location, int flags,
-              struct program_space *search_pspace,
+              struct sym_search_scope *search_scope,
               struct symtab *default_symtab,
               int default_line)
 {
   struct symtabs_and_lines result;
   linespec_parser parser;
   struct cleanup *cleanups;
+  struct sym_search_scope null_scope = null_search_scope ();
+  int i;
+
+  if (search_scope == NULL)
+    search_scope = &null_scope;
 
   linespec_parser_new (&parser, flags, current_language,
-                      search_pspace, default_symtab,
+                      search_scope, default_symtab,
                       default_line, NULL);
   cleanups = make_cleanup (linespec_parser_delete, &parser);
   save_current_program_space ();
 
   result = event_location_to_sals (&parser, location);
 
+  validate_sals (&result, search_scope);
+
   do_cleanups (cleanups);
   return result;
 }
@@ -2787,7 +2881,7 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg)
       return values;
     }
 
-  add_all_symbol_names_from_pspace (&info, NULL, symbol_names);
+  add_all_symbol_names_from_search_scope (&info, NULL, symbol_names);
 
   if (!VEC_empty (symbolp, info.result.symbols)
       || !VEC_empty (bound_minimal_symbol_d, info.result.minimal_symbols))
@@ -2897,10 +2991,10 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs,
        {
          iterate_over_all_matching_symtabs (state, class_name, STRUCT_DOMAIN,
                                             collect_one_symbol, &collector,
-                                            NULL, 0);
+                                            state->search_scope, 0);
          iterate_over_all_matching_symtabs (state, class_name, VAR_DOMAIN,
                                             collect_one_symbol, &collector,
-                                            NULL, 0);
+                                            state->search_scope, 0);
        }
       else
        {
@@ -2986,15 +3080,15 @@ compare_msymbols (const void *a, const void *b)
    are considered.  Results are stored into INFO.  */
 
 static void
-add_all_symbol_names_from_pspace (struct collect_info *info,
-                                 struct program_space *pspace,
-                                 VEC (const_char_ptr) *names)
+add_all_symbol_names_from_search_scope (struct collect_info *info,
+                                       struct sym_search_scope *search_scope,
+                                       VEC (const_char_ptr) *names)
 {
   int ix;
   const char *iter;
 
   for (ix = 0; VEC_iterate (const_char_ptr, names, ix, iter); ++ix)
-    add_matching_symbols_to_info (iter, info, pspace);
+    add_matching_symbols_to_info (iter, info, search_scope);
 }
 
 static void
@@ -3091,6 +3185,8 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
              != SYMTAB_PSPACE (symbol_symtab (VEC_index (symbolp, sym_classes,
                                                          ix + 1)))))
        {
+         struct sym_search_scope search_scope = null_search_scope ();
+
          /* If we did not find a direct implementation anywhere in
             this program space, consider superclasses.  */
          if (VEC_length (const_char_ptr, result_names) == last_result_len)
@@ -3098,9 +3194,11 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
                                     &result_names);
 
          /* We have a list of candidate symbol names, so now we
-            iterate over the symbol tables looking for all
-            matches in this pspace.  */
-         add_all_symbol_names_from_pspace (&info, pspace, result_names);
+            iterate over the symbol tables looking for all matches in
+            this pspace.  */
+         search_scope.pspace = pspace;
+         add_all_symbol_names_from_search_scope (&info, &search_scope,
+                                                 result_names);
 
          VEC_truncate (typep, superclass_vec, 0);
          last_result_len = VEC_length (const_char_ptr, result_names);
@@ -3152,13 +3250,12 @@ add_symtabs_to_list (struct symtab *symtab, void *d)
   return 0;
 }
 
-/* Given a file name, return a VEC of all matching symtabs.  If
-   SEARCH_PSPACE is not NULL, the search is restricted to just that
-   program space.  */
+/* Return a VEC of all symtabs in SEARCH_SCOPE that match a
+   filename.  */
 
 static VEC (symtab_ptr) *
 collect_symtabs_from_filename (const char *file,
-                              struct program_space *search_pspace)
+                              struct sym_search_scope *search_scope)
 {
   struct symtab_collector collector;
   struct cleanup *cleanups;
@@ -3170,20 +3267,12 @@ collect_symtabs_from_filename (const char *file,
   cleanups = make_cleanup_htab_delete (collector.symtab_table);
 
   /* Find that file's data.  */
-  if (search_pspace == NULL)
+  ALL_SEARCH_PSPACES (search_scope->pspace, pspace)
     {
-      ALL_PSPACES (pspace)
-        {
-         if (pspace->executing_startup)
-           continue;
+      if (pspace->executing_startup)
+       continue;
 
-         set_current_program_space (pspace);
-         iterate_over_symtabs (file, add_symtabs_to_list, &collector);
-       }
-    }
-  else
-    {
-      set_current_program_space (search_pspace);
+      set_current_program_space (pspace);
       iterate_over_symtabs (file, add_symtabs_to_list, &collector);
     }
 
@@ -3191,16 +3280,16 @@ collect_symtabs_from_filename (const char *file,
   return collector.symtabs;
 }
 
-/* Return all the symtabs associated to the FILENAME.  If SEARCH_PSPACE is
-   not NULL, the search is restricted to just that program space.  */
+/* Return all the symtabs associated to the FILENAME.  The search is
+   restricted to SEARCH_SCOPE.  */
 
 static VEC (symtab_ptr) *
 symtabs_from_filename (const char *filename,
-                      struct program_space *search_pspace)
+                      struct sym_search_scope *search_scope)
 {
   VEC (symtab_ptr) *result;
   
-  result = collect_symtabs_from_filename (filename, search_pspace);
+  result = collect_symtabs_from_filename (filename, search_scope);
 
   if (VEC_empty (symtab_ptr, result))
     {
@@ -3237,10 +3326,10 @@ find_function_symbols (struct linespec_state *state,
   /* Try NAME as an Objective-C selector.  */
   find_imps (name, &symbol_names);
   if (!VEC_empty (const_char_ptr, symbol_names))
-    add_all_symbol_names_from_pspace (&info, state->search_pspace,
-                                     symbol_names);
+    add_all_symbol_names_from_search_scope (&info, state->search_scope,
+                                           symbol_names);
   else
-    add_matching_symbols_to_info (name, &info, state->search_pspace);
+    add_matching_symbols_to_info (name, &info, state->search_scope);
 
   do_cleanups (cleanup);
 
@@ -3502,6 +3591,7 @@ decode_digits_ordinary (struct linespec_state *self,
 
          init_sal (&sal);
          sal.pspace = SYMTAB_PSPACE (elt);
+         sal.objfile = SYMTAB_OBJFILE (elt);
          sal.symtab = elt;
          sal.line = line;
          sal.pc = pc;
@@ -3602,6 +3692,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
   sal = find_pc_sect_line (MSYMBOL_VALUE_ADDRESS (objfile, msymbol),
                           (struct obj_section *) 0, 0);
   sal.section = MSYMBOL_OBJ_SECTION (objfile, msymbol);
+  sal.msymbol = msymbol;
 
   /* The minimal symbol might point to a function descriptor;
      resolve it to the actual code address instead.  */
@@ -3783,16 +3874,15 @@ add_minsym (struct minimal_symbol *minsym, void *d)
   VEC_safe_push (bound_minimal_symbol_d, info->msyms, &mo);
 }
 
-/* Search for minimal symbols called NAME.  If SEARCH_PSPACE
-   is not NULL, the search is restricted to just that program
-   space.
+/* Search for minimal symbols called NAME.  The search is restricted
+   to SEARCH_SCOPE.
 
    If SYMTAB is NULL, search all objfiles, otherwise
    restrict results to the given SYMTAB.  */
 
 static void
 search_minsyms_for_name (struct collect_info *info, const char *name,
-                        struct program_space *search_pspace,
+                        struct sym_search_scope *search_scope,
                         struct symtab *symtab)
 {
   struct collect_minsyms local;
@@ -3810,18 +3900,16 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
     {
       struct program_space *pspace;
 
-      ALL_PSPACES (pspace)
+      ALL_SEARCH_PSPACES (search_scope->pspace, pspace)
       {
        struct objfile *objfile;
 
-       if (search_pspace != NULL && search_pspace != pspace)
-         continue;
        if (pspace->executing_startup)
          continue;
 
        set_current_program_space (pspace);
 
-       ALL_OBJFILES (objfile)
+       ALL_SEARCH_OBJFILES (pspace, search_scope->objfile, objfile)
        {
          local.objfile = objfile;
          iterate_over_minimal_symbols (objfile, name, add_minsym, &local);
@@ -3830,7 +3918,8 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
     }
   else
     {
-      if (search_pspace == NULL || SYMTAB_PSPACE (symtab) == search_pspace)
+      if (search_pspace_matches_pspace (search_scope->pspace,
+                                       SYMTAB_PSPACE (symtab)))
        {
          set_current_program_space (SYMTAB_PSPACE (symtab));
          local.objfile = SYMTAB_OBJFILE(symtab);
@@ -3873,14 +3962,13 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
     do_cleanups (cleanup);
 }
 
-/* A helper function to add all symbols matching NAME to INFO.  If
-   PSPACE is not NULL, the search is restricted to just that program
-   space.  */
+/* A helper function to add all symbols matching NAME to INFO.  The
+   search is restricted to SEARCH_SCOPE.  */
 
 static void
 add_matching_symbols_to_info (const char *name,
                              struct collect_info *info,
-                             struct program_space *pspace)
+                             struct sym_search_scope *search_scope)
 {
   int ix;
   struct symtab *elt;
@@ -3891,10 +3979,11 @@ add_matching_symbols_to_info (const char *name,
        {
          iterate_over_all_matching_symtabs (info->state, name, VAR_DOMAIN,
                                             collect_symbols, info,
-                                            pspace, 1);
-         search_minsyms_for_name (info, name, pspace, NULL);
+                                            search_scope, 1);
+         search_minsyms_for_name (info, name, search_scope, NULL);
        }
-      else if (pspace == NULL || pspace == SYMTAB_PSPACE (elt))
+      else if (search_pspace_matches_pspace (search_scope->pspace,
+                                            SYMTAB_PSPACE (elt)))
        {
          int prev_len = VEC_length (symbolp, info->result.symbols);
 
@@ -3911,7 +4000,7 @@ add_matching_symbols_to_info (const char *name,
             this case.  */
          if (prev_len == VEC_length (symbolp, info->result.symbols)
              && elt->language == language_asm)
-           search_minsyms_for_name (info, name, pspace, elt);
+           search_minsyms_for_name (info, name, search_scope, elt);
        }
     }
 }
@@ -3928,6 +4017,7 @@ symbol_to_sal (struct symtab_and_line *result,
   if (SYMBOL_CLASS (sym) == LOC_BLOCK)
     {
       *result = find_function_start_sal (sym, funfirstline);
+      result->symbol = sym;
       return 1;
     }
   else
@@ -3939,6 +4029,7 @@ symbol_to_sal (struct symtab_and_line *result,
          result->line = SYMBOL_LINE (sym);
          result->pc = SYMBOL_VALUE_ADDRESS (sym);
          result->pspace = SYMTAB_PSPACE (result->symtab);
+         result->objfile = SYMTAB_OBJFILE (result->symtab);
          result->explicit_pc = 1;
          return 1;
        }
@@ -3953,6 +4044,7 @@ symbol_to_sal (struct symtab_and_line *result,
          result->symtab = symbol_symtab (sym);
          result->line = SYMBOL_LINE (sym);
          result->pspace = SYMTAB_PSPACE (result->symtab);
+         result->objfile = SYMTAB_OBJFILE (result->symtab);
          return 1;
        }
     }
index b802612d10d452004365951bb918de7632d7ce3c..856b9a989839de14e306c2088606f49ef6ced0d5 100644 (file)
@@ -97,7 +97,7 @@ extern struct cleanup *
 
 extern struct symtabs_and_lines
        decode_line_1 (const struct event_location *location, int flags,
-                      struct program_space *search_pspace,
+                      struct sym_search_scope *search_scope,
                       struct symtab *default_symtab, int default_line);
 
 /* Parse LOCATION and return results.  This is the "full"
@@ -140,7 +140,7 @@ extern struct symtabs_and_lines
    filtered out.  */
 
 extern void decode_line_full (const struct event_location *location, int flags,
-                             struct program_space *search_pspace,
+                             struct sym_search_scope *search_scope,
                              struct symtab *default_symtab, int default_line,
                              struct linespec_result *canonical,
                              const char *select_mode,
index 15fe6016708518afa31cc6f4421c9bec0d75303f..9f7550741a42cba66db3e4467a9d21fb77510deb 100644 (file)
@@ -1453,6 +1453,11 @@ struct symtab_and_line
   /* XXX If PROBE is not NULL, then this is the objfile in which the probe
      originated.  */
   struct objfile *objfile;
+
+  /* If this SAL originated from a minsym, this is it.  */
+  struct minimal_symbol *msymbol;
+  /* If this SAL originated from a symbol, this is it.  */
+  struct symbol *symbol;
 };
 
 extern void init_sal (struct symtab_and_line *sal);
@@ -1664,4 +1669,7 @@ void initialize_objfile_symbol (struct symbol *);
 
 struct template_symbol *allocate_template_symbol (struct objfile *);
 
+void validate_sals (struct symtabs_and_lines *result,
+                   struct sym_search_scope *search_scope);
+
 #endif /* !defined(SYMTAB_H) */