mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 06:45:56 +08:00
Rework symbol searches to move Ada-specific stuff to ada-lang.c.
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.
This commit is contained in:
@ -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>
|
||||
|
||||
|
158
gdb/ada-lang.c
158
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;
|
||||
}
|
||||
|
||||
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 +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),
|
||||
|
@ -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)
|
||||
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 *))
|
||||
{
|
||||
/* For now, we don't support Ada. Still the function can be called if the
|
||||
/* 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,
|
||||
|
286
gdb/psymtab.c
286
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,
|
||||
|
@ -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.
|
||||
/* 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. */
|
||||
|
||||
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);
|
||||
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.
|
||||
|
||||
|
Reference in New Issue
Block a user