2002-07-11 Daniel Jacobowitz <drow@mvista.com>
Based on patch from Daniel Berlin <dberlin@dberlin.org>. * buildsym.c: Include "demangle.h" for SYMBOL_INIT_DEMANGLED_NAME. (finish_block) For non-function blocks, hash the symbol table. For function blocks, mark the symbol table as unhashed. * minsyms.c (msymbol_hash): Return hash value without taking modulus. (msymbol_hash_iw): Likewise. (add_minsym_to_hash_table): Take modulus of msymbol_hash's return value. (add_minsym_to_demangled_hash_table): Likewise for msymbol_hash_iw. (lookup_minimal_symbol): Likewise for both. * symtab.h (struct block): Add `hashtable' flag. Comment the hashtable. (BLOCK_HASHTABLE, BLOCK_BUCKETS, BLOCK_BUCKET): New macro. (ALL_BLOCK_SYMBOLS): Update. (BLOCK_SHOULD_SORT): Do not sort hashed blocks. (struct symbol): Add `hash_next' pointer. * symtab.c (lookup_block_symbol): Search using the hash table when possible. (find_pc_sect_symtab): Use ALL_BLOCK_SYMBOLS. (search_symbols, find_addr_symbol): Likewise. * dstread.c (process_dst_block): Clear hashtable bit for new block. (read_dst_symtab): Likewise. * jv-lang.c (get_java_class_symtab): Likewise. * mdebugread.c: Include "gdb_assert.h". (shrink_block): Assert that the block being modified is not hashed. * coffread.c (patch_opaque_types): Use ALL_BLOCK_SYMBOLS. * symmisc.c (free_symtab_block): Walk the hash table when freeing symbols. (dump_symtab): Recognize hashed blocks. * printcmd.c (print_frame_args): Assert that function blocks do not have hashed symbol tables. * ada-lang.c (symtab_for_sym): Use ALL_BLOCK_SYMBOLS. (fill_in_ada_prototype, debug_print_block): Likewise. (ada_add_block_symbols): Use ALL_BLOCK_SYMBOLS. Handle hash tables.
This commit is contained in:
parent
7c1f909cd5
commit
261397f84f
12 changed files with 291 additions and 143 deletions
|
@ -1,3 +1,41 @@
|
|||
2002-07-11 Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
Based on patch from Daniel Berlin <dberlin@dberlin.org>.
|
||||
* buildsym.c: Include "demangle.h" for SYMBOL_INIT_DEMANGLED_NAME.
|
||||
(finish_block) For non-function blocks, hash the symbol table. For
|
||||
function blocks, mark the symbol table as unhashed.
|
||||
* minsyms.c (msymbol_hash): Return hash value without taking modulus.
|
||||
(msymbol_hash_iw): Likewise.
|
||||
(add_minsym_to_hash_table): Take modulus of msymbol_hash's return
|
||||
value.
|
||||
(add_minsym_to_demangled_hash_table): Likewise for msymbol_hash_iw.
|
||||
(lookup_minimal_symbol): Likewise for both.
|
||||
* symtab.h (struct block): Add `hashtable' flag. Comment the
|
||||
hashtable.
|
||||
(BLOCK_HASHTABLE, BLOCK_BUCKETS, BLOCK_BUCKET): New macro.
|
||||
(ALL_BLOCK_SYMBOLS): Update.
|
||||
(BLOCK_SHOULD_SORT): Do not sort hashed blocks.
|
||||
(struct symbol): Add `hash_next' pointer.
|
||||
* symtab.c (lookup_block_symbol): Search using the hash table when
|
||||
possible.
|
||||
(find_pc_sect_symtab): Use ALL_BLOCK_SYMBOLS.
|
||||
(search_symbols, find_addr_symbol): Likewise.
|
||||
|
||||
* dstread.c (process_dst_block): Clear hashtable bit for new block.
|
||||
(read_dst_symtab): Likewise.
|
||||
* jv-lang.c (get_java_class_symtab): Likewise.
|
||||
* mdebugread.c: Include "gdb_assert.h".
|
||||
(shrink_block): Assert that the block being modified is not hashed.
|
||||
* coffread.c (patch_opaque_types): Use ALL_BLOCK_SYMBOLS.
|
||||
* symmisc.c (free_symtab_block): Walk the hash table when freeing
|
||||
symbols.
|
||||
(dump_symtab): Recognize hashed blocks.
|
||||
* printcmd.c (print_frame_args): Assert that function blocks do not
|
||||
have hashed symbol tables.
|
||||
* ada-lang.c (symtab_for_sym): Use ALL_BLOCK_SYMBOLS.
|
||||
(fill_in_ada_prototype, debug_print_block): Likewise.
|
||||
(ada_add_block_symbols): Use ALL_BLOCK_SYMBOLS. Handle hash tables.
|
||||
|
||||
2002-07-11 Corinna Vinschen <vinschen@redhat.com>
|
||||
|
||||
* stack.c (print_frame): Use result of frame_address_in_block()
|
||||
|
|
|
@ -3560,6 +3560,7 @@ symtab_for_sym (sym)
|
|||
struct symtab* s;
|
||||
struct objfile *objfile;
|
||||
struct block *b;
|
||||
struct symbol *tmp_sym;
|
||||
int i, j;
|
||||
|
||||
ALL_SYMTABS (objfile, s)
|
||||
|
@ -3574,12 +3575,12 @@ symtab_for_sym (sym)
|
|||
case LOC_BLOCK:
|
||||
case LOC_CONST_BYTES:
|
||||
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
|
||||
for (i = 0; i < BLOCK_NSYMS (b); i += 1)
|
||||
if (sym == BLOCK_SYM (b, i))
|
||||
ALL_BLOCK_SYMBOLS (b, i, tmp_sym)
|
||||
if (sym == tmp_sym)
|
||||
return s;
|
||||
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
|
||||
for (i = 0; i < BLOCK_NSYMS (b); i += 1)
|
||||
if (sym == BLOCK_SYM (b, i))
|
||||
ALL_BLOCK_SYMBOLS (b, i, tmp_sym)
|
||||
if (sym == tmp_sym)
|
||||
return s;
|
||||
break;
|
||||
default:
|
||||
|
@ -3601,8 +3602,8 @@ symtab_for_sym (sym)
|
|||
j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1)
|
||||
{
|
||||
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), j);
|
||||
for (i = 0; i < BLOCK_NSYMS (b); i += 1)
|
||||
if (sym == BLOCK_SYM (b, i))
|
||||
ALL_BLOCK_SYMBOLS (b, i, tmp_sym)
|
||||
if (sym == tmp_sym)
|
||||
return s;
|
||||
}
|
||||
break;
|
||||
|
@ -4094,14 +4095,14 @@ ada_add_block_symbols (block, name, namespace, objfile, wild)
|
|||
/* Set true when we find a matching non-argument symbol */
|
||||
int found_sym;
|
||||
int is_sorted = BLOCK_SHOULD_SORT (block);
|
||||
struct symbol *sym;
|
||||
|
||||
arg_sym = NULL; found_sym = 0;
|
||||
if (wild)
|
||||
{
|
||||
for (i = 0; i < BLOCK_NSYMS (block); i += 1)
|
||||
struct symbol *sym;
|
||||
ALL_BLOCK_SYMBOLS (block, i, sym)
|
||||
{
|
||||
struct symbol *sym = BLOCK_SYM (block, i);
|
||||
|
||||
if (SYMBOL_NAMESPACE (sym) == namespace &&
|
||||
wild_match (name, name_len, SYMBOL_NAME (sym)))
|
||||
{
|
||||
|
@ -4149,10 +4150,9 @@ ada_add_block_symbols (block, name, namespace, objfile, wild)
|
|||
else
|
||||
i = 0;
|
||||
|
||||
for (; i < BLOCK_NSYMS (block); i += 1)
|
||||
for (; i < BLOCK_BUCKETS (block); i += 1)
|
||||
for (sym = BLOCK_BUCKET (block, i); sym != NULL; sym = sym->hash_next)
|
||||
{
|
||||
struct symbol *sym = BLOCK_SYM (block, i);
|
||||
|
||||
if (SYMBOL_NAMESPACE (sym) == namespace)
|
||||
{
|
||||
int cmp = strncmp (name, SYMBOL_NAME (sym), name_len);
|
||||
|
@ -4160,8 +4160,11 @@ ada_add_block_symbols (block, name, namespace, objfile, wild)
|
|||
if (cmp < 0)
|
||||
{
|
||||
if (is_sorted)
|
||||
{
|
||||
i = BLOCK_BUCKETS (block);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (cmp == 0
|
||||
&& is_name_suffix (SYMBOL_NAME (sym) + name_len))
|
||||
{
|
||||
|
@ -4219,7 +4222,8 @@ ada_add_block_symbols (block, name, namespace, objfile, wild)
|
|||
else
|
||||
i = 0;
|
||||
|
||||
for (; i < BLOCK_NSYMS (block); i += 1)
|
||||
for (; i < BLOCK_BUCKETS (block); i += 1)
|
||||
for (sym = BLOCK_BUCKET (block, i); sym != NULL; sym = sym->hash_next)
|
||||
{
|
||||
struct symbol *sym = BLOCK_SYM (block, i);
|
||||
|
||||
|
@ -4238,8 +4242,11 @@ ada_add_block_symbols (block, name, namespace, objfile, wild)
|
|||
if (cmp < 0)
|
||||
{
|
||||
if (is_sorted)
|
||||
{
|
||||
i = BLOCK_BUCKETS (block);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (cmp == 0
|
||||
&& is_name_suffix (SYMBOL_NAME (sym) + name_len + 5))
|
||||
{
|
||||
|
@ -4292,6 +4299,7 @@ fill_in_ada_prototype (func)
|
|||
struct type* ftype;
|
||||
struct type* rtype;
|
||||
size_t max_fields;
|
||||
struct symbol *sym;
|
||||
|
||||
if (func == NULL
|
||||
|| TYPE_CODE (SYMBOL_TYPE (func)) != TYPE_CODE_FUNC
|
||||
|
@ -4308,16 +4316,13 @@ fill_in_ada_prototype (func)
|
|||
SYMBOL_TYPE (func) = ftype;
|
||||
|
||||
b = SYMBOL_BLOCK_VALUE (func);
|
||||
nsyms = BLOCK_NSYMS (b);
|
||||
|
||||
nargs = 0;
|
||||
max_fields = 8;
|
||||
TYPE_FIELDS (ftype) =
|
||||
(struct field*) xmalloc (sizeof (struct field) * max_fields);
|
||||
for (i = 0; i < nsyms; i += 1)
|
||||
ALL_BLOCK_SYMBOLS (b, i, sym)
|
||||
{
|
||||
struct symbol *sym = BLOCK_SYM (b, i);
|
||||
|
||||
GROW_VECT (TYPE_FIELDS (ftype), max_fields, nargs+1);
|
||||
|
||||
switch (SYMBOL_CLASS (sym))
|
||||
|
@ -4903,6 +4908,8 @@ debug_print_block (b)
|
|||
struct block* b;
|
||||
{
|
||||
int i;
|
||||
struct symbol *i;
|
||||
|
||||
fprintf (stderr, "Block: %p; [0x%lx, 0x%lx]",
|
||||
b, BLOCK_START(b), BLOCK_END(b));
|
||||
if (BLOCK_FUNCTION(b) != NULL)
|
||||
|
@ -4910,11 +4917,11 @@ debug_print_block (b)
|
|||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, "\t Superblock: %p\n", BLOCK_SUPERBLOCK(b));
|
||||
fprintf (stderr, "\t Symbols:");
|
||||
for (i = 0; i < BLOCK_NSYMS (b); i += 1)
|
||||
ALL_BLOCK_SYMBOLS (b, i, sym)
|
||||
{
|
||||
if (i > 0 && i % 4 == 0)
|
||||
fprintf (stderr, "\n\t\t ");
|
||||
fprintf (stderr, " %s", SYMBOL_NAME (BLOCK_SYM (b, i)));
|
||||
fprintf (stderr, " %s", SYMBOL_NAME (sym));
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "bcache.h"
|
||||
#include "filenames.h" /* For DOSish file names */
|
||||
#include "macrotab.h"
|
||||
#include "demangle.h" /* Needed by SYMBOL_INIT_DEMANGLED_NAME. */
|
||||
/* Ask buildsym.h to define the vars it normally declares `extern'. */
|
||||
#define EXTERN
|
||||
/**/
|
||||
|
@ -243,17 +244,49 @@ finish_block (struct symbol *symbol, struct pending **listhead,
|
|||
/* EMPTY */ ;
|
||||
}
|
||||
|
||||
block = (struct block *) obstack_alloc (&objfile->symbol_obstack,
|
||||
(sizeof (struct block) + ((i - 1) * sizeof (struct symbol *))));
|
||||
|
||||
/* Copy the symbols into the block. */
|
||||
|
||||
if (symbol)
|
||||
{
|
||||
block = (struct block *)
|
||||
obstack_alloc (&objfile->symbol_obstack,
|
||||
(sizeof (struct block) +
|
||||
((i - 1) * sizeof (struct symbol *))));
|
||||
BLOCK_NSYMS (block) = i;
|
||||
for (next = *listhead; next; next = next->next)
|
||||
for (j = next->nsyms - 1; j >= 0; j--)
|
||||
{
|
||||
BLOCK_SYM (block, --i) = next->symbol[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int htab_size = BLOCK_HASHTABLE_SIZE (i);
|
||||
|
||||
block = (struct block *)
|
||||
obstack_alloc (&objfile->symbol_obstack,
|
||||
(sizeof (struct block) +
|
||||
((htab_size - 1) * sizeof (struct symbol *))));
|
||||
for (j = 0; j < htab_size; j++)
|
||||
{
|
||||
BLOCK_BUCKET (block, j) = 0;
|
||||
}
|
||||
BLOCK_BUCKETS (block) = htab_size;
|
||||
for (next = *listhead; next; next = next->next)
|
||||
{
|
||||
for (j = next->nsyms - 1; j >= 0; j--)
|
||||
{
|
||||
BLOCK_SYM (block, --i) = next->symbol[j];
|
||||
struct symbol *sym;
|
||||
unsigned int hash_index;
|
||||
const char *name = SYMBOL_DEMANGLED_NAME (next->symbol[j]);
|
||||
if (name == NULL)
|
||||
name = SYMBOL_NAME (next->symbol[j]);
|
||||
hash_index = msymbol_hash_iw (name);
|
||||
hash_index = hash_index % BLOCK_BUCKETS (block);
|
||||
sym = BLOCK_BUCKET (block, hash_index);
|
||||
BLOCK_BUCKET (block, hash_index) = next->symbol[j];
|
||||
next->symbol[j]->hash_next = sym;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,6 +304,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
|
|||
struct type *ftype = SYMBOL_TYPE (symbol);
|
||||
SYMBOL_BLOCK_VALUE (symbol) = block;
|
||||
BLOCK_FUNCTION (block) = symbol;
|
||||
BLOCK_HASHTABLE (block) = 0;
|
||||
|
||||
if (TYPE_NFIELDS (ftype) <= 0)
|
||||
{
|
||||
|
@ -352,6 +386,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
|
|||
else
|
||||
{
|
||||
BLOCK_FUNCTION (block) = NULL;
|
||||
BLOCK_HASHTABLE (block) = 1;
|
||||
}
|
||||
|
||||
/* Now "free" the links of the list, and empty the list. */
|
||||
|
|
|
@ -1409,13 +1409,12 @@ patch_opaque_types (struct symtab *s)
|
|||
|
||||
/* Go through the per-file symbols only */
|
||||
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
|
||||
for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--)
|
||||
ALL_BLOCK_SYMBOLS (b, i, real_sym)
|
||||
{
|
||||
/* Find completed typedefs to use to fix opaque ones.
|
||||
Remove syms from the chain when their types are stored,
|
||||
but search the whole chain, as there may be several syms
|
||||
from different files with the same name. */
|
||||
real_sym = BLOCK_SYM (b, i);
|
||||
if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
|
||||
SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&
|
||||
TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
|
||||
|
|
|
@ -1396,6 +1396,7 @@ process_dst_block (struct objfile *objfile, dst_rec_ptr_t entry)
|
|||
symnum++;
|
||||
}
|
||||
BLOCK_NSYMS (block) = total_symbols;
|
||||
BLOCK_HASHTABLE (block) = 0;
|
||||
BLOCK_START (block) = address;
|
||||
BLOCK_END (block) = address + size;
|
||||
BLOCK_SUPERBLOCK (block) = 0;
|
||||
|
@ -1480,6 +1481,7 @@ read_dst_symtab (struct objfile *objfile)
|
|||
(total_globals - 1) *
|
||||
sizeof (struct symbol *));
|
||||
BLOCK_NSYMS (global_block) = total_globals;
|
||||
BLOCK_HASHTABLE (global_block) = 0;
|
||||
for (symnum = 0; symnum < total_globals; symnum++)
|
||||
{
|
||||
nextsym = dst_global_symbols->next;
|
||||
|
|
|
@ -106,6 +106,7 @@ get_java_class_symtab (void)
|
|||
bl = (struct block *)
|
||||
obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
|
||||
BLOCK_NSYMS (bl) = 0;
|
||||
BLOCK_HASHTABLE (bl) = 0;
|
||||
BLOCK_START (bl) = 0;
|
||||
BLOCK_END (bl) = 0;
|
||||
BLOCK_FUNCTION (bl) = NULL;
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "stabsread.h"
|
||||
#include "complaints.h"
|
||||
#include "demangle.h"
|
||||
#include "gdb_assert.h"
|
||||
|
||||
/* These are needed if the tm.h file does not contain the necessary
|
||||
mips specific definitions. */
|
||||
|
@ -4727,6 +4728,11 @@ shrink_block (struct block *b, struct symtab *s)
|
|||
+ ((BLOCK_NSYMS (b) - 1)
|
||||
* sizeof (struct symbol *))));
|
||||
|
||||
/* FIXME: Not worth hashing this block as it's built. */
|
||||
/* All callers should have created the block with new_block (), which
|
||||
would mean it was not previously hashed. Make sure. */
|
||||
gdb_assert (BLOCK_HASHTABLE (new) == 0);
|
||||
|
||||
/* Should chase pointers to old one. Fortunately, that`s just
|
||||
the block`s function and inferior blocks */
|
||||
if (BLOCK_FUNCTION (new) && SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) == b)
|
||||
|
|
|
@ -91,7 +91,7 @@ msymbol_hash_iw (const char *string)
|
|||
++string;
|
||||
}
|
||||
}
|
||||
return hash % MINIMAL_SYMBOL_HASH_SIZE;
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* Compute a hash code for a string. */
|
||||
|
@ -102,7 +102,7 @@ msymbol_hash (const char *string)
|
|||
unsigned int hash = 0;
|
||||
for (; *string; ++string)
|
||||
hash = hash * 67 + *string - 113;
|
||||
return hash % MINIMAL_SYMBOL_HASH_SIZE;
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* Add the minimal symbol SYM to an objfile's minsym hash table, TABLE. */
|
||||
|
@ -112,7 +112,7 @@ add_minsym_to_hash_table (struct minimal_symbol *sym,
|
|||
{
|
||||
if (sym->hash_next == NULL)
|
||||
{
|
||||
unsigned int hash = msymbol_hash (SYMBOL_NAME (sym));
|
||||
unsigned int hash = msymbol_hash (SYMBOL_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
|
||||
sym->hash_next = table[hash];
|
||||
table[hash] = sym;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
|
|||
{
|
||||
if (sym->demangled_hash_next == NULL)
|
||||
{
|
||||
unsigned int hash = msymbol_hash_iw (SYMBOL_DEMANGLED_NAME (sym));
|
||||
unsigned int hash = msymbol_hash_iw (SYMBOL_DEMANGLED_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
|
||||
sym->demangled_hash_next = table[hash];
|
||||
table[hash] = sym;
|
||||
}
|
||||
|
@ -154,8 +154,8 @@ lookup_minimal_symbol (register const char *name, const char *sfile,
|
|||
struct minimal_symbol *found_file_symbol = NULL;
|
||||
struct minimal_symbol *trampoline_symbol = NULL;
|
||||
|
||||
unsigned int hash = msymbol_hash (name);
|
||||
unsigned int dem_hash = msymbol_hash_iw (name);
|
||||
unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
|
||||
unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
|
||||
|
||||
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
|
||||
if (sfile != NULL)
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "objfiles.h" /* ditto */
|
||||
#include "completer.h" /* for completion functions */
|
||||
#include "ui-out.h"
|
||||
#include "gdb_assert.h"
|
||||
|
||||
extern int asm_demangle; /* Whether to demangle syms in asm printouts */
|
||||
extern int addressprint; /* Whether to print hex addresses in HLL " */
|
||||
|
@ -1785,6 +1786,10 @@ print_frame_args (struct symbol *func, struct frame_info *fi, int num,
|
|||
if (func)
|
||||
{
|
||||
b = SYMBOL_BLOCK_VALUE (func);
|
||||
/* Function blocks are order sensitive, and thus should not be
|
||||
hashed. */
|
||||
gdb_assert (BLOCK_HASHTABLE (b) == 0);
|
||||
|
||||
ALL_BLOCK_SYMBOLS (b, i, sym)
|
||||
{
|
||||
QUIT;
|
||||
|
|
|
@ -86,11 +86,17 @@ static void
|
|||
free_symtab_block (struct objfile *objfile, struct block *b)
|
||||
{
|
||||
register int i, n;
|
||||
n = BLOCK_NSYMS (b);
|
||||
struct symbol *sym, *next_sym;
|
||||
|
||||
n = BLOCK_BUCKETS (b);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
xmfree (objfile->md, SYMBOL_NAME (BLOCK_SYM (b, i)));
|
||||
xmfree (objfile->md, (PTR) BLOCK_SYM (b, i));
|
||||
for (sym = BLOCK_BUCKET (b, i); sym; sym = next_sym)
|
||||
{
|
||||
next_sym = sym->hash_next;
|
||||
xmfree (objfile->md, SYMBOL_NAME (sym));
|
||||
xmfree (objfile->md, (PTR) sym);
|
||||
}
|
||||
}
|
||||
xmfree (objfile->md, (PTR) b);
|
||||
}
|
||||
|
@ -457,7 +463,13 @@ dump_symtab (struct objfile *objfile, struct symtab *symtab,
|
|||
fprintf_filtered (outfile, " under ");
|
||||
gdb_print_host_address (BLOCK_SUPERBLOCK (b), outfile);
|
||||
}
|
||||
blen = BLOCK_NSYMS (b);
|
||||
/* drow/2002-07-10: We could save the total symbols count
|
||||
even if we're using a hashtable, but nothing else but this message
|
||||
wants it. */
|
||||
blen = BLOCK_BUCKETS (b);
|
||||
if (BLOCK_HASHTABLE (b))
|
||||
fprintf_filtered (outfile, ", %d buckets in ", blen);
|
||||
else
|
||||
fprintf_filtered (outfile, ", %d syms in ", blen);
|
||||
print_address_numeric (BLOCK_START (b), 1, outfile);
|
||||
fprintf_filtered (outfile, "..");
|
||||
|
@ -474,8 +486,8 @@ dump_symtab (struct objfile *objfile, struct symtab *symtab,
|
|||
if (BLOCK_GCC_COMPILED (b))
|
||||
fprintf_filtered (outfile, ", compiled with gcc%d", BLOCK_GCC_COMPILED (b));
|
||||
fprintf_filtered (outfile, "\n");
|
||||
/* Now print each symbol in this block. */
|
||||
/* FIXMED: Sort? */
|
||||
/* Now print each symbol in this block (in no particular order, if
|
||||
we're using a hashtable). */
|
||||
ALL_BLOCK_SYMBOLS (b, j, sym)
|
||||
{
|
||||
struct print_symbol_args s;
|
||||
|
|
32
gdb/symtab.c
32
gdb/symtab.c
|
@ -1328,6 +1328,22 @@ lookup_block_symbol (register const struct block *block, const char *name,
|
|||
register struct symbol *sym_found = NULL;
|
||||
register int do_linear_search = 1;
|
||||
|
||||
if (BLOCK_HASHTABLE (block))
|
||||
{
|
||||
unsigned int hash_index;
|
||||
hash_index = msymbol_hash_iw (name);
|
||||
hash_index = hash_index % BLOCK_BUCKETS (block);
|
||||
for (sym = BLOCK_BUCKET (block, hash_index); sym; sym = sym->hash_next)
|
||||
{
|
||||
if (SYMBOL_NAMESPACE (sym) == namespace
|
||||
&& (mangled_name
|
||||
? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
|
||||
: SYMBOL_MATCHES_NAME (sym, name)))
|
||||
return sym;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If the blocks's symbols were sorted, start with a binary search. */
|
||||
|
||||
if (BLOCK_SHOULD_SORT (block))
|
||||
|
@ -1582,14 +1598,15 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
|
|||
if (section != 0)
|
||||
{
|
||||
int i;
|
||||
struct symbol *sym = NULL;
|
||||
|
||||
for (i = 0; i < b->nsyms; i++)
|
||||
ALL_BLOCK_SYMBOLS (b, i, sym)
|
||||
{
|
||||
fixup_symbol_section (b->sym[i], objfile);
|
||||
if (section == SYMBOL_BFD_SECTION (b->sym[i]))
|
||||
fixup_symbol_section (sym, objfile);
|
||||
if (section == SYMBOL_BFD_SECTION (sym))
|
||||
break;
|
||||
}
|
||||
if (i >= b->nsyms)
|
||||
if ((i >= BLOCK_BUCKETS (b)) && (sym == NULL))
|
||||
continue; /* no symbol in this symtab matches section */
|
||||
}
|
||||
distance = BLOCK_END (b) - BLOCK_START (b);
|
||||
|
@ -1661,10 +1678,8 @@ find_addr_symbol (CORE_ADDR addr, struct symtab **symtabp, CORE_ADDR *symaddrp)
|
|||
{
|
||||
QUIT;
|
||||
block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum);
|
||||
top = BLOCK_NSYMS (block);
|
||||
for (bot = 0; bot < top; bot++)
|
||||
ALL_BLOCK_SYMBOLS (block, bot, sym)
|
||||
{
|
||||
sym = BLOCK_SYM (block, bot);
|
||||
switch (SYMBOL_CLASS (sym))
|
||||
{
|
||||
case LOC_STATIC:
|
||||
|
@ -2795,10 +2810,9 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
|
|||
struct symbol_search *prevtail = tail;
|
||||
int nfound = 0;
|
||||
b = BLOCKVECTOR_BLOCK (bv, i);
|
||||
for (j = 0; j < BLOCK_NSYMS (b); j++)
|
||||
ALL_BLOCK_SYMBOLS (b, j, sym)
|
||||
{
|
||||
QUIT;
|
||||
sym = BLOCK_SYM (b, j);
|
||||
if (file_matches (s->filename, files, nfiles)
|
||||
&& ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
|
||||
&& ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF
|
||||
|
|
57
gdb/symtab.h
57
gdb/symtab.h
|
@ -386,6 +386,25 @@ struct block
|
|||
|
||||
unsigned char gcc_compile_flag;
|
||||
|
||||
/* The symbols for this block are either in a simple linear list or
|
||||
in a simple hashtable. Blocks which correspond to a function
|
||||
(which have a list of symbols corresponding to arguments) use
|
||||
a linear list, as do some older symbol readers (currently only
|
||||
mdebugread and dstread). Other blocks are hashed.
|
||||
|
||||
The hashtable uses the same hash function as the minsym hashtables,
|
||||
found in minsyms.c:minsym_hash_iw. Symbols are hashed based on
|
||||
their demangled name if appropriate, and on their name otherwise.
|
||||
The hash function ignores space, and stops at the beginning of the
|
||||
argument list if any.
|
||||
|
||||
The table is laid out in NSYMS/5 buckets and symbols are chained via
|
||||
their hash_next field. */
|
||||
|
||||
/* If this is really a hashtable of the symbols, this flag is 1. */
|
||||
|
||||
unsigned char hashtable;
|
||||
|
||||
/* Number of local symbols. */
|
||||
|
||||
int nsyms;
|
||||
|
@ -398,30 +417,38 @@ struct block
|
|||
|
||||
#define BLOCK_START(bl) (bl)->startaddr
|
||||
#define BLOCK_END(bl) (bl)->endaddr
|
||||
#define BLOCK_NSYMS(bl) (bl)->nsyms
|
||||
#define BLOCK_SYM(bl, n) (bl)->sym[n]
|
||||
#define BLOCK_FUNCTION(bl) (bl)->function
|
||||
#define BLOCK_SUPERBLOCK(bl) (bl)->superblock
|
||||
#define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag
|
||||
#define BLOCK_HASHTABLE(bl) (bl)->hashtable
|
||||
|
||||
/* For blocks without a hashtable (BLOCK_HASHTABLE (bl) == 0) only. */
|
||||
#define BLOCK_NSYMS(bl) (bl)->nsyms
|
||||
#define BLOCK_SYM(bl, n) (bl)->sym[n]
|
||||
|
||||
/* For blocks with a hashtable, but these are valid for non-hashed blocks as
|
||||
well - each symbol will appear to be one bucket by itself. */
|
||||
#define BLOCK_BUCKETS(bl) (bl)->nsyms
|
||||
#define BLOCK_BUCKET(bl, n) (bl)->sym[n]
|
||||
|
||||
/* Macro used to set the size of a hashtable for N symbols. */
|
||||
#define BLOCK_HASHTABLE_SIZE(n) ((n)/5 + 1)
|
||||
|
||||
/* Macro to loop through all symbols in a block BL, in no particular order.
|
||||
i counts which bucket we are in, and sym points to the current symbol. */
|
||||
|
||||
/* Macro to loop through all symbols in a block BL.
|
||||
i counts which symbol we are looking at, and sym points to the current
|
||||
symbol.
|
||||
The contortion at the end is to avoid reading past the last valid
|
||||
BLOCK_SYM. */
|
||||
#define ALL_BLOCK_SYMBOLS(bl, i, sym) \
|
||||
for ((i) = 0, (sym) = BLOCK_SYM ((bl), (i)); \
|
||||
(i) < BLOCK_NSYMS ((bl)); \
|
||||
++(i), (sym) = ((i) < BLOCK_NSYMS ((bl))) \
|
||||
? BLOCK_SYM ((bl), (i)) \
|
||||
: NULL)
|
||||
for ((i) = 0; (i) < BLOCK_BUCKETS ((bl)); (i)++) \
|
||||
for ((sym) = BLOCK_BUCKET ((bl), (i)); (sym); \
|
||||
(sym) = (sym)->hash_next)
|
||||
|
||||
/* Nonzero if symbols of block BL should be sorted alphabetically.
|
||||
Don't sort a block which corresponds to a function. If we did the
|
||||
sorting would have to preserve the order of the symbols for the
|
||||
arguments. */
|
||||
arguments. Also don't sort any block that we chose to hash. */
|
||||
|
||||
#define BLOCK_SHOULD_SORT(bl) ((bl)->nsyms >= 40 && BLOCK_FUNCTION (bl) == NULL)
|
||||
#define BLOCK_SHOULD_SORT(bl) (! BLOCK_HASHTABLE (bl) \
|
||||
&& BLOCK_FUNCTION (bl) == NULL)
|
||||
|
||||
|
||||
/* Represent one symbol name; a variable, constant, function or typedef. */
|
||||
|
@ -671,6 +698,8 @@ struct symbol
|
|||
/* List of ranges where this symbol is active. This is only
|
||||
used by alias symbols at the current time. */
|
||||
struct range_list *ranges;
|
||||
|
||||
struct symbol *hash_next;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue