* [RFA] Rework symbol searches to move Ada-specific stuff to ada-lang.c.
@ 2010-10-05 8:42 Paul Hilfinger
2010-10-06 22:52 ` Tom Tromey
2010-10-06 23:15 ` [RFA] " Joel Brobecker
0 siblings, 2 replies; 8+ messages in thread
From: Paul Hilfinger @ 2010-10-05 8:42 UTC (permalink / raw)
To: gdb-patches
This patch is a follow-on to the preceding dictionary patch.
It is a clean-up of some of our symbol-lookup machinery to pull some
kludgy Ada-specific definitions out of psymtab.c. In place of
map_ada_symtabs and ada_lookup_partial_symbol, we have a method
map_matching_symbols, which searches through all symbol tables and
partial symbol tables looking for a symbol that matches according to
a matching function that is passed as a parameter. This requires some
care, because partial symbol tables speed up searches by binary search,
while full symbol tables use hashing. To call map_matching_symbols, therefore,
you may need to supply both a matching function that is compatible with the
dictionary hash function and an ordering relation that is compatible with
strcmp_iw, which is used to order partial symbol tables.
Having added this general routine to psymtab.c, we use it in ada-lang.c
to rework add_non_local_symbols (now renamed add_nonlocal_symbols).
Tested on i686 Linux with no regressions.
Paul Hilfinger
Changelog:
gdb/
* ada-lang.c (full_match): Declare.
(ada_match_name): Rename to match_name (we should avoid prefixing static
symbols with "ada_").
(match_name): New name for ada_match_name.
(struct ada_psym_data): Remove and replace with...
(struct match_data): User data for map_matching_symbols.
(ada_add_psyms): Remove.
(aux_add_nonlocal_symbols): New function, used as callback for
map_matching_symbols.
(compare_names): Ordering function adopted from strcmp_iw for Ada-encoded
symbols.
(ada_add_non_local_symbols): Rename to add_nonlocal_symbols.
(add_nonlocal_symbols): Renamed from ada_add_non_local_symbols.
Rework to use map_matching_symbols instead of map_ada_symtabs.
(ada_lookup_symbol_list): Use add_nonlocal_symbols.
* psymtab.c: Include dependency on dictionary.h.
(match_partial_symbol): New function.
(ada_lookup_partial_symbol): Remove.
(map_block): New function, auxiliary to map_matching_symbols_psymtab.
(map_matching_symbols_psymtab): New function.
(psym_functions): Replace map_ada_symtabs with map_matching_symbols_psymtab.
* symfile.h: Replace map_ada_symtabs definition with map_matching_symbols.
---
gdb/ada-lang.c | 157 +++++++++++++++++++++++-------
gdb/dwarf2read.c | 20 ++--
gdb/psymtab.c | 284 ++++++++++++++++++++++++++----------------------------
gdb/symfile.h | 40 +++++---
4 files changed, 289 insertions(+), 212 deletions(-)
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 912cc22..9ecf923 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -103,6 +103,8 @@ static int ada_type_match (struct type *, struct type *, int);
static int ada_args_match (struct symbol *, struct value **, int);
+static int full_match (const char *, const char *);
+
static struct value *make_array_descriptor (struct type *, struct value *);
static void ada_add_block_symbols (struct obstack *,
@@ -1254,7 +1256,7 @@ ada_la_decode (const char *encoded, int options)
either argument is NULL. */
static int
-ada_match_name (const char *sym_name, const char *name, int wild)
+match_name (const char *sym_name, const char *name, int wild)
{
if (sym_name == NULL || name == NULL)
return 0;
@@ -4267,7 +4269,7 @@ ada_lookup_simple_minsym (const char *name)
ALL_MSYMBOLS (objfile, msymbol)
{
- if (ada_match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match)
+ if (match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match)
&& MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
return msymbol;
}
@@ -4627,28 +4629,89 @@ ada_add_local_symbols (struct obstack *obstackp, const char *name,
}
/* An object of this type is used as the user_data argument when
- calling the map_ada_symtabs method. */
+ calling the map_matching_symbols method. */
-struct ada_psym_data
+struct match_data
{
+ struct objfile *objfile;
struct obstack *obstackp;
- const char *name;
- domain_enum domain;
- int global;
- int wild_match;
+ struct symbol *arg_sym;
+ int found_sym;
};
-/* Callback function for map_ada_symtabs. */
-
-static void
-ada_add_psyms (struct objfile *objfile, struct symtab *s, void *user_data)
+/* A callback for add_matching_symbols that adds SYM, found in BLOCK,
+ to a list of symbols. DATA0 is a pointer to a struct match_data *
+ containing the obstack that collects the symbol list, the file that SYM
+ must come from, a flag indicating whether a non-argument symbol has
+ been found in the current block, and the last argument symbol
+ passed in SYM within the current block (if any). When SYM is null,
+ marking the end of a block, the argument symbol is added if no
+ other has been found. */
+static int
+aux_add_nonlocal_symbols (struct block *block, struct symbol *sym, void *data0)
{
- struct ada_psym_data *data = user_data;
- const int block_kind = data->global ? GLOBAL_BLOCK : STATIC_BLOCK;
+ struct match_data *data = (struct match_data *) data0;
+
+ if (sym == NULL)
+ {
+ if (!data->found_sym && data->arg_sym != NULL)
+ add_defn_to_vec (data->obstackp,
+ fixup_symbol_section (data->arg_sym, data->objfile),
+ block);
+ data->found_sym = 0;
+ data->arg_sym = NULL;
+ }
+ else
+ {
+ if (SYMBOL_CLASS (sym) == LOC_UNRESOLVED)
+ return 0;
+ else if (SYMBOL_IS_ARGUMENT (sym))
+ data->arg_sym = sym;
+ else
+ {
+ data->found_sym = 1;
+ add_defn_to_vec (data->obstackp,
+ fixup_symbol_section (sym, data->objfile),
+ block);
+ }
+ }
+ return 0;
+}
- ada_add_block_symbols (data->obstackp,
- BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), block_kind),
- data->name, data->domain, objfile, data->wild_match);
+/* Compare STRING1 to STRING2, with results as for strcmp.
+ Compatible with strcmp_iw in that strcmp_iw (STRING1, STRING2) <= 0
+ implies compare_names (STRING1, STRING2) (they may differ as to
+ what symbols compare equal). */
+static int
+compare_names (const char *string1, const char *string2)
+{
+ while (*string1 != '\0' && *string2 != '\0')
+ {
+ if (isspace (*string1) || isspace (*string2))
+ return strcmp_iw_ordered (string1, string2);
+ if (*string1 != *string2)
+ break;
+ string1 += 1;
+ string2 += 1;
+ }
+ switch (*string1)
+ {
+ case '(':
+ return strcmp_iw_ordered (string1, string2);
+ case '_':
+ if (*string2 == '\0')
+ {
+ if (is_name_suffix (string2))
+ return 0;
+ else
+ return -1;
+ }
+ default:
+ if (*string2 == '(')
+ return strcmp_iw_ordered (string1, string2);
+ else
+ return *string1 - *string2;
+ }
}
/* Add to OBSTACKP all non-local symbols whose name and domain match
@@ -4656,27 +4719,43 @@ ada_add_psyms (struct objfile *objfile, struct symtab *s, void *user_data)
symbols if GLOBAL is non-zero, or on STATIC_BLOCK symbols otherwise. */
static void
-ada_add_non_local_symbols (struct obstack *obstackp, const char *name,
- domain_enum domain, int global,
- int is_wild_match)
+add_nonlocal_symbols (struct obstack *obstackp, const char *name,
+ domain_enum domain, int global,
+ int is_wild_match)
{
struct objfile *objfile;
- struct ada_psym_data data;
+ struct match_data data;
data.obstackp = obstackp;
- data.name = name;
- data.domain = domain;
- data.global = global;
- data.wild_match = is_wild_match;
+ data.arg_sym = NULL;
ALL_OBJFILES (objfile)
- {
- if (objfile->sf)
- objfile->sf->qf->map_ada_symtabs (objfile, wild_match, is_name_suffix,
- ada_add_psyms, name,
- global, domain,
- is_wild_match, &data);
- }
+ {
+ data.objfile = objfile;
+
+ if (is_wild_match)
+ objfile->sf->qf->map_matching_symbols (name, domain, objfile, global,
+ aux_add_nonlocal_symbols, &data,
+ wild_match, NULL);
+ else
+ objfile->sf->qf->map_matching_symbols (name, domain, objfile, global,
+ aux_add_nonlocal_symbols, &data,
+ full_match, compare_names);
+ }
+
+ if (num_defns_collected (obstackp) == 0 && global && !is_wild_match)
+ {
+ ALL_OBJFILES (objfile)
+ {
+ char *name1 = alloca (strlen (name) + sizeof ("_ada_"));
+ strcpy (name1, "_ada_");
+ strcpy (name1 + sizeof ("_ada_") - 1, name);
+ data.objfile = objfile;
+ objfile->sf->qf->map_matching_symbols (name1, domain, objfile, global,
+ aux_add_nonlocal_symbols, &data,
+ full_match, compare_names);
+ }
+ }
}
/* Find symbols in DOMAIN matching NAME0, in BLOCK0 and enclosing
@@ -4753,15 +4832,15 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0,
/* Search symbols from all global blocks. */
- ada_add_non_local_symbols (&symbol_list_obstack, name, namespace, 1,
- wild_match);
+ add_nonlocal_symbols (&symbol_list_obstack, name, namespace, 1,
+ wild_match);
/* Now add symbols from all per-file blocks if we've gotten no hits
(not strictly correct, but perhaps better than an error). */
if (num_defns_collected (&symbol_list_obstack) == 0)
- ada_add_non_local_symbols (&symbol_list_obstack, name, namespace, 0,
- wild_match);
+ add_nonlocal_symbols (&symbol_list_obstack, name, namespace, 0,
+ wild_match);
done:
ndefns = num_defns_collected (&symbol_list_obstack);
@@ -5062,10 +5141,12 @@ wild_match (const char *name, const char *patn)
}
}
+/* Returns 0 iff symbol name SYM_NAME matches SEARCH_NAME, apart from
+ informational suffix. */
static int
full_match (const char* sym_name, const char* search_name)
{
- return !ada_match_name (sym_name, search_name, 0);
+ return !match_name (sym_name, search_name, 0);
}
@@ -5118,7 +5199,7 @@ ada_add_block_symbols (struct obstack *obstackp,
else
{
for (sym = dict_iter_match_first (BLOCK_DICT (block), name,
- full_match, &iter);
+ full_match, &iter);
sym != NULL; sym = dict_iter_match_next (name, full_match, &iter))
{
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index bf36e01..4525875 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -2371,16 +2371,16 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name)
}
static void
-dw2_map_ada_symtabs (struct objfile *objfile,
- int (*wild_match) (const char *, const char *),
- int (*is_name_suffix) (const char *),
- void (*callback) (struct objfile *,
- struct symtab *, void *),
- const char *name, int global,
- domain_enum namespace, int wild,
- void *data)
-{
- /* For now, we don't support Ada. Still the function can be called if the
+dw2_map_matching_symbols (const char* name, domain_enum namespace,
+ struct objfile *objfile, int global,
+ int (*callback) (struct block *,
+ struct symbol *, void *),
+ void *data,
+ int (*match) (const char *, const char *),
+ int (*ordered_compare) (const char *,
+ const char *))
+{
+ /* Currently unimplemented; used for Ada. The function can be called if the
current language is Ada for a non-Ada objfile using GNU index. As Ada
does not look for non-Ada symbols this function should just return. */
}
@@ -2560,7 +2560,7 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions =
dw2_expand_all_symtabs,
dw2_expand_symtabs_with_filename,
dw2_find_symbol_file,
- dw2_map_ada_symtabs,
+ dw2_map_matching_symbols,
dw2_expand_symtabs_matching,
dw2_find_pc_sect_symtab,
dw2_map_symbol_names,
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index eac3e1a..f98e9ef 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -32,6 +32,7 @@
#include "command.h"
#include "readline/readline.h"
#include "gdb_regex.h"
+#include "dictionary.h"
#ifndef DEV_TTY
#define DEV_TTY "/dev/tty"
@@ -47,6 +48,15 @@ struct psymbol_bcache
((pst) -> symtab != NULL ? (pst) -> symtab : psymtab_to_symtab (pst))
/* Lookup a partial symbol. */
+static struct partial_symbol *match_partial_symbol (struct partial_symtab *,
+ int,
+ const char *, domain_enum,
+ int (*) (const char *,
+ const char *),
+ int (*) (const char *,
+ const char *));
+
+
static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
const char *, int,
domain_enum);
@@ -426,6 +436,84 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile,
return NULL;
}
+/* Look in PST for a symbol in DOMAIN whose name matches NAME. Search
+ the global block of PST if GLOBAL, and otherwise the static block.
+ MATCH is the comparison operation that returns true iff MATCH (s,
+ NAME), where s is a SYMBOL_SEARCH_NAME. If ORDERED_COMPARE is
+ non-null, the symbols in the block are assumed to be ordered
+ according to it (allowing binary search). It must be compatible
+ with MATCH. Returns the symbol, if found, and otherwise NULL. */
+static struct partial_symbol *
+match_partial_symbol (struct partial_symtab *pst, int global,
+ const char *name, domain_enum domain,
+ int (*match) (const char *, const char *),
+ int (*ordered_compare) (const char *, const char *))
+{
+ struct partial_symbol **start, **psym;
+ struct partial_symbol **top, **real_top, **bottom, **center;
+ int length = (global ? pst->n_global_syms : pst->n_static_syms);
+ int do_linear_search = 1;
+
+ if (length == 0)
+ return NULL;
+ start = (global ?
+ pst->objfile->global_psymbols.list + pst->globals_offset :
+ pst->objfile->static_psymbols.list + pst->statics_offset);
+
+ if (global && ordered_compare) /* Can use a binary search. */
+ {
+ do_linear_search = 0;
+
+ /* Binary search. This search is guaranteed to end with center
+ pointing at the earliest partial symbol whose name might be
+ correct. At that point *all* partial symbols with an
+ appropriate name will be checked against the correct
+ domain. */
+
+ bottom = start;
+ top = start + length - 1;
+ real_top = top;
+ while (top > bottom)
+ {
+ center = bottom + (top - bottom) / 2;
+ gdb_assert (center < top);
+ if (!do_linear_search
+ && (SYMBOL_LANGUAGE (*center) == language_java))
+ do_linear_search = 1;
+ if (ordered_compare (SYMBOL_SEARCH_NAME (*center), name) >= 0)
+ top = center;
+ else
+ bottom = center + 1;
+ }
+ gdb_assert (top == bottom);
+
+ while (top <= real_top
+ && match (SYMBOL_SEARCH_NAME (*top), name) == 0)
+ {
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
+ SYMBOL_DOMAIN (*top), domain))
+ return (*top);
+ top++;
+ }
+ }
+
+ /* Can't use a binary search or else we found during the binary search that
+ we should also do a linear search. */
+
+ if (do_linear_search)
+ {
+ for (psym = start; psym < start + length; psym++)
+ {
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
+ SYMBOL_DOMAIN (*psym), domain)
+ && match (SYMBOL_SEARCH_NAME (*psym), name) == 0)
+ return (*psym);
+ }
+ }
+
+ return (NULL);
+}
+
static void
pre_expand_symtabs_matching_psymtabs (struct objfile *objfile,
int kind, const char *name,
@@ -435,7 +523,7 @@ pre_expand_symtabs_matching_psymtabs (struct objfile *objfile,
}
/* Look, in partial_symtab PST, for symbol whose natural name is NAME.
- Check the global symbols if GLOBAL, the static symbols if not. */
+ Check the global symbols if GLOBAL, the static symbols if not. */
static struct partial_symbol *
lookup_partial_symbol (struct partial_symtab *pst, const char *name,
@@ -473,7 +561,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
if (!(center < top))
internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
if (!do_linear_search
- && (SYMBOL_LANGUAGE (*center) == language_java))
+ && SYMBOL_LANGUAGE (*center) == language_java)
{
do_linear_search = 1;
}
@@ -500,7 +588,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
}
/* Can't use a binary search or else we found during the binary search that
- we should also do a linear search. */
+ we should also do a linear search. */
if (do_linear_search)
{
@@ -967,174 +1055,72 @@ find_symbol_file_from_partial (struct objfile *objfile, const char *name)
return NULL;
}
-/* Look, in partial_symtab PST, for symbol NAME in given namespace.
- Check the global symbols if GLOBAL, the static symbols if not.
- Do wild-card match if WILD. */
+/* For all symbols, s, in BLOCK that are in NAMESPACE and match NAME
+ according to the function MATCH, call CALLBACK(BLOCK, s, DATA).
+ BLOCK is assumed to come from OBJFILE. Returns 1 iff CALLBACK
+ ever returns non-zero, and otherwise returns 0. */
-static struct partial_symbol *
-ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name,
- int global, domain_enum namespace, int wild,
- int (*wild_match) (const char *, const char *),
- int (*is_name_suffix) (const char *))
+static int
+map_block (const char *name, domain_enum namespace, struct objfile *objfile,
+ struct block *block,
+ int (*callback) (struct block *, struct symbol *, void *),
+ void *data,
+ int (*match) (const char *, const char *))
{
- struct partial_symbol **start;
- int name_len = strlen (name);
- int length = (global ? pst->n_global_syms : pst->n_static_syms);
- int i;
+ struct dict_iterator iter;
+ struct symbol *sym;
- if (length == 0)
+ for (sym = dict_iter_match_first (BLOCK_DICT (block), name, match, &iter);
+ sym != NULL; sym = dict_iter_match_next (name, match, &iter))
{
- return (NULL);
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ SYMBOL_DOMAIN (sym), namespace))
+ {
+ if (callback (block, sym, data))
+ return 1;
+ }
}
- start = (global ?
- pst->objfile->global_psymbols.list + pst->globals_offset :
- pst->objfile->static_psymbols.list + pst->statics_offset);
-
- if (wild)
- {
- for (i = 0; i < length; i += 1)
- {
- struct partial_symbol *psym = start[i];
-
- if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
- SYMBOL_DOMAIN (psym), namespace)
- && (*wild_match) (SYMBOL_LINKAGE_NAME (psym), name) == 0)
- return psym;
- }
- return NULL;
- }
- else
- {
- if (global)
- {
- int U;
-
- i = 0;
- U = length - 1;
- while (U - i > 4)
- {
- int M = (U + i) >> 1;
- struct partial_symbol *psym = start[M];
-
- if (SYMBOL_LINKAGE_NAME (psym)[0] < name[0])
- i = M + 1;
- else if (SYMBOL_LINKAGE_NAME (psym)[0] > name[0])
- U = M - 1;
- else if (strcmp (SYMBOL_LINKAGE_NAME (psym), name) < 0)
- i = M + 1;
- else
- U = M;
- }
- }
- else
- i = 0;
-
- while (i < length)
- {
- struct partial_symbol *psym = start[i];
-
- if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
- SYMBOL_DOMAIN (psym), namespace))
- {
- int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym), name_len);
-
- if (cmp < 0)
- {
- if (global)
- break;
- }
- else if (cmp == 0
- && (*is_name_suffix) (SYMBOL_LINKAGE_NAME (psym)
- + name_len))
- return psym;
- }
- i += 1;
- }
-
- if (global)
- {
- int U;
-
- i = 0;
- U = length - 1;
- while (U - i > 4)
- {
- int M = (U + i) >> 1;
- struct partial_symbol *psym = start[M];
-
- if (SYMBOL_LINKAGE_NAME (psym)[0] < '_')
- i = M + 1;
- else if (SYMBOL_LINKAGE_NAME (psym)[0] > '_')
- U = M - 1;
- else if (strcmp (SYMBOL_LINKAGE_NAME (psym), "_ada_") < 0)
- i = M + 1;
- else
- U = M;
- }
- }
- else
- i = 0;
-
- while (i < length)
- {
- struct partial_symbol *psym = start[i];
-
- if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
- SYMBOL_DOMAIN (psym), namespace))
- {
- int cmp;
-
- cmp = (int) '_' - (int) SYMBOL_LINKAGE_NAME (psym)[0];
- if (cmp == 0)
- {
- cmp = strncmp ("_ada_", SYMBOL_LINKAGE_NAME (psym), 5);
- if (cmp == 0)
- cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym) + 5,
- name_len);
- }
-
- if (cmp < 0)
- {
- if (global)
- break;
- }
- else if (cmp == 0
- && (*is_name_suffix) (SYMBOL_LINKAGE_NAME (psym)
- + name_len + 5))
- return psym;
- }
- i += 1;
- }
- }
- return NULL;
+ return 0;
}
+/* Psymtab version of map_matching_symbols. See its definition in
+ the definition of quick_symbol_functions in symfile.h. */
+
static void
-map_ada_symtabs (struct objfile *objfile,
- int (*wild_match) (const char *, const char *),
- int (*is_name_suffix) (const char *),
- void (*callback) (struct objfile *, struct symtab *, void *),
- const char *name, int global, domain_enum namespace, int wild,
- void *data)
+map_matching_symbols_psymtab (const char *name, domain_enum namespace,
+ struct objfile *objfile, int global,
+ int (*callback) (struct block *,
+ struct symbol *, void *),
+ void *data,
+ int (*match) (const char *, const char *),
+ int (*ordered_compare) (const char *,
+ const char *))
{
+ const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
struct partial_symtab *ps;
ALL_OBJFILE_PSYMTABS (objfile, ps)
{
QUIT;
if (ps->readin
- || ada_lookup_partial_symbol (ps, name, global, namespace, wild,
- wild_match, is_name_suffix))
+ || match_partial_symbol (ps, global, name, namespace, match,
+ ordered_compare))
{
struct symtab *s = PSYMTAB_TO_SYMTAB (ps);
+ struct block *block;
if (s == NULL || !s->primary)
continue;
- (*callback) (objfile, s, data);
+ block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), block_kind);
+ if (map_block (name, namespace, objfile, block,
+ callback, data, match))
+ return;
+ if (callback (block, NULL, data))
+ return;
}
}
-}
+}
static void
expand_symtabs_matching_via_partial (struct objfile *objfile,
@@ -1220,7 +1206,7 @@ const struct quick_symbol_functions psym_functions =
expand_partial_symbol_tables,
read_psymtabs_with_filename,
find_symbol_file_from_partial,
- map_ada_symtabs,
+ map_matching_symbols_psymtab,
expand_symtabs_matching_via_partial,
find_pc_sect_symtab_from_partial,
map_symbol_names_psymtab,
diff --git a/gdb/symfile.h b/gdb/symfile.h
index f9b4e01..c9f4e65 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -212,21 +212,31 @@ struct quick_symbol_functions
named NAME. If no such symbol exists in OBJFILE, return NULL. */
const char *(*find_symbol_file) (struct objfile *objfile, const char *name);
- /* This method is specific to Ada. It walks the partial symbol
- tables of OBJFILE looking for a name match. WILD_MATCH and
- IS_NAME_SUFFIX are predicate functions that the implementation
- may call to check for a match.
-
- This function is completely ad hoc and new implementations should
- refer to the psymtab implementation to see what to do. */
- void (*map_ada_symtabs) (struct objfile *objfile,
- int (*wild_match) (const char *, const char *),
- int (*is_name_suffix) (const char *),
- void (*callback) (struct objfile *,
- struct symtab *, void *),
- const char *name, int global,
- domain_enum namespace, int wild,
- void *data);
+ /* Find global or static symbols in all tables that are in NAMESPACE
+ and for which MATCH (symbol name, NAME) == 0, passing each to
+ CALLBACK, reading in partial symbol symbol tables as needed. Look
+ through global symbols if GLOBAL and otherwise static symbols.
+ Passes NAME, NAMESPACE, and DATA to CALLBACK with each symbol
+ found. After each block is processed, passes NULL to CALLBACK.
+ MATCH must be weaker than strcmp_iw in the sense that
+ strcmp_iw(x,y) == 0 --> MATCH(x,y) == 0. ORDERED_COMPARE, if
+ non-null, must be an ordering relation compatible with strcmp_iw
+ in the sense that
+ strcmp(x,y) == 0 --> ORDERED_COMPARE(x,y) == 0
+ and
+ strcmp(x,y) <= 0 --> ORDERED_COMPARE(x,y) <= 0
+ (allowing strcmp(x,y) < 0 while ORDERED_COMPARE(x, y) == 0).
+ CALLBACK returns 0 to indicate that the scan should continue, or
+ non-zero to indicate that the scan should be terminated. */
+
+ void (*map_matching_symbols) (const char *name, domain_enum namespace,
+ struct objfile *, int global,
+ int (*callback) (struct block *,
+ struct symbol *, void *),
+ void *data,
+ int (*match) (const char *, const char *),
+ int (*ordered_compare) (const char *,
+ const char *));
/* Expand all symbol tables in OBJFILE matching some criteria.
--
1.7.0.4
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [RFA] Rework symbol searches to move Ada-specific stuff to ada-lang.c. 2010-10-05 8:42 [RFA] Rework symbol searches to move Ada-specific stuff to ada-lang.c Paul Hilfinger @ 2010-10-06 22:52 ` Tom Tromey 2010-10-07 4:14 ` Paul Hilfinger 2010-10-07 7:19 ` [commit] " Paul Hilfinger 2010-10-06 23:15 ` [RFA] " Joel Brobecker 1 sibling, 2 replies; 8+ messages in thread From: Tom Tromey @ 2010-10-06 22:52 UTC (permalink / raw) To: Hilfinger; +Cc: gdb-patches >>>>> "Paul" == Paul Hilfinger <hilfingr@syracuse.mckusick.com> writes: Paul> Having added this general routine to psymtab.c, we use it in ada-lang.c Paul> to rework add_non_local_symbols (now renamed add_nonlocal_symbols). I don't think I should approve the ada-specific changes -- and I was wrong to do so in my last review, I'll send a follow-up. The psymtab / symfile / dwarf2read changes seem fine though. I have a few little nits. Paul> +dw2_map_matching_symbols (const char* name, domain_enum namespace, "const char *name" Paul> /* Lookup a partial symbol. */ Paul> +static struct partial_symbol *match_partial_symbol (struct partial_symtab *, Paul> + int, Paul> + const char *, domain_enum, Paul> + int (*) (const char *, Paul> + const char *), Paul> + int (*) (const char *, Paul> + const char *)); Paul> + Paul> + Paul> static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *, This insertion separates a comment from the declaration it comments. I think it is fine to just remove that comment, though. It doesn't really add anything. Paul> +/* Look in PST for a symbol in DOMAIN whose name matches NAME. Search Paul> + the global block of PST if GLOBAL, and otherwise the static block. Paul> + MATCH is the comparison operation that returns true iff MATCH (s, Paul> + NAME), where s is a SYMBOL_SEARCH_NAME. If ORDERED_COMPARE is Paul> + non-null, the symbols in the block are assumed to be ordered Paul> + according to it (allowing binary search). It must be compatible Paul> + with MATCH. Returns the symbol, if found, and otherwise NULL. */ Paul> +static struct partial_symbol * Paul> +match_partial_symbol (struct partial_symtab *pst, int global, We've recently started trying to enforce the rule about having a blank line between a function comment and the start of the function definition. Paul> + return (*top); A few places have parens here, but they aren't needed. Just write "return *top;". Paul> + /* Find global or static symbols in all tables that are in NAMESPACE Paul> + and for which MATCH (symbol name, NAME) == 0, passing each to Paul> + CALLBACK, reading in partial symbol symbol tables as needed. Look Paul> + through global symbols if GLOBAL and otherwise static symbols. Paul> + Passes NAME, NAMESPACE, and DATA to CALLBACK with each symbol Paul> + found. After each block is processed, passes NULL to CALLBACK. Paul> + MATCH must be weaker than strcmp_iw in the sense that Paul> + strcmp_iw(x,y) == 0 --> MATCH(x,y) == 0. ORDERED_COMPARE, if Paul> + non-null, must be an ordering relation compatible with strcmp_iw Paul> + in the sense that Paul> + strcmp(x,y) == 0 --> ORDERED_COMPARE(x,y) == 0 Paul> + and Paul> + strcmp(x,y) <= 0 --> ORDERED_COMPARE(x,y) <= 0 Paul> + (allowing strcmp(x,y) < 0 while ORDERED_COMPARE(x, y) == 0). Paul> + CALLBACK returns 0 to indicate that the scan should continue, or Paul> + non-zero to indicate that the scan should be terminated. */ Thanks for being so thorough in this comment. Tom ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFA] Rework symbol searches to move Ada-specific stuff to ada-lang.c. 2010-10-06 22:52 ` Tom Tromey @ 2010-10-07 4:14 ` Paul Hilfinger 2010-10-07 17:53 ` Tom Tromey 2010-10-07 7:19 ` [commit] " Paul Hilfinger 1 sibling, 1 reply; 8+ messages in thread From: Paul Hilfinger @ 2010-10-07 4:14 UTC (permalink / raw) To: Tom Tromey; +Cc: Hilfinger, gdb-patches On Wed, 2010-10-06 at 16:51 -0600, Tom Tromey wrote: > >>>>> "Paul" == Paul Hilfinger <hilfingr@syracuse.mckusick.com> writes: > > Paul> +dw2_map_matching_symbols (const char* name, domain_enum namespace, > > "const char *name" > OK. > Paul> /* Lookup a partial symbol. */ > Paul> +static struct partial_symbol *match_partial_symbol (struct partial_symtab *, > Paul> + int, > Paul> + const char *, domain_enum, > Paul> + int (*) (const char *, > Paul> + const char *), > Paul> + int (*) (const char *, > Paul> + const char *)); > Paul> + > Paul> + > Paul> static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *, > > This insertion separates a comment from the declaration it comments. > > I think it is fine to just remove that comment, though. It doesn't > really add anything. > OK > Paul> +/* Look in PST for a symbol in DOMAIN whose name matches NAME. Search > Paul> + the global block of PST if GLOBAL, and otherwise the static block. > Paul> + MATCH is the comparison operation that returns true iff MATCH (s, > Paul> + NAME), where s is a SYMBOL_SEARCH_NAME. If ORDERED_COMPARE is > Paul> + non-null, the symbols in the block are assumed to be ordered > Paul> + according to it (allowing binary search). It must be compatible > Paul> + with MATCH. Returns the symbol, if found, and otherwise NULL. */ > Paul> +static struct partial_symbol * > Paul> +match_partial_symbol (struct partial_symtab *pst, int global, > > We've recently started trying to enforce the rule about having a blank > line between a function comment and the start of the function > definition. OK. > Paul> + return (*top); > > A few places have parens here, but they aren't needed. > Just write "return *top;". OK (BTW: That line was copied from the original). > > Paul> + /* Find global or static symbols in all tables that are in NAMESPACE > Paul> + and for which MATCH (symbol name, NAME) == 0, passing each to > Paul> + CALLBACK, reading in partial symbol symbol tables as needed. Look > Paul> + through global symbols if GLOBAL and otherwise static symbols. > Paul> + Passes NAME, NAMESPACE, and DATA to CALLBACK with each symbol > Paul> + found. After each block is processed, passes NULL to CALLBACK. > Paul> + MATCH must be weaker than strcmp_iw in the sense that > Paul> + strcmp_iw(x,y) == 0 --> MATCH(x,y) == 0. ORDERED_COMPARE, if > Paul> + non-null, must be an ordering relation compatible with strcmp_iw > Paul> + in the sense that > Paul> + strcmp(x,y) == 0 --> ORDERED_COMPARE(x,y) == 0 > Paul> + and > Paul> + strcmp(x,y) <= 0 --> ORDERED_COMPARE(x,y) <= 0 > Paul> + (allowing strcmp(x,y) < 0 while ORDERED_COMPARE(x, y) == 0). > Paul> + CALLBACK returns 0 to indicate that the scan should continue, or > Paul> + non-zero to indicate that the scan should be terminated. */ > > Thanks for being so thorough in this comment. You're welcome. Paul ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFA] Rework symbol searches to move Ada-specific stuff to ada-lang.c. 2010-10-07 4:14 ` Paul Hilfinger @ 2010-10-07 17:53 ` Tom Tromey 0 siblings, 0 replies; 8+ messages in thread From: Tom Tromey @ 2010-10-07 17:53 UTC (permalink / raw) To: Hilfinger; +Cc: Hilfinger, gdb-patches >>>>> "Paul" == Paul Hilfinger <HIlfinger@cs.berkeley.edu> writes: Paul> + return (*top); Tom> A few places have parens here, but they aren't needed. Tom> Just write "return *top;". Paul> OK (BTW: That line was copied from the original). Oh, ok. I had looked to see if this was the case, but I must have missed it. My view is that it is always ok to leave code as-is when moving it around. I recommend pushing back on reviewers who ask for changes to the context of a patch :-) Tom ^ permalink raw reply [flat|nested] 8+ messages in thread
* [commit] Rework symbol searches to move Ada-specific stuff to ada-lang.c. 2010-10-06 22:52 ` Tom Tromey 2010-10-07 4:14 ` Paul Hilfinger @ 2010-10-07 7:19 ` Paul Hilfinger 1 sibling, 0 replies; 8+ messages in thread From: Paul Hilfinger @ 2010-10-07 7:19 UTC (permalink / raw) To: gdb-patches I've committed the following, with the suggested changes. Paul Hilfinger This is a clean-up of some of our symbol-lookup machinery to pull some kludgy Ada-specific definitions out of psymtab.c. In place of map_ada_symtabs and ada_lookup_partial_symbol, we have a method map_matching_symbols, which searches through all symbol tables and partial symbol tables looking for a symbol that matches according to a matching function that is passed as a parameter. This requires some care, because partial symbol tables speed up searches by binary search, while full symbol tables use hashing. To call map_matching_symbols, therefore, you may need to supply both a matching function that is compatible with the dictionary hash function and an ordering relation that is compatible with strcmp_iw, which is used to order partial symbol tables. Having added this general routine to psymtab.c, we use it in ada-lang.c to rework add_non_local_symbols (now renamed add_nonlocal_symbols). Changelog: gdb/ * ada-lang.c (full_match): Declare. (ada_match_name): Rename to match_name (we should avoid prefixing static symbols with "ada_"). (match_name): New name for ada_match_name. (struct ada_psym_data): Remove and replace with... (struct match_data): User data for map_matching_symbols. (ada_add_psyms): Remove. (aux_add_nonlocal_symbols): New function, used as callback for map_matching_symbols. (compare_names): Ordering function adopted from strcmp_iw for Ada-encoded symbols. (ada_add_non_local_symbols): Rename to add_nonlocal_symbols. (add_nonlocal_symbols): Renamed from ada_add_non_local_symbols. Rework to use map_matching_symbols instead of map_ada_symtabs. (ada_lookup_symbol_list): Use add_nonlocal_symbols. * psymtab.c: Include dependency on dictionary.h. (match_partial_symbol): New function. (ada_lookup_partial_symbol): Remove. (map_block): New function, auxiliary to map_matching_symbols_psymtab. (map_matching_symbols_psymtab): New function. (psym_functions): Replace map_ada_symtabs with map_matching_symbols_psymtab. * symfile.h: Replace map_ada_symtabs definition with map_matching_symbols. --- gdb/ChangeLog | 61 ++++++++---- gdb/ada-lang.c | 158 +++++++++++++++++++++++------- gdb/dwarf2read.c | 20 ++-- gdb/psymtab.c | 286 ++++++++++++++++++++++++++---------------------------- gdb/symfile.h | 40 +++++--- 5 files changed, 335 insertions(+), 230 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9e5a615..803edfe 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,24 +1,49 @@ +2010-10-07 Paul Hilfinger <hilfinger@adacore.com> + + * ada-lang.c (full_match): Declare. + (ada_match_name): Rename to match_name (we should avoid prefixing static + symbols with "ada_"). + (match_name): New name for ada_match_name. + (struct ada_psym_data): Remove and replace with... + (struct match_data): User data for map_matching_symbols. + (ada_add_psyms): Remove. + (aux_add_nonlocal_symbols): New function, used as callback for + map_matching_symbols. + (compare_names): Ordering function adopted from strcmp_iw for Ada-encoded + symbols. + (ada_add_non_local_symbols): Rename to add_nonlocal_symbols. + (add_nonlocal_symbols): Renamed from ada_add_non_local_symbols. + Rework to use map_matching_symbols instead of map_ada_symtabs. + (ada_lookup_symbol_list): Use add_nonlocal_symbols. + * psymtab.c: Include dependency on dictionary.h. + (match_partial_symbol): New function. + (ada_lookup_partial_symbol): Remove. + (map_block): New function, auxiliary to map_matching_symbols_psymtab. + (map_matching_symbols_psymtab): New function. + (psym_functions): Replace map_ada_symtabs with map_matching_symbols_psymtab. + * symfile.h: Replace map_ada_symtabs definition with map_matching_symbols. + 2010-10-06 Paul Hilfinger <hilfinger@adacore.com> * ada-lang.c (ada_match_name): Use new API for wild_match. - (wild_match): Change API to be consistent with that of strcmp_iw; - return 0 for a match, and switch operand order. - (full_match): New function. - (ada_add_block_symbols): Use dict_iter_match_{first,next} for - matching to allow use of hashing. - * dictionary.c (struct dict_vector): Generalize iter_name_first, - iter_name_next ot iter_match_first, iter_match_next. - (iter_name_first_hashed): Replace with iter_match_first_hashed. - (iter_name_next_hashed): Replace with iter_match_next_hashed. - (iter_name_first_linear): Replace with iter_match_first_linear. - (iter_name_next_linear): Replace with iter_match_next_linear. - (dict_iter_name_first): Re-implement to use dict_iter_match_first. - (dict_iter_name_next): Re-implement to use dict_iter_match_next. - (dict_iter_match_first): New function. - (dict_iter_match_next): New function. - (dict_hash): New function. - * dictionary.h (dict_iter_match_first, dict_iter_match_next): Declare. - * psymtab.c (ada_lookup_partial_symbol): Use new wild_match API. + (wild_match): Change API to be consistent with that of strcmp_iw; + return 0 for a match, and switch operand order. + (full_match): New function. + (ada_add_block_symbols): Use dict_iter_match_{first,next} for + matching to allow use of hashing. + * dictionary.c (struct dict_vector): Generalize iter_name_first, + iter_name_next ot iter_match_first, iter_match_next. + (iter_name_first_hashed): Replace with iter_match_first_hashed. + (iter_name_next_hashed): Replace with iter_match_next_hashed. + (iter_name_first_linear): Replace with iter_match_first_linear. + (iter_name_next_linear): Replace with iter_match_next_linear. + (dict_iter_name_first): Re-implement to use dict_iter_match_first. + (dict_iter_name_next): Re-implement to use dict_iter_match_next. + (dict_iter_match_first): New function. + (dict_iter_match_next): New function. + (dict_hash): New function. + * dictionary.h (dict_iter_match_first, dict_iter_match_next): Declare. + * psymtab.c (ada_lookup_partial_symbol): Use new wild_match API. 2010-10-06 Doug Evans <dje@google.com> diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index c111e40..ea71ea2 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -103,6 +103,8 @@ static int ada_type_match (struct type *, struct type *, int); static int ada_args_match (struct symbol *, struct value **, int); +static int full_match (const char *, const char *); + static struct value *make_array_descriptor (struct type *, struct value *); static void ada_add_block_symbols (struct obstack *, @@ -1254,7 +1256,7 @@ ada_la_decode (const char *encoded, int options) either argument is NULL. */ static int -ada_match_name (const char *sym_name, const char *name, int wild) +match_name (const char *sym_name, const char *name, int wild) { if (sym_name == NULL || name == NULL) return 0; @@ -4267,7 +4269,7 @@ ada_lookup_simple_minsym (const char *name) ALL_MSYMBOLS (objfile, msymbol) { - if (ada_match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match) + if (match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match) && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline) return msymbol; } @@ -4627,28 +4629,91 @@ ada_add_local_symbols (struct obstack *obstackp, const char *name, } /* An object of this type is used as the user_data argument when - calling the map_ada_symtabs method. */ + calling the map_matching_symbols method. */ -struct ada_psym_data +struct match_data { + struct objfile *objfile; struct obstack *obstackp; - const char *name; - domain_enum domain; - int global; - int wild_match; + struct symbol *arg_sym; + int found_sym; }; -/* Callback function for map_ada_symtabs. */ +/* A callback for add_matching_symbols that adds SYM, found in BLOCK, + to a list of symbols. DATA0 is a pointer to a struct match_data * + containing the obstack that collects the symbol list, the file that SYM + must come from, a flag indicating whether a non-argument symbol has + been found in the current block, and the last argument symbol + passed in SYM within the current block (if any). When SYM is null, + marking the end of a block, the argument symbol is added if no + other has been found. */ -static void -ada_add_psyms (struct objfile *objfile, struct symtab *s, void *user_data) +static int +aux_add_nonlocal_symbols (struct block *block, struct symbol *sym, void *data0) { - struct ada_psym_data *data = user_data; - const int block_kind = data->global ? GLOBAL_BLOCK : STATIC_BLOCK; + struct match_data *data = (struct match_data *) data0; + + if (sym == NULL) + { + if (!data->found_sym && data->arg_sym != NULL) + add_defn_to_vec (data->obstackp, + fixup_symbol_section (data->arg_sym, data->objfile), + block); + data->found_sym = 0; + data->arg_sym = NULL; + } + else + { + if (SYMBOL_CLASS (sym) == LOC_UNRESOLVED) + return 0; + else if (SYMBOL_IS_ARGUMENT (sym)) + data->arg_sym = sym; + else + { + data->found_sym = 1; + add_defn_to_vec (data->obstackp, + fixup_symbol_section (sym, data->objfile), + block); + } + } + return 0; +} + +/* Compare STRING1 to STRING2, with results as for strcmp. + Compatible with strcmp_iw in that strcmp_iw (STRING1, STRING2) <= 0 + implies compare_names (STRING1, STRING2) (they may differ as to + what symbols compare equal). */ - ada_add_block_symbols (data->obstackp, - BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), block_kind), - data->name, data->domain, objfile, data->wild_match); +static int +compare_names (const char *string1, const char *string2) +{ + while (*string1 != '\0' && *string2 != '\0') + { + if (isspace (*string1) || isspace (*string2)) + return strcmp_iw_ordered (string1, string2); + if (*string1 != *string2) + break; + string1 += 1; + string2 += 1; + } + switch (*string1) + { + case '(': + return strcmp_iw_ordered (string1, string2); + case '_': + if (*string2 == '\0') + { + if (is_name_suffix (string2)) + return 0; + else + return -1; + } + default: + if (*string2 == '(') + return strcmp_iw_ordered (string1, string2); + else + return *string1 - *string2; + } } /* Add to OBSTACKP all non-local symbols whose name and domain match @@ -4656,27 +4721,43 @@ ada_add_psyms (struct objfile *objfile, struct symtab *s, void *user_data) symbols if GLOBAL is non-zero, or on STATIC_BLOCK symbols otherwise. */ static void -ada_add_non_local_symbols (struct obstack *obstackp, const char *name, - domain_enum domain, int global, - int is_wild_match) +add_nonlocal_symbols (struct obstack *obstackp, const char *name, + domain_enum domain, int global, + int is_wild_match) { struct objfile *objfile; - struct ada_psym_data data; + struct match_data data; data.obstackp = obstackp; - data.name = name; - data.domain = domain; - data.global = global; - data.wild_match = is_wild_match; + data.arg_sym = NULL; ALL_OBJFILES (objfile) - { - if (objfile->sf) - objfile->sf->qf->map_ada_symtabs (objfile, wild_match, is_name_suffix, - ada_add_psyms, name, - global, domain, - is_wild_match, &data); - } + { + data.objfile = objfile; + + if (is_wild_match) + objfile->sf->qf->map_matching_symbols (name, domain, objfile, global, + aux_add_nonlocal_symbols, &data, + wild_match, NULL); + else + objfile->sf->qf->map_matching_symbols (name, domain, objfile, global, + aux_add_nonlocal_symbols, &data, + full_match, compare_names); + } + + if (num_defns_collected (obstackp) == 0 && global && !is_wild_match) + { + ALL_OBJFILES (objfile) + { + char *name1 = alloca (strlen (name) + sizeof ("_ada_")); + strcpy (name1, "_ada_"); + strcpy (name1 + sizeof ("_ada_") - 1, name); + data.objfile = objfile; + objfile->sf->qf->map_matching_symbols (name1, domain, objfile, global, + aux_add_nonlocal_symbols, &data, + full_match, compare_names); + } + } } /* Find symbols in DOMAIN matching NAME0, in BLOCK0 and enclosing @@ -4753,15 +4834,15 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0, /* Search symbols from all global blocks. */ - ada_add_non_local_symbols (&symbol_list_obstack, name, namespace, 1, - wild_match); + add_nonlocal_symbols (&symbol_list_obstack, name, namespace, 1, + wild_match); /* Now add symbols from all per-file blocks if we've gotten no hits (not strictly correct, but perhaps better than an error). */ if (num_defns_collected (&symbol_list_obstack) == 0) - ada_add_non_local_symbols (&symbol_list_obstack, name, namespace, 0, - wild_match); + add_nonlocal_symbols (&symbol_list_obstack, name, namespace, 0, + wild_match); done: ndefns = num_defns_collected (&symbol_list_obstack); @@ -5062,10 +5143,13 @@ wild_match (const char *name, const char *patn) } } +/* Returns 0 iff symbol name SYM_NAME matches SEARCH_NAME, apart from + informational suffix. */ + static int full_match (const char *sym_name, const char *search_name) { - return !ada_match_name (sym_name, search_name, 0); + return !match_name (sym_name, search_name, 0); } @@ -5118,7 +5202,7 @@ ada_add_block_symbols (struct obstack *obstackp, else { for (sym = dict_iter_match_first (BLOCK_DICT (block), name, - full_match, &iter); + full_match, &iter); sym != NULL; sym = dict_iter_match_next (name, full_match, &iter)) { if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 02304cb..5aeb739 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -2371,16 +2371,16 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name) } static void -dw2_map_ada_symtabs (struct objfile *objfile, - int (*wild_match) (const char *, const char *), - int (*is_name_suffix) (const char *), - void (*callback) (struct objfile *, - struct symtab *, void *), - const char *name, int global, - domain_enum namespace, int wild, - void *data) -{ - /* For now, we don't support Ada. Still the function can be called if the +dw2_map_matching_symbols (const char * name, domain_enum namespace, + struct objfile *objfile, int global, + int (*callback) (struct block *, + struct symbol *, void *), + void *data, + int (*match) (const char *, const char *), + int (*ordered_compare) (const char *, + const char *)) +{ + /* Currently unimplemented; used for Ada. The function can be called if the current language is Ada for a non-Ada objfile using GNU index. As Ada does not look for non-Ada symbols this function should just return. */ } @@ -2560,7 +2560,7 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions = dw2_expand_all_symtabs, dw2_expand_symtabs_with_filename, dw2_find_symbol_file, - dw2_map_ada_symtabs, + dw2_map_matching_symbols, dw2_expand_symtabs_matching, dw2_find_pc_sect_symtab, dw2_map_symbol_names, diff --git a/gdb/psymtab.c b/gdb/psymtab.c index eac3e1a..95f102b 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -32,6 +32,7 @@ #include "command.h" #include "readline/readline.h" #include "gdb_regex.h" +#include "dictionary.h" #ifndef DEV_TTY #define DEV_TTY "/dev/tty" @@ -46,7 +47,15 @@ struct psymbol_bcache #define PSYMTAB_TO_SYMTAB(pst) \ ((pst) -> symtab != NULL ? (pst) -> symtab : psymtab_to_symtab (pst)) -/* Lookup a partial symbol. */ +static struct partial_symbol *match_partial_symbol (struct partial_symtab *, + int, + const char *, domain_enum, + int (*) (const char *, + const char *), + int (*) (const char *, + const char *)); + + static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *, const char *, int, domain_enum); @@ -426,6 +435,85 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile, return NULL; } +/* Look in PST for a symbol in DOMAIN whose name matches NAME. Search + the global block of PST if GLOBAL, and otherwise the static block. + MATCH is the comparison operation that returns true iff MATCH (s, + NAME), where s is a SYMBOL_SEARCH_NAME. If ORDERED_COMPARE is + non-null, the symbols in the block are assumed to be ordered + according to it (allowing binary search). It must be compatible + with MATCH. Returns the symbol, if found, and otherwise NULL. */ + +static struct partial_symbol * +match_partial_symbol (struct partial_symtab *pst, int global, + const char *name, domain_enum domain, + int (*match) (const char *, const char *), + int (*ordered_compare) (const char *, const char *)) +{ + struct partial_symbol **start, **psym; + struct partial_symbol **top, **real_top, **bottom, **center; + int length = (global ? pst->n_global_syms : pst->n_static_syms); + int do_linear_search = 1; + + if (length == 0) + return NULL; + start = (global ? + pst->objfile->global_psymbols.list + pst->globals_offset : + pst->objfile->static_psymbols.list + pst->statics_offset); + + if (global && ordered_compare) /* Can use a binary search. */ + { + do_linear_search = 0; + + /* Binary search. This search is guaranteed to end with center + pointing at the earliest partial symbol whose name might be + correct. At that point *all* partial symbols with an + appropriate name will be checked against the correct + domain. */ + + bottom = start; + top = start + length - 1; + real_top = top; + while (top > bottom) + { + center = bottom + (top - bottom) / 2; + gdb_assert (center < top); + if (!do_linear_search + && (SYMBOL_LANGUAGE (*center) == language_java)) + do_linear_search = 1; + if (ordered_compare (SYMBOL_SEARCH_NAME (*center), name) >= 0) + top = center; + else + bottom = center + 1; + } + gdb_assert (top == bottom); + + while (top <= real_top + && match (SYMBOL_SEARCH_NAME (*top), name) == 0) + { + if (symbol_matches_domain (SYMBOL_LANGUAGE (*top), + SYMBOL_DOMAIN (*top), domain)) + return *top; + top++; + } + } + + /* Can't use a binary search or else we found during the binary search that + we should also do a linear search. */ + + if (do_linear_search) + { + for (psym = start; psym < start + length; psym++) + { + if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym), + SYMBOL_DOMAIN (*psym), domain) + && match (SYMBOL_SEARCH_NAME (*psym), name) == 0) + return *psym; + } + } + + return NULL; +} + static void pre_expand_symtabs_matching_psymtabs (struct objfile *objfile, int kind, const char *name, @@ -435,7 +523,7 @@ pre_expand_symtabs_matching_psymtabs (struct objfile *objfile, } /* Look, in partial_symtab PST, for symbol whose natural name is NAME. - Check the global symbols if GLOBAL, the static symbols if not. */ + Check the global symbols if GLOBAL, the static symbols if not. */ static struct partial_symbol * lookup_partial_symbol (struct partial_symtab *pst, const char *name, @@ -473,7 +561,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, if (!(center < top)) internal_error (__FILE__, __LINE__, _("failed internal consistency check")); if (!do_linear_search - && (SYMBOL_LANGUAGE (*center) == language_java)) + && SYMBOL_LANGUAGE (*center) == language_java) { do_linear_search = 1; } @@ -500,7 +588,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, } /* Can't use a binary search or else we found during the binary search that - we should also do a linear search. */ + we should also do a linear search. */ if (do_linear_search) { @@ -967,174 +1055,72 @@ find_symbol_file_from_partial (struct objfile *objfile, const char *name) return NULL; } -/* Look, in partial_symtab PST, for symbol NAME in given namespace. - Check the global symbols if GLOBAL, the static symbols if not. - Do wild-card match if WILD. */ +/* For all symbols, s, in BLOCK that are in NAMESPACE and match NAME + according to the function MATCH, call CALLBACK(BLOCK, s, DATA). + BLOCK is assumed to come from OBJFILE. Returns 1 iff CALLBACK + ever returns non-zero, and otherwise returns 0. */ -static struct partial_symbol * -ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name, - int global, domain_enum namespace, int wild, - int (*wild_match) (const char *, const char *), - int (*is_name_suffix) (const char *)) +static int +map_block (const char *name, domain_enum namespace, struct objfile *objfile, + struct block *block, + int (*callback) (struct block *, struct symbol *, void *), + void *data, + int (*match) (const char *, const char *)) { - struct partial_symbol **start; - int name_len = strlen (name); - int length = (global ? pst->n_global_syms : pst->n_static_syms); - int i; + struct dict_iterator iter; + struct symbol *sym; - if (length == 0) + for (sym = dict_iter_match_first (BLOCK_DICT (block), name, match, &iter); + sym != NULL; sym = dict_iter_match_next (name, match, &iter)) { - return (NULL); + if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), + SYMBOL_DOMAIN (sym), namespace)) + { + if (callback (block, sym, data)) + return 1; + } } - start = (global ? - pst->objfile->global_psymbols.list + pst->globals_offset : - pst->objfile->static_psymbols.list + pst->statics_offset); - - if (wild) - { - for (i = 0; i < length; i += 1) - { - struct partial_symbol *psym = start[i]; - - if (symbol_matches_domain (SYMBOL_LANGUAGE (psym), - SYMBOL_DOMAIN (psym), namespace) - && (*wild_match) (SYMBOL_LINKAGE_NAME (psym), name) == 0) - return psym; - } - return NULL; - } - else - { - if (global) - { - int U; - - i = 0; - U = length - 1; - while (U - i > 4) - { - int M = (U + i) >> 1; - struct partial_symbol *psym = start[M]; - - if (SYMBOL_LINKAGE_NAME (psym)[0] < name[0]) - i = M + 1; - else if (SYMBOL_LINKAGE_NAME (psym)[0] > name[0]) - U = M - 1; - else if (strcmp (SYMBOL_LINKAGE_NAME (psym), name) < 0) - i = M + 1; - else - U = M; - } - } - else - i = 0; - - while (i < length) - { - struct partial_symbol *psym = start[i]; - - if (symbol_matches_domain (SYMBOL_LANGUAGE (psym), - SYMBOL_DOMAIN (psym), namespace)) - { - int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym), name_len); - - if (cmp < 0) - { - if (global) - break; - } - else if (cmp == 0 - && (*is_name_suffix) (SYMBOL_LINKAGE_NAME (psym) - + name_len)) - return psym; - } - i += 1; - } - - if (global) - { - int U; - - i = 0; - U = length - 1; - while (U - i > 4) - { - int M = (U + i) >> 1; - struct partial_symbol *psym = start[M]; - - if (SYMBOL_LINKAGE_NAME (psym)[0] < '_') - i = M + 1; - else if (SYMBOL_LINKAGE_NAME (psym)[0] > '_') - U = M - 1; - else if (strcmp (SYMBOL_LINKAGE_NAME (psym), "_ada_") < 0) - i = M + 1; - else - U = M; - } - } - else - i = 0; - - while (i < length) - { - struct partial_symbol *psym = start[i]; - - if (symbol_matches_domain (SYMBOL_LANGUAGE (psym), - SYMBOL_DOMAIN (psym), namespace)) - { - int cmp; - - cmp = (int) '_' - (int) SYMBOL_LINKAGE_NAME (psym)[0]; - if (cmp == 0) - { - cmp = strncmp ("_ada_", SYMBOL_LINKAGE_NAME (psym), 5); - if (cmp == 0) - cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym) + 5, - name_len); - } - - if (cmp < 0) - { - if (global) - break; - } - else if (cmp == 0 - && (*is_name_suffix) (SYMBOL_LINKAGE_NAME (psym) - + name_len + 5)) - return psym; - } - i += 1; - } - } - return NULL; + return 0; } +/* Psymtab version of map_matching_symbols. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + static void -map_ada_symtabs (struct objfile *objfile, - int (*wild_match) (const char *, const char *), - int (*is_name_suffix) (const char *), - void (*callback) (struct objfile *, struct symtab *, void *), - const char *name, int global, domain_enum namespace, int wild, - void *data) +map_matching_symbols_psymtab (const char *name, domain_enum namespace, + struct objfile *objfile, int global, + int (*callback) (struct block *, + struct symbol *, void *), + void *data, + int (*match) (const char *, const char *), + int (*ordered_compare) (const char *, + const char *)) { + const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK; struct partial_symtab *ps; ALL_OBJFILE_PSYMTABS (objfile, ps) { QUIT; if (ps->readin - || ada_lookup_partial_symbol (ps, name, global, namespace, wild, - wild_match, is_name_suffix)) + || match_partial_symbol (ps, global, name, namespace, match, + ordered_compare)) { struct symtab *s = PSYMTAB_TO_SYMTAB (ps); + struct block *block; if (s == NULL || !s->primary) continue; - (*callback) (objfile, s, data); + block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), block_kind); + if (map_block (name, namespace, objfile, block, + callback, data, match)) + return; + if (callback (block, NULL, data)) + return; } } -} +} static void expand_symtabs_matching_via_partial (struct objfile *objfile, @@ -1220,7 +1206,7 @@ const struct quick_symbol_functions psym_functions = expand_partial_symbol_tables, read_psymtabs_with_filename, find_symbol_file_from_partial, - map_ada_symtabs, + map_matching_symbols_psymtab, expand_symtabs_matching_via_partial, find_pc_sect_symtab_from_partial, map_symbol_names_psymtab, diff --git a/gdb/symfile.h b/gdb/symfile.h index f9b4e01..c9f4e65 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -212,21 +212,31 @@ struct quick_symbol_functions named NAME. If no such symbol exists in OBJFILE, return NULL. */ const char *(*find_symbol_file) (struct objfile *objfile, const char *name); - /* This method is specific to Ada. It walks the partial symbol - tables of OBJFILE looking for a name match. WILD_MATCH and - IS_NAME_SUFFIX are predicate functions that the implementation - may call to check for a match. - - This function is completely ad hoc and new implementations should - refer to the psymtab implementation to see what to do. */ - void (*map_ada_symtabs) (struct objfile *objfile, - int (*wild_match) (const char *, const char *), - int (*is_name_suffix) (const char *), - void (*callback) (struct objfile *, - struct symtab *, void *), - const char *name, int global, - domain_enum namespace, int wild, - void *data); + /* Find global or static symbols in all tables that are in NAMESPACE + and for which MATCH (symbol name, NAME) == 0, passing each to + CALLBACK, reading in partial symbol symbol tables as needed. Look + through global symbols if GLOBAL and otherwise static symbols. + Passes NAME, NAMESPACE, and DATA to CALLBACK with each symbol + found. After each block is processed, passes NULL to CALLBACK. + MATCH must be weaker than strcmp_iw in the sense that + strcmp_iw(x,y) == 0 --> MATCH(x,y) == 0. ORDERED_COMPARE, if + non-null, must be an ordering relation compatible with strcmp_iw + in the sense that + strcmp(x,y) == 0 --> ORDERED_COMPARE(x,y) == 0 + and + strcmp(x,y) <= 0 --> ORDERED_COMPARE(x,y) <= 0 + (allowing strcmp(x,y) < 0 while ORDERED_COMPARE(x, y) == 0). + CALLBACK returns 0 to indicate that the scan should continue, or + non-zero to indicate that the scan should be terminated. */ + + void (*map_matching_symbols) (const char *name, domain_enum namespace, + struct objfile *, int global, + int (*callback) (struct block *, + struct symbol *, void *), + void *data, + int (*match) (const char *, const char *), + int (*ordered_compare) (const char *, + const char *)); /* Expand all symbol tables in OBJFILE matching some criteria. -- 1.7.0.4 -- Paul N. Hilfinger (Hilfinger@adacore.com) ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFA] Rework symbol searches to move Ada-specific stuff to ada-lang.c. 2010-10-05 8:42 [RFA] Rework symbol searches to move Ada-specific stuff to ada-lang.c Paul Hilfinger 2010-10-06 22:52 ` Tom Tromey @ 2010-10-06 23:15 ` Joel Brobecker 2010-10-06 23:49 ` Doug Evans 2010-10-07 4:18 ` Paul Hilfinger 1 sibling, 2 replies; 8+ messages in thread From: Joel Brobecker @ 2010-10-06 23:15 UTC (permalink / raw) To: Paul Hilfinger; +Cc: gdb-patches FWIW, Paul actually knows a lot more about the ada-* code since he wrote most of it. So I do not feel that it needs to be approved by me before he can commit Ada-related changes. But a second pair of eyes never hurts, so... > (ada_match_name): Rename to match_name (we should avoid prefixing static > symbols with "ada_"). I don't oppose this change, but I really don't understand why that's something we should avoid. If it's something Ada-specific, why not saying so in the function name? > +/* A callback for add_matching_symbols that adds SYM, found in BLOCK, > + to a list of symbols. DATA0 is a pointer to a struct match_data * > + containing the obstack that collects the symbol list, the file that SYM > + must come from, a flag indicating whether a non-argument symbol has > + been found in the current block, and the last argument symbol > + passed in SYM within the current block (if any). When SYM is null, > + marking the end of a block, the argument symbol is added if no > + other has been found. */ > +static int > +aux_add_nonlocal_symbols (struct block *block, struct symbol *sym, void *data0) A formatting nit: Doug would like us to add an empty line after the comment that documents a function... > +/* Compare STRING1 to STRING2, with results as for strcmp. > + Compatible with strcmp_iw in that strcmp_iw (STRING1, STRING2) <= 0 > + implies compare_names (STRING1, STRING2) (they may differ as to > + what symbols compare equal). */ > +static int > +compare_names (const char *string1, const char *string2) Same here. > +/* Returns 0 iff symbol name SYM_NAME matches SEARCH_NAME, apart from > + informational suffix. */ > static int > full_match (const char* sym_name, const char* search_name) Same here. -- Joel ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFA] Rework symbol searches to move Ada-specific stuff to ada-lang.c. 2010-10-06 23:15 ` [RFA] " Joel Brobecker @ 2010-10-06 23:49 ` Doug Evans 2010-10-07 4:18 ` Paul Hilfinger 1 sibling, 0 replies; 8+ messages in thread From: Doug Evans @ 2010-10-06 23:49 UTC (permalink / raw) To: Joel Brobecker; +Cc: Paul Hilfinger, gdb-patches On Wed, Oct 6, 2010 at 4:15 PM, Joel Brobecker <brobecker@adacore.com> wrote: > A formatting nit: Doug would like us to add an empty line after the > comment that documents a function... Nit: I'd word this differently. It's true that I prefer this style, but it's also a documented style rule. [But THANKS for making the effort to help enforce a style rule I like. :-)] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFA] Rework symbol searches to move Ada-specific stuff to ada-lang.c. 2010-10-06 23:15 ` [RFA] " Joel Brobecker 2010-10-06 23:49 ` Doug Evans @ 2010-10-07 4:18 ` Paul Hilfinger 1 sibling, 0 replies; 8+ messages in thread From: Paul Hilfinger @ 2010-10-07 4:18 UTC (permalink / raw) To: Joel Brobecker; +Cc: Paul Hilfinger, gdb-patches On Wed, 2010-10-06 at 16:15 -0700, Joel Brobecker wrote: > > (ada_match_name): Rename to match_name (we should avoid prefixing static > > symbols with "ada_"). > > I don't oppose this change, but I really don't understand why that's > something we should avoid. If it's something Ada-specific, why not > saying so in the function name? > I'm trying to be consistent. For most other static (file scope) definitions, we have avoided to unnecessary prefix. In a better language (:->), we'd be writing ada.foo to access exported symbols from outside the Ada module, and just foo to access symbols defined in the module. > > +/* A callback for add_matching_symbols that adds SYM, found in BLOCK, > > + to a list of symbols. DATA0 is a pointer to a struct match_data * > > + containing the obstack that collects the symbol list, the file that SYM > > + must come from, a flag indicating whether a non-argument symbol has > > + been found in the current block, and the last argument symbol > > + passed in SYM within the current block (if any). When SYM is null, > > + marking the end of a block, the argument symbol is added if no > > + other has been found. */ > > +static int > > +aux_add_nonlocal_symbols (struct block *block, struct symbol *sym, void *data0) > > A formatting nit: Doug would like us to add an empty line after the > comment that documents a function... So I hear. > > +/* Compare STRING1 to STRING2, with results as for strcmp. > > + Compatible with strcmp_iw in that strcmp_iw (STRING1, STRING2) <= 0 > > + implies compare_names (STRING1, STRING2) (they may differ as to > > + what symbols compare equal). */ > > +static int > > +compare_names (const char *string1, const char *string2) > > Same here. > > > +/* Returns 0 iff symbol name SYM_NAME matches SEARCH_NAME, apart from > > + informational suffix. */ > > static int > > full_match (const char* sym_name, const char* search_name) > > Same here. > Thanks for your comments. Paul ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-10-07 17:53 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-10-05 8:42 [RFA] Rework symbol searches to move Ada-specific stuff to ada-lang.c Paul Hilfinger 2010-10-06 22:52 ` Tom Tromey 2010-10-07 4:14 ` Paul Hilfinger 2010-10-07 17:53 ` Tom Tromey 2010-10-07 7:19 ` [commit] " Paul Hilfinger 2010-10-06 23:15 ` [RFA] " Joel Brobecker 2010-10-06 23:49 ` Doug Evans 2010-10-07 4:18 ` Paul Hilfinger
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox