* symtab.c (do_free_search_symbols_cleanup): Change arg to,
effectively, struct symbol_search **. (make_cleanup_free_search_symbols): Change arg to struct symbol_search **. All callers updated. (compare_search_syms): Compare symtab file name and block as well. (search_symbols_equal): New function. (sort_search_symbols_remove_dups): Renamed from sort_search_symbols. New args new_head, new_tail. Result is now void. Remove dups after sorting the symbols. (search_symbols): Sort all found symbols once, after all have been found, and remove duplicates. Simplify cleanup tracking of result. * symtab.h (make_cleanup_free_search_symbols): Update prototype.
This commit is contained in:
parent
ec94af8326
commit
b52109bc0c
|
@ -1,5 +1,18 @@
|
|||
2013-08-01 Doug Evans <dje@google.com>
|
||||
|
||||
* symtab.c (do_free_search_symbols_cleanup): Change arg to,
|
||||
effectively, struct symbol_search **.
|
||||
(make_cleanup_free_search_symbols): Change arg to struct
|
||||
symbol_search **. All callers updated.
|
||||
(compare_search_syms): Compare symtab file name and block as well.
|
||||
(search_symbols_equal): New function.
|
||||
(sort_search_symbols_remove_dups): Renamed from sort_search_symbols.
|
||||
New args new_head, new_tail. Result is now void. Remove dups after
|
||||
sorting the symbols.
|
||||
(search_symbols): Sort all found symbols once, after all have been
|
||||
found, and remove duplicates. Simplify cleanup tracking of result.
|
||||
* symtab.h (make_cleanup_free_search_symbols): Update prototype.
|
||||
|
||||
Further workarounds for binutils/15021.
|
||||
* dwarf2read.c (recursively_compute_inclusions): Change type of result
|
||||
parameter to VEC (symtab_ptr) **. New parameter all_type_symtabs.
|
||||
|
|
144
gdb/symtab.c
144
gdb/symtab.c
|
@ -3307,64 +3307,102 @@ free_search_symbols (struct symbol_search *symbols)
|
|||
}
|
||||
|
||||
static void
|
||||
do_free_search_symbols_cleanup (void *symbols)
|
||||
do_free_search_symbols_cleanup (void *symbolsp)
|
||||
{
|
||||
struct symbol_search *symbols = *(struct symbol_search **) symbolsp;
|
||||
|
||||
free_search_symbols (symbols);
|
||||
}
|
||||
|
||||
struct cleanup *
|
||||
make_cleanup_free_search_symbols (struct symbol_search *symbols)
|
||||
make_cleanup_free_search_symbols (struct symbol_search **symbolsp)
|
||||
{
|
||||
return make_cleanup (do_free_search_symbols_cleanup, symbols);
|
||||
return make_cleanup (do_free_search_symbols_cleanup, symbolsp);
|
||||
}
|
||||
|
||||
/* Helper function for sort_search_symbols and qsort. Can only
|
||||
/* Helper function for sort_search_symbols_remove_dups and qsort. Can only
|
||||
sort symbols, not minimal symbols. */
|
||||
|
||||
static int
|
||||
compare_search_syms (const void *sa, const void *sb)
|
||||
{
|
||||
struct symbol_search **sym_a = (struct symbol_search **) sa;
|
||||
struct symbol_search **sym_b = (struct symbol_search **) sb;
|
||||
struct symbol_search *sym_a = *(struct symbol_search **) sa;
|
||||
struct symbol_search *sym_b = *(struct symbol_search **) sb;
|
||||
int c;
|
||||
|
||||
return strcmp (SYMBOL_PRINT_NAME ((*sym_a)->symbol),
|
||||
SYMBOL_PRINT_NAME ((*sym_b)->symbol));
|
||||
c = strcmp (sym_a->symtab->filename, sym_b->symtab->filename);
|
||||
if (c != 0)
|
||||
return c;
|
||||
|
||||
if (sym_a->block != sym_b->block)
|
||||
return sym_a->block - sym_b->block;
|
||||
|
||||
return strcmp (SYMBOL_PRINT_NAME (sym_a->symbol),
|
||||
SYMBOL_PRINT_NAME (sym_b->symbol));
|
||||
}
|
||||
|
||||
/* Sort the ``nfound'' symbols in the list after prevtail. Leave
|
||||
prevtail where it is, but update its next pointer to point to
|
||||
the first of the sorted symbols. */
|
||||
/* Helper function for sort_search_symbols_remove_dups.
|
||||
Return TRUE if symbols A, B are equal. */
|
||||
|
||||
static struct symbol_search *
|
||||
sort_search_symbols (struct symbol_search *prevtail, int nfound)
|
||||
static int
|
||||
search_symbols_equal (const struct symbol_search *a,
|
||||
const struct symbol_search *b)
|
||||
{
|
||||
return (strcmp (a->symtab->filename, b->symtab->filename) == 0
|
||||
&& a->block == b->block
|
||||
&& strcmp (SYMBOL_PRINT_NAME (a->symbol),
|
||||
SYMBOL_PRINT_NAME (b->symbol)) == 0);
|
||||
}
|
||||
|
||||
/* Sort the NFOUND symbols in list FOUND and remove duplicates.
|
||||
The duplicates are freed, and the new list is returned in
|
||||
*NEW_HEAD, *NEW_TAIL. */
|
||||
|
||||
static void
|
||||
sort_search_symbols_remove_dups (struct symbol_search *found, int nfound,
|
||||
struct symbol_search **new_head,
|
||||
struct symbol_search **new_tail)
|
||||
{
|
||||
struct symbol_search **symbols, *symp, *old_next;
|
||||
int i;
|
||||
int i, j, nunique;
|
||||
|
||||
gdb_assert (found != NULL && nfound > 0);
|
||||
|
||||
/* Build an array out of the list so we can easily sort them. */
|
||||
symbols = (struct symbol_search **) xmalloc (sizeof (struct symbol_search *)
|
||||
* nfound);
|
||||
symp = prevtail->next;
|
||||
symp = found;
|
||||
for (i = 0; i < nfound; i++)
|
||||
{
|
||||
gdb_assert (symp != NULL);
|
||||
gdb_assert (symp->block >= 0 && symp->block <= 1);
|
||||
symbols[i] = symp;
|
||||
symp = symp->next;
|
||||
}
|
||||
/* Generally NULL. */
|
||||
old_next = symp;
|
||||
gdb_assert (symp == NULL);
|
||||
|
||||
qsort (symbols, nfound, sizeof (struct symbol_search *),
|
||||
compare_search_syms);
|
||||
|
||||
symp = prevtail;
|
||||
for (i = 0; i < nfound; i++)
|
||||
/* Collapse out the dups. */
|
||||
for (i = 1, j = 1; i < nfound; ++i)
|
||||
{
|
||||
symp->next = symbols[i];
|
||||
symp = symp->next;
|
||||
if (! search_symbols_equal (symbols[j - 1], symbols[i]))
|
||||
symbols[j++] = symbols[i];
|
||||
else
|
||||
xfree (symbols[i]);
|
||||
}
|
||||
symp->next = old_next;
|
||||
nunique = j;
|
||||
symbols[j - 1]->next = NULL;
|
||||
|
||||
/* Rebuild the linked list. */
|
||||
for (i = 0; i < nunique - 1; i++)
|
||||
symbols[i]->next = symbols[i + 1];
|
||||
symbols[nunique - 1]->next = NULL;
|
||||
|
||||
*new_head = symbols[0];
|
||||
*new_tail = symbols[nunique - 1];
|
||||
xfree (symbols);
|
||||
return symp;
|
||||
}
|
||||
|
||||
/* An object of this type is passed as the user_data to the
|
||||
|
@ -3412,8 +3450,9 @@ search_symbols_name_matches (const char *symname, void *user_data)
|
|||
|
||||
free_search_symbols should be called when *MATCHES is no longer needed.
|
||||
|
||||
The results are sorted locally; each symtab's global and static blocks are
|
||||
separately alphabetized. */
|
||||
Within each file the results are sorted locally; each symtab's global and
|
||||
static blocks are separately alphabetized.
|
||||
Duplicate entries are removed. */
|
||||
|
||||
void
|
||||
search_symbols (char *regexp, enum search_domain kind,
|
||||
|
@ -3441,10 +3480,10 @@ search_symbols (char *regexp, enum search_domain kind,
|
|||
enum minimal_symbol_type ourtype2;
|
||||
enum minimal_symbol_type ourtype3;
|
||||
enum minimal_symbol_type ourtype4;
|
||||
struct symbol_search *sr;
|
||||
struct symbol_search *psr;
|
||||
struct symbol_search *found;
|
||||
struct symbol_search *tail;
|
||||
struct search_symbols_data datum;
|
||||
int nfound;
|
||||
|
||||
/* OLD_CHAIN .. RETVAL_CHAIN is always freed, RETVAL_CHAIN .. current
|
||||
CLEANUP_CHAIN is freed only in the case of an error. */
|
||||
|
@ -3458,8 +3497,7 @@ search_symbols (char *regexp, enum search_domain kind,
|
|||
ourtype3 = types3[kind];
|
||||
ourtype4 = types4[kind];
|
||||
|
||||
sr = *matches = NULL;
|
||||
tail = NULL;
|
||||
*matches = NULL;
|
||||
datum.preg_p = 0;
|
||||
|
||||
if (regexp != NULL)
|
||||
|
@ -3531,8 +3569,6 @@ search_symbols (char *regexp, enum search_domain kind,
|
|||
&datum);
|
||||
}
|
||||
|
||||
retval_chain = make_cleanup (null_cleanup, NULL);
|
||||
|
||||
/* Here, we search through the minimal symbol tables for functions
|
||||
and variables that match, and force their symbols to be read.
|
||||
This is in particular necessary for demangled variable names,
|
||||
|
@ -3581,14 +3617,16 @@ search_symbols (char *regexp, enum search_domain kind,
|
|||
}
|
||||
}
|
||||
|
||||
found = NULL;
|
||||
tail = NULL;
|
||||
nfound = 0;
|
||||
retval_chain = make_cleanup_free_search_symbols (&found);
|
||||
|
||||
ALL_PRIMARY_SYMTABS (objfile, s)
|
||||
{
|
||||
bv = BLOCKVECTOR (s);
|
||||
for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
|
||||
{
|
||||
struct symbol_search *prevtail = tail;
|
||||
int nfound = 0;
|
||||
|
||||
b = BLOCKVECTOR_BLOCK (bv, i);
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
{
|
||||
|
@ -3623,7 +3661,7 @@ search_symbols (char *regexp, enum search_domain kind,
|
|||
&& SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
|
||||
{
|
||||
/* match */
|
||||
psr = (struct symbol_search *)
|
||||
struct symbol_search *psr = (struct symbol_search *)
|
||||
xmalloc (sizeof (struct symbol_search));
|
||||
psr->block = i;
|
||||
psr->symtab = real_symtab;
|
||||
|
@ -3631,31 +3669,22 @@ search_symbols (char *regexp, enum search_domain kind,
|
|||
psr->msymbol = NULL;
|
||||
psr->next = NULL;
|
||||
if (tail == NULL)
|
||||
sr = psr;
|
||||
found = psr;
|
||||
else
|
||||
tail->next = psr;
|
||||
tail = psr;
|
||||
nfound ++;
|
||||
}
|
||||
}
|
||||
if (nfound > 0)
|
||||
{
|
||||
if (prevtail == NULL)
|
||||
{
|
||||
struct symbol_search dummy;
|
||||
|
||||
dummy.next = sr;
|
||||
tail = sort_search_symbols (&dummy, nfound);
|
||||
sr = dummy.next;
|
||||
|
||||
make_cleanup_free_search_symbols (sr);
|
||||
}
|
||||
else
|
||||
tail = sort_search_symbols (prevtail, nfound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found != NULL)
|
||||
{
|
||||
sort_search_symbols_remove_dups (found, nfound, &found, &tail);
|
||||
/* Note: nfound is no longer useful beyond this point. */
|
||||
}
|
||||
|
||||
/* If there are no eyes, avoid all contact. I mean, if there are
|
||||
no debug symbols, then print directly from the msymbol_vector. */
|
||||
|
||||
|
@ -3687,7 +3716,7 @@ search_symbols (char *regexp, enum search_domain kind,
|
|||
== NULL)
|
||||
{
|
||||
/* match */
|
||||
psr = (struct symbol_search *)
|
||||
struct symbol_search *psr = (struct symbol_search *)
|
||||
xmalloc (sizeof (struct symbol_search));
|
||||
psr->block = i;
|
||||
psr->msymbol = msymbol;
|
||||
|
@ -3695,10 +3724,7 @@ search_symbols (char *regexp, enum search_domain kind,
|
|||
psr->symbol = NULL;
|
||||
psr->next = NULL;
|
||||
if (tail == NULL)
|
||||
{
|
||||
sr = psr;
|
||||
make_cleanup_free_search_symbols (sr);
|
||||
}
|
||||
found = psr;
|
||||
else
|
||||
tail->next = psr;
|
||||
tail = psr;
|
||||
|
@ -3711,7 +3737,7 @@ search_symbols (char *regexp, enum search_domain kind,
|
|||
|
||||
discard_cleanups (retval_chain);
|
||||
do_cleanups (old_chain);
|
||||
*matches = sr;
|
||||
*matches = found;
|
||||
}
|
||||
|
||||
/* Helper function for symtab_symbol_info, this function uses
|
||||
|
@ -3793,7 +3819,7 @@ symtab_symbol_info (char *regexp, enum search_domain kind, int from_tty)
|
|||
|
||||
/* Must make sure that if we're interrupted, symbols gets freed. */
|
||||
search_symbols (regexp, kind, 0, (char **) NULL, &symbols);
|
||||
old_chain = make_cleanup_free_search_symbols (symbols);
|
||||
old_chain = make_cleanup_free_search_symbols (&symbols);
|
||||
|
||||
if (regexp != NULL)
|
||||
printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
|
||||
|
@ -3895,7 +3921,7 @@ rbreak_command (char *regexp, int from_tty)
|
|||
}
|
||||
|
||||
search_symbols (regexp, FUNCTIONS_DOMAIN, nfiles, files, &ss);
|
||||
old_chain = make_cleanup_free_search_symbols (ss);
|
||||
old_chain = make_cleanup_free_search_symbols (&ss);
|
||||
make_cleanup (free_current_contents, &string);
|
||||
|
||||
start_rbreak_breakpoints ();
|
||||
|
|
|
@ -1292,7 +1292,7 @@ struct symbol_search
|
|||
|
||||
/* Information describing what was found.
|
||||
|
||||
If symtab abd symbol are NOT NULL, then information was found
|
||||
If symtab and symbol are NOT NULL, then information was found
|
||||
for this match. */
|
||||
struct symtab *symtab;
|
||||
struct symbol *symbol;
|
||||
|
@ -1309,7 +1309,7 @@ extern void search_symbols (char *, enum search_domain, int, char **,
|
|||
struct symbol_search **);
|
||||
extern void free_search_symbols (struct symbol_search *);
|
||||
extern struct cleanup *make_cleanup_free_search_symbols (struct symbol_search
|
||||
*);
|
||||
**);
|
||||
|
||||
/* The name of the ``main'' function.
|
||||
FIXME: cagney/2001-03-20: Can't make main_name() const since some
|
||||
|
|
Loading…
Reference in New Issue