New "iterate_over_objfiles_in_search_order" gdbarch method.
authorJoel Brobecker <brobecker@gnat.com>
Tue, 5 Jun 2012 13:50:50 +0000 (13:50 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Tue, 5 Jun 2012 13:50:50 +0000 (13:50 +0000)
This patch introduces the "iterate_over_objfiles_in_search_order"
gdbarch method, as well as its default implementation, and converts
the areas where it will matter to using this gdbarch method.

The default method implementation is the only one installed, and
the changes should have no functional impact in terms of behavior.
This only paves the way for the architectures that will need their
own version.

gdb/ChangeLog:

        * gdbarch.sh: Add generation of
        "iterate_over_objfiles_in_search_order_cb_ftype" typedef in
        gdbarch.h.  Add include of "objfiles.h" in gdbarch.c.
        (iterate_over_objfiles_in_search_order): New gdbarch method.
        * gdbarch.h, gdbarch.c: Regenerate.
        * objfiles.h (default_iterate_over_objfiles_in_search_order):
        Add declaration.
        * objfiles.c (default_iterate_over_objfiles_in_search_order):
        New function.
        * symtab.c (lookup_symbol_aux_objfile): New function, extracted
        out of lookup_symbol_aux_symtabs.
        (lookup_symbol_aux_symtabs): Replace extracted-out code by
        call to lookup_symbol_aux_objfile.
        (struct global_sym_lookup_data): New type.
        (lookup_symbol_global_iterator_cb): New function.
        (lookup_symbol_global): Search for symbol using
        gdbarch_iterate_over_objfiles_in_search_order and
        lookup_symbol_global_iterator_cb.
        * findvar.c (struct minsym_lookup_data): New type.
        (minsym_lookup_iterator_cb): New function.
        (default_read_var_value) [case LOC_UNRESOLVED]: Resolve the
        symbol's address via gdbarch_iterate_over_objfiles_in_search_order
        and minsym_lookup_iterator_cb.

gdb/ChangeLog
gdb/findvar.c
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/objfiles.c
gdb/objfiles.h
gdb/symtab.c

index 743e974b7eb3ac941ffd555a0280ae3ed8c80698..a6448a71f109f76041567c6cc0221951458bb5fe 100644 (file)
@@ -1,3 +1,29 @@
+2012-06-05  Joel Brobecker  <brobecker@adacore.com>
+
+       * gdbarch.sh: Add generation of
+       "iterate_over_objfiles_in_search_order_cb_ftype" typedef in
+       gdbarch.h.  Add include of "objfiles.h" in gdbarch.c.
+       (iterate_over_objfiles_in_search_order): New gdbarch method.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       * objfiles.h (default_iterate_over_objfiles_in_search_order):
+       Add declaration.
+       * objfiles.c (default_iterate_over_objfiles_in_search_order):
+       New function.
+       * symtab.c (lookup_symbol_aux_objfile): New function, extracted
+       out of lookup_symbol_aux_symtabs.
+       (lookup_symbol_aux_symtabs): Replace extracted-out code by
+       call to lookup_symbol_aux_objfile.
+       (struct global_sym_lookup_data): New type.
+       (lookup_symbol_global_iterator_cb): New function.
+       (lookup_symbol_global): Search for symbol using
+       gdbarch_iterate_over_objfiles_in_search_order and
+       lookup_symbol_global_iterator_cb.
+       * findvar.c (struct minsym_lookup_data): New type.
+       (minsym_lookup_iterator_cb): New function.
+       (default_read_var_value) [case LOC_UNRESOLVED]: Resolve the
+       symbol's address via gdbarch_iterate_over_objfiles_in_search_order
+       and minsym_lookup_iterator_cb.
+
 2012-06-05  Joel Brobecker  <brobecker@adacore.com>
 
        Revert the following patch:
index 9009e6f324be2ae80984546281c665aba35c3ef2..66bcebee3486e8e4bd726b7431dfeaadcaf303f0 100644 (file)
@@ -406,6 +406,37 @@ symbol_read_needs_frame (struct symbol *sym)
   return 1;
 }
 
+/* Private data to be used with minsym_lookup_iterator_cb.  */
+
+struct minsym_lookup_data
+{
+  /* The name of the minimal symbol we are searching for.  */
+  const char *name;
+
+  /* The field where the callback should store the minimal symbol
+     if found.  It should be initialized to NULL before the search
+     is started.  */
+  struct minimal_symbol *result;
+};
+
+/* A callback function for gdbarch_iterate_over_objfiles_in_search_order.
+   It searches by name for a minimal symbol within the given OBJFILE.
+   The arguments are passed via CB_DATA, which in reality is a pointer
+   to struct minsym_lookup_data.  */
+
+static int
+minsym_lookup_iterator_cb (struct objfile *objfile, void *cb_data)
+{
+  struct minsym_lookup_data *data = (struct minsym_lookup_data *) cb_data;
+
+  gdb_assert (data->result == NULL);
+
+  data->result = lookup_minimal_symbol (data->name, NULL, objfile);
+
+  /* The iterator should stop iff a match was found.  */
+  return (data->result != NULL);
+}
+
 /* A default implementation for the "la_read_var_value" hook in
    the language vector which should work in most situations.  */
 
@@ -559,10 +590,19 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
 
     case LOC_UNRESOLVED:
       {
+       struct minsym_lookup_data lookup_data;
        struct minimal_symbol *msym;
        struct obj_section *obj_section;
 
-       msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (var), NULL, NULL);
+       memset (&lookup_data, 0, sizeof (lookup_data));
+       lookup_data.name = SYMBOL_LINKAGE_NAME (var);
+
+       gdbarch_iterate_over_objfiles_in_search_order
+         (get_objfile_arch (SYMBOL_SYMTAB (var)->objfile),
+          minsym_lookup_iterator_cb, &lookup_data,
+          SYMBOL_SYMTAB (var)->objfile);
+       msym = lookup_data.result;
+
        if (msym == NULL)
          error (_("No global symbol \"%s\"."), SYMBOL_LINKAGE_NAME (var));
        if (overlay_debugging)
index 9d7b67a9c7869ca38b560ea887ac1c5126686359..4d46a5dd48e722e0b61840870923e00151053ed4 100644 (file)
@@ -49,6 +49,7 @@
 #include "gdb_obstack.h"
 #include "observer.h"
 #include "regcache.h"
+#include "objfiles.h"
 
 /* Static function declarations */
 
@@ -284,6 +285,7 @@ struct gdbarch
   int has_dos_based_file_system;
   gdbarch_gen_return_address_ftype *gen_return_address;
   gdbarch_info_proc_ftype *info_proc;
+  gdbarch_iterate_over_objfiles_in_search_order_ftype *iterate_over_objfiles_in_search_order;
 };
 
 
@@ -451,6 +453,7 @@ struct gdbarch startup_gdbarch =
   0,  /* has_dos_based_file_system */
   default_gen_return_address,  /* gen_return_address */
   0,  /* info_proc */
+  default_iterate_over_objfiles_in_search_order,  /* iterate_over_objfiles_in_search_order */
   /* startup_gdbarch() */
 };
 
@@ -541,6 +544,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
   gdbarch->auto_charset = default_auto_charset;
   gdbarch->auto_wide_charset = default_auto_wide_charset;
   gdbarch->gen_return_address = default_gen_return_address;
+  gdbarch->iterate_over_objfiles_in_search_order = default_iterate_over_objfiles_in_search_order;
   /* gdbarch_alloc() */
 
   return gdbarch;
@@ -749,6 +753,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of has_dos_based_file_system, invalid_p == 0 */
   /* Skip verify of gen_return_address, invalid_p == 0 */
   /* Skip verify of info_proc, has predicate.  */
+  /* Skip verify of iterate_over_objfiles_in_search_order, invalid_p == 0 */
   buf = ui_file_xstrdup (log, &length);
   make_cleanup (xfree, buf);
   if (length > 0)
@@ -1066,6 +1071,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                       "gdbarch_dump: integer_to_address = <%s>\n",
                       host_address_to_string (gdbarch->integer_to_address));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: iterate_over_objfiles_in_search_order = <%s>\n",
+                      host_address_to_string (gdbarch->iterate_over_objfiles_in_search_order));
   fprintf_unfiltered (file,
                       "gdbarch_dump: long_bit = %s\n",
                       plongest (gdbarch->long_bit));
@@ -4245,6 +4253,23 @@ set_gdbarch_info_proc (struct gdbarch *gdbarch,
   gdbarch->info_proc = info_proc;
 }
 
+void
+gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->iterate_over_objfiles_in_search_order != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_iterate_over_objfiles_in_search_order called\n");
+  gdbarch->iterate_over_objfiles_in_search_order (gdbarch, cb, cb_data, current_objfile);
+}
+
+void
+set_gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch,
+                                                   gdbarch_iterate_over_objfiles_in_search_order_ftype iterate_over_objfiles_in_search_order)
+{
+  gdbarch->iterate_over_objfiles_in_search_order = iterate_over_objfiles_in_search_order;
+}
+
 
 /* Keep a registry of per-architecture data-pointers required by GDB
    modules.  */
index e4e7abfdfe3eb7affb524e331fd1bfdef2563592..a82e8bbbe29ae926fa80892d1ee45e38cf346088 100644 (file)
@@ -69,6 +69,12 @@ struct stap_parse_info;
    GDB, this global should be made target-specific.  */
 extern struct gdbarch *target_gdbarch;
 
+/* Callback type for the 'iterate_over_objfiles_in_search_order'
+   gdbarch  method.  */
+
+typedef int (iterate_over_objfiles_in_search_order_cb_ftype)
+  (struct objfile *objfile, void *cb_data);
+
 
 /* The following are pre-initialized by GDBARCH.  */
 
@@ -1175,6 +1181,24 @@ typedef void (gdbarch_info_proc_ftype) (struct gdbarch *gdbarch, char *args, enu
 extern void gdbarch_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what);
 extern void set_gdbarch_info_proc (struct gdbarch *gdbarch, gdbarch_info_proc_ftype *info_proc);
 
+/* Iterate over all objfiles in the order that makes the most sense
+   for the architecture to make global symbol searches.
+  
+   CB is a callback function where OBJFILE is the objfile to be searched,
+   and CB_DATA a pointer to user-defined data (the same data that is passed
+   when calling this gdbarch method).  The iteration stops if this function
+   returns nonzero.
+  
+   CB_DATA is a pointer to some user-defined data to be passed to
+   the callback.
+  
+   If not NULL, CURRENT_OBJFILE corresponds to the objfile being
+   inspected when the symbol search was requested. */
+
+typedef void (gdbarch_iterate_over_objfiles_in_search_order_ftype) (struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile);
+extern void gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile);
+extern void set_gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, gdbarch_iterate_over_objfiles_in_search_order_ftype *iterate_over_objfiles_in_search_order);
+
 /* Definition for an unknown syscall, used basically in error-cases.  */
 #define UNKNOWN_SYSCALL (-1)
 
index 0f58defb383308c6064251433d059f4ed7c6a9cd..2324138486051765ad6f2df4d3f8950663dd43e3 100755 (executable)
@@ -936,6 +936,21 @@ m:void:gen_return_address:struct agent_expr *ax, struct axs_value *value, CORE_A
 # Implement the "info proc" command.
 M:void:info_proc:char *args, enum info_proc_what what:args, what
 
+# Iterate over all objfiles in the order that makes the most sense
+# for the architecture to make global symbol searches.
+#
+# CB is a callback function where OBJFILE is the objfile to be searched,
+# and CB_DATA a pointer to user-defined data (the same data that is passed
+# when calling this gdbarch method).  The iteration stops if this function
+# returns nonzero.
+#
+# CB_DATA is a pointer to some user-defined data to be passed to
+# the callback.
+#
+# If not NULL, CURRENT_OBJFILE corresponds to the objfile being
+# inspected when the symbol search was requested.
+m:void:iterate_over_objfiles_in_search_order:iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile:cb, cb_data, current_objfile:0:default_iterate_over_objfiles_in_search_order::0
+
 EOF
 }
 
@@ -1064,6 +1079,12 @@ struct stap_parse_info;
    Eventually, when support for multiple targets is implemented in
    GDB, this global should be made target-specific.  */
 extern struct gdbarch *target_gdbarch;
+
+/* Callback type for the 'iterate_over_objfiles_in_search_order'
+   gdbarch  method.  */
+
+typedef int (iterate_over_objfiles_in_search_order_cb_ftype)
+  (struct objfile *objfile, void *cb_data);
 EOF
 
 # function typedef's
@@ -1382,6 +1403,7 @@ cat <<EOF
 #include "gdb_obstack.h"
 #include "observer.h"
 #include "regcache.h"
+#include "objfiles.h"
 
 /* Static function declarations */
 
index 8d9f8a5484cfcf4a1f28408d0042f43259820258..f5e5c75b86f4f64acdc91eb6c8d3c90ab27a150c 100644 (file)
@@ -1525,6 +1525,31 @@ gdb_bfd_unref (struct bfd *abfd)
   xfree (name);
 }
 
+/* The default implementation for the "iterate_over_objfiles_in_search_order"
+   gdbarch method.  It is equivalent to use the ALL_OBJFILES macro,
+   searching the objfiles in the order they are stored internally,
+   ignoring CURRENT_OBJFILE.
+
+   On most platorms, it should be close enough to doing the best
+   we can without some knowledge specific to the architecture.  */
+
+void
+default_iterate_over_objfiles_in_search_order
+  (struct gdbarch *gdbarch,
+   iterate_over_objfiles_in_search_order_cb_ftype *cb,
+   void *cb_data, struct objfile *current_objfile)
+{
+  int stop = 0;
+  struct objfile *objfile;
+
+  ALL_OBJFILES (objfile)
+    {
+       stop = cb (objfile, cb_data);
+       if (stop)
+        return;
+    }
+}
+
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 extern initialize_file_ftype _initialize_objfiles;
 
index 98cc39ee7e70784ad712110a17b17cb01b6fc258..01c3aead713119a31a95fe410de59b377016c3d0 100644 (file)
@@ -525,6 +525,11 @@ extern void *objfile_data (struct objfile *objfile,
 extern struct bfd *gdb_bfd_ref (struct bfd *abfd);
 extern void gdb_bfd_unref (struct bfd *abfd);
 extern int gdb_bfd_close_or_warn (struct bfd *abfd);
+
+extern void default_iterate_over_objfiles_in_search_order
+  (struct gdbarch *gdbarch,
+   iterate_over_objfiles_in_search_order_cb_ftype *cb,
+   void *cb_data, struct objfile *current_objfile);
 \f
 
 /* Traverse all object files in the current program space.
index 7e6483f2782554aeac65e2a49bc650091e60b092..6133b5cc653b7659acd9cf3d56d70cd7538c6d60 100644 (file)
@@ -1498,40 +1498,55 @@ lookup_global_symbol_from_objfile (const struct objfile *main_objfile,
   return NULL;
 }
 
-/* Check to see if the symbol is defined in one of the symtabs.
-   BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK,
+/* Check to see if the symbol is defined in one of the OBJFILE's
+   symtabs.  BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK,
    depending on whether or not we want to search global symbols or
    static symbols.  */
 
+static struct symbol *
+lookup_symbol_aux_objfile (struct objfile *objfile, int block_index,
+                          const char *name, const domain_enum domain)
+{
+  struct symbol *sym = NULL;
+  struct blockvector *bv;
+  const struct block *block;
+  struct symtab *s;
+
+  if (objfile->sf)
+    objfile->sf->qf->pre_expand_symtabs_matching (objfile, block_index,
+                                                 name, domain);
+
+  ALL_OBJFILE_SYMTABS (objfile, s)
+    if (s->primary)
+      {
+       bv = BLOCKVECTOR (s);
+       block = BLOCKVECTOR_BLOCK (bv, block_index);
+       sym = lookup_block_symbol (block, name, domain);
+       if (sym)
+         {
+           block_found = block;
+           return fixup_symbol_section (sym, objfile);
+         }
+      }
+
+  return NULL;
+}
+
+/* Same as lookup_symbol_aux_objfile, except that it searches all
+   objfiles.  Return the first match found.  */
+
 static struct symbol *
 lookup_symbol_aux_symtabs (int block_index, const char *name,
                           const domain_enum domain)
 {
   struct symbol *sym;
   struct objfile *objfile;
-  struct blockvector *bv;
-  const struct block *block;
-  struct symtab *s;
 
   ALL_OBJFILES (objfile)
   {
-    if (objfile->sf)
-      objfile->sf->qf->pre_expand_symtabs_matching (objfile,
-                                                   block_index,
-                                                   name, domain);
-
-    ALL_OBJFILE_SYMTABS (objfile, s)
-      if (s->primary)
-       {
-         bv = BLOCKVECTOR (s);
-         block = BLOCKVECTOR_BLOCK (bv, block_index);
-         sym = lookup_block_symbol (block, name, domain);
-         if (sym)
-           {
-             block_found = block;
-             return fixup_symbol_section (sym, objfile);
-           }
-       }
+    sym = lookup_symbol_aux_objfile (objfile, block_index, name, domain);
+    if (sym)
+      return sym;
   }
 
   return NULL;
@@ -1648,6 +1663,46 @@ lookup_symbol_static (const char *name,
     return NULL;
 }
 
+/* Private data to be used with lookup_symbol_global_iterator_cb.  */
+
+struct global_sym_lookup_data
+{
+  /* The name of the symbol we are searching for.  */
+  const char *name;
+
+  /* The domain to use for our search.  */
+  domain_enum domain;
+
+  /* The field where the callback should store the symbol if found.
+     It should be initialized to NULL before the search is started.  */
+  struct symbol *result;
+};
+
+/* A callback function for gdbarch_iterate_over_objfiles_in_search_order.
+   It searches by name for a symbol in the GLOBAL_BLOCK of the given
+   OBJFILE.  The arguments for the search are passed via CB_DATA,
+   which in reality is a pointer to struct global_sym_lookup_data.  */
+
+static int
+lookup_symbol_global_iterator_cb (struct objfile *objfile,
+                                 void *cb_data)
+{
+  struct global_sym_lookup_data *data =
+    (struct global_sym_lookup_data *) cb_data;
+
+  gdb_assert (data->result == NULL);
+
+  data->result = lookup_symbol_aux_objfile (objfile, GLOBAL_BLOCK,
+                                           data->name, data->domain);
+  if (data->result == NULL)
+    data->result = lookup_symbol_aux_quick (objfile, GLOBAL_BLOCK,
+                                           data->name, data->domain);
+
+  /* If we found a match, tell the iterator to stop.  Otherwise,
+     keep going.  */
+  return (data->result != NULL);
+}
+
 /* Lookup a symbol in all files' global blocks (searching psymtabs if
    necessary).  */
 
@@ -1658,6 +1713,7 @@ lookup_symbol_global (const char *name,
 {
   struct symbol *sym = NULL;
   struct objfile *objfile = NULL;
+  struct global_sym_lookup_data lookup_data;
 
   /* Call library-specific lookup procedure.  */
   objfile = lookup_objfile_from_block (block);
@@ -1666,18 +1722,14 @@ lookup_symbol_global (const char *name,
   if (sym != NULL)
     return sym;
 
-  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, domain);
-  if (sym != NULL)
-    return sym;
-
-  ALL_OBJFILES (objfile)
-  {
-    sym = lookup_symbol_aux_quick (objfile, GLOBAL_BLOCK, name, domain);
-    if (sym)
-      return sym;
-  }
+  memset (&lookup_data, 0, sizeof (lookup_data));
+  lookup_data.name = name;
+  lookup_data.domain = domain;
+  gdbarch_iterate_over_objfiles_in_search_order
+    (objfile != NULL ? get_objfile_arch (objfile) : target_gdbarch,
+     lookup_symbol_global_iterator_cb, &lookup_data, objfile);
 
-  return NULL;
+  return lookup_data.result;
 }
 
 int