diff options
-rw-r--r-- | gdb/ChangeLog | 36 | ||||
-rw-r--r-- | gdb/coffread.c | 6 | ||||
-rw-r--r-- | gdb/defs.h | 2 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 15 | ||||
-rw-r--r-- | gdb/dwarfread.c | 4 | ||||
-rw-r--r-- | gdb/mdebugread.c | 4 | ||||
-rw-r--r-- | gdb/minsyms.c | 11 | ||||
-rw-r--r-- | gdb/objfiles.c | 10 | ||||
-rw-r--r-- | gdb/objfiles.h | 10 | ||||
-rw-r--r-- | gdb/stabsread.c | 38 | ||||
-rw-r--r-- | gdb/symfile.c | 11 | ||||
-rw-r--r-- | gdb/symtab.c | 160 | ||||
-rw-r--r-- | gdb/symtab.h | 8 | ||||
-rw-r--r-- | gdb/utils.c | 8 |
14 files changed, 221 insertions, 102 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5a11d46..892cf79 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,39 @@ +2003-02-04 Daniel Jacobowitz <drow@mvista.com> + + * defs.h (streq): Add prototype. + * utils.c (streq): New function. + + * dwarf2read.c (new_symbol): Use SYMBOL_SET_NAMES instead of + SYMBOL_NAME and SYMBOL_INIT_DEMANGLED_NAME. + * mdebugread.c (new_symbol): Likewise. + * stabsread.c (define_symbol): Likewise. + * coffread.c (process_coff_symbol): Likewise. + * dwarfread.c (new_symbol): Likewise. + + * minsyms.c (prim_record_minimal_symbol_and_info): Use + SYMBOL_SET_NAMES instead of setting SYMBOL_NAME. Set the language + here. + (install_minimal_symbols): Don't set SYMBOL_LANGUAGE or call + SYMBOL_INIT_DEMANGLED_NAME. + * objfiles.c: Include "hashtab.h". + (allocate_objfile): Call htab_set_functions_ex for the + demangled_names_hash. + (free_objfile): Call htab_delete for the demangled_names_hash. + * objfiles.h (struct htab): Add declaration. + (struct objfile): Add demangled_names_hash. + * symfile.c: Include "hashtab.h". + (reread_symbols): Call htab_delete for the demangled_names_hash. + (add_psymbol_to_list): Use SYMBOL_SET_NAMES instead of putting + SYMBOL_NAME in the bcache. + * symtab.c: Include "hashtab.h". Update comments. + (create_demangled_names_hash, symbol_set_names): New functions. + (symbol_find_demangled_name): New function, broken out from + symbol_init_demangled_names. + (symbol_init_demangled_names): Use it. + * symtab.h (SYMBOL_INIT_DEMANGLED_NAME): Add missing parentheses. + (SYMBOL_SET_NAMES): New macro. + (symbol_set_names): Add prototype. + 2003-02-03 Jim Blandy <jimb@redhat.com> Use a single, consistent representation for an empty minimal diff --git a/gdb/coffread.c b/gdb/coffread.c index 573306d..adbca1c 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -1,6 +1,6 @@ /* Read coff symbol tables and convert to internal format, for GDB. Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001, 2002 + 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu). @@ -1469,10 +1469,8 @@ process_coff_symbol (register struct coff_symbol *cs, memset (sym, 0, sizeof (struct symbol)); name = cs->c_name; name = EXTERNAL_NAME (name, objfile->obfd); - SYMBOL_NAME (sym) = obsavestring (name, strlen (name), - &objfile->symbol_obstack); SYMBOL_LANGUAGE (sym) = language_auto; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); + SYMBOL_SET_NAMES (sym, name, strlen (name), objfile); /* default assumptions */ SYMBOL_VALUE (sym) = cs->c_value; @@ -308,6 +308,8 @@ extern void notice_quit (void); extern int strcmp_iw (const char *, const char *); +extern int streq (const char *, const char *); + extern int subset_compare (char *, char *); extern char *safe_strerror (int); diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index dd66145..ee0c9d4 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -4950,8 +4950,10 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, sizeof (struct symbol)); OBJSTAT (objfile, n_syms++); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = obsavestring (name, strlen (name), - &objfile->symbol_obstack); + + /* Cache this symbol's name and the name's demangled form (if any). */ + SYMBOL_LANGUAGE (sym) = cu_language; + SYMBOL_SET_NAMES (sym, name, strlen (name), objfile); /* Default assumptions. Use the passed type or decode it from the die. */ @@ -4966,15 +4968,6 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, { SYMBOL_LINE (sym) = DW_UNSND (attr); } - - /* If this symbol is from a C++ compilation, then attempt to - cache the demangled form for future reference. This is a - typical time versus space tradeoff, that was decided in favor - of time because it sped up C++ symbol lookups by a factor of - about 20. */ - - SYMBOL_LANGUAGE (sym) = cu_language; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); switch (die->tag) { case DW_TAG_label: diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c index 5c50b99..ea72fc0 100644 --- a/gdb/dwarfread.c +++ b/gdb/dwarfread.c @@ -2780,8 +2780,6 @@ new_symbol (struct dieinfo *dip, struct objfile *objfile) sizeof (struct symbol)); OBJSTAT (objfile, n_syms++); memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = create_name (dip->at_name, - &objfile->symbol_obstack); /* default assumptions */ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_CLASS (sym) = LOC_STATIC; @@ -2793,7 +2791,7 @@ new_symbol (struct dieinfo *dip, struct objfile *objfile) C++ symbol lookups by a factor of about 20. */ SYMBOL_LANGUAGE (sym) = cu_language; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); + SYMBOL_SET_NAMES (sym, dip->at_name, strlen (dip->at_name), objfile); switch (dip->die_tag) { case TAG_label: diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c index 30e94c7..ad87f46 100644 --- a/gdb/mdebugread.c +++ b/gdb/mdebugread.c @@ -4779,10 +4779,8 @@ new_symbol (char *name) sizeof (struct symbol))); memset (s, 0, sizeof (*s)); - SYMBOL_NAME (s) = obsavestring (name, strlen (name), - ¤t_objfile->symbol_obstack); SYMBOL_LANGUAGE (s) = psymtab_language; - SYMBOL_INIT_DEMANGLED_NAME (s, ¤t_objfile->symbol_obstack); + SYMBOL_SET_NAMES (s, name, strlen (name), current_objfile); return s; } diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 92dfa82..e4b0596 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -612,9 +612,10 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, msym_bunch = new; } msymbol = &msym_bunch->contents[msym_bunch_index]; - SYMBOL_NAME (msymbol) = obsavestring ((char *) name, strlen (name), - &objfile->symbol_obstack); SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown); + SYMBOL_LANGUAGE (msymbol) = language_auto; + SYMBOL_SET_NAMES (msymbol, (char *)name, strlen (name), objfile); + SYMBOL_VALUE_ADDRESS (msymbol) = address; SYMBOL_SECTION (msymbol) = section; SYMBOL_BFD_SECTION (msymbol) = bfd_section; @@ -866,7 +867,6 @@ install_minimal_symbols (struct objfile *objfile) for (bindex = 0; bindex < msym_bunch_index; bindex++, mcount++) { msymbols[mcount] = bunch->contents[bindex]; - SYMBOL_LANGUAGE (&msymbols[mcount]) = language_auto; if (SYMBOL_NAME (&msymbols[mcount])[0] == leading_char) { SYMBOL_NAME (&msymbols[mcount])++; @@ -926,11 +926,6 @@ install_minimal_symbols (struct objfile *objfile) } } } - - /* Now walk through all the minimal symbols, selecting the newly added - ones and attempting to cache their C++ demangled names. */ - for (; mcount-- > 0; msymbols++) - SYMBOL_INIT_DEMANGLED_NAME (msymbols, &objfile->symbol_obstack); /* Now build the hash tables; we can't do this incrementally at an earlier point since we weren't finished with the obstack diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 16d8527..9084401 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -1,7 +1,7 @@ /* GDB routines for manipulating objfiles. Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002 Free Software Foundation, Inc. + 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. @@ -39,6 +39,7 @@ #include <fcntl.h> #include "gdb_obstack.h" #include "gdb_string.h" +#include "hashtab.h" #include "breakpoint.h" @@ -191,6 +192,11 @@ allocate_objfile (bfd *abfd, int flags) objfile->md = md; objfile->mmfd = fd; /* Update pointers to functions to *our* copies */ + if (objfile->demangled_names_hash) + htab_set_functions_ex + (objfile->demangled_names_hash, htab_hash_string, + (int (*) (const void *, const void *)) streq, NULL, + objfile->md, xmcalloc, xmfree); obstack_chunkfun (&objfile->psymbol_cache.cache, xmmalloc); obstack_freefun (&objfile->psymbol_cache.cache, xmfree); obstack_chunkfun (&objfile->macro_cache.cache, xmmalloc); @@ -551,6 +557,8 @@ free_objfile (struct objfile *objfile) /* Free the obstacks for non-reusable objfiles */ bcache_xfree (objfile->psymbol_cache); bcache_xfree (objfile->macro_cache); + if (objfile->demangled_names_hash) + htab_delete (objfile->demangled_names_hash); obstack_free (&objfile->psymbol_obstack, 0); obstack_free (&objfile->symbol_obstack, 0); obstack_free (&objfile->type_obstack, 0); diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 44b8201..7546623 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -1,7 +1,7 @@ /* Definitions for symbol file management in GDB. Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002 Free Software Foundation, Inc. + 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -27,6 +27,7 @@ #include "symfile.h" /* For struct psymbol_allocation_list */ struct bcache; +struct htab; /* This structure maintains information on a per-objfile basis about the "entry point" of the objfile, and the scope within which the entry point @@ -286,6 +287,13 @@ struct objfile struct bcache *psymbol_cache; /* Byte cache for partial syms */ struct bcache *macro_cache; /* Byte cache for macros */ + /* Hash table for mapping symbol names to demangled names. Each + entry in the hash table is actually two consecutive strings, + both null-terminated; the first one is a mangled or linkage + name, and the second is the demangled name or just a zero byte + if the name doesn't demangle. */ + struct htab *demangled_names_hash; + /* Vectors of all partial symbols read in from file. The actual data is stored in the psymbol_obstack. */ diff --git a/gdb/stabsread.c b/gdb/stabsread.c index b873be6..0afd6d5 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -1329,23 +1329,13 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, if (refnum >= 0) { if (nlen > 0) - { - SYMBOL_NAME (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, nlen); - strncpy (SYMBOL_NAME (sym), s, nlen); - SYMBOL_NAME (sym)[nlen] = '\0'; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); - } + SYMBOL_SET_NAMES (sym, s, nlen, objfile); else /* FIXME! Want SYMBOL_NAME (sym) = 0; Get error if leave name 0. So give it something. */ { nlen = p - string; - SYMBOL_NAME (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, nlen); - strncpy (SYMBOL_NAME (sym), string, nlen); - SYMBOL_NAME (sym)[nlen] = '\0'; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); + SYMBOL_SET_NAMES (sym, string, nlen, objfile); } } /* Advance STRING beyond the reference id. */ @@ -1355,29 +1345,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, { normal: SYMBOL_LANGUAGE (sym) = current_subfile->language; - SYMBOL_NAME (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, ((p - string) + 1)); - /* Open-coded memcpy--saves function call time. */ - /* FIXME: Does it really? Try replacing with simple strcpy and - try it on an executable with a large symbol table. */ - /* FIXME: considering that gcc can open code memcpy anyway, I - doubt it. xoxorich. */ - { - register char *p1 = string; - register char *p2 = SYMBOL_NAME (sym); - while (p1 != p) - { - *p2++ = *p1++; - } - *p2++ = '\0'; - } - - /* If this symbol is from a C++ compilation, then attempt to cache the - demangled form for future reference. This is a typical time versus - space tradeoff, that was decided in favor of time because it sped up - C++ symbol lookups by a factor of about 20. */ - - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); + SYMBOL_SET_NAMES (sym, string, p - string, objfile); } p++; diff --git a/gdb/symfile.c b/gdb/symfile.c index 7a53bee..23ca1d2 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -44,6 +44,7 @@ #include "gdb_obstack.h" #include "completer.h" #include "bcache.h" +#include "hashtab.h" #include <readline/readline.h> #include "gdb_assert.h" @@ -1983,6 +1984,11 @@ reread_symbols (void) objfile->psymbol_cache = bcache_xmalloc (); bcache_xfree (objfile->macro_cache); objfile->macro_cache = bcache_xmalloc (); + if (objfile->demangled_names_hash != NULL) + { + htab_delete (objfile->demangled_names_hash); + objfile->demangled_names_hash = NULL; + } obstack_free (&objfile->psymbol_obstack, 0); obstack_free (&objfile->symbol_obstack, 0); obstack_free (&objfile->type_obstack, 0); @@ -2684,7 +2690,6 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace, /* Create local copy of the partial symbol */ memcpy (buf, name, namelength); buf[namelength] = '\0'; - SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, objfile->psymbol_cache); /* val and coreaddr are mutually exclusive, one of them *will* be zero */ if (val != 0) { @@ -2698,7 +2703,8 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace, SYMBOL_LANGUAGE (&psymbol) = language; PSYMBOL_NAMESPACE (&psymbol) = namespace; PSYMBOL_CLASS (&psymbol) = class; - SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language); + + SYMBOL_SET_NAMES (&psymbol, buf, namelength, objfile); /* Stash the partial symbol away in the cache */ psym = bcache (&psymbol, sizeof (struct partial_symbol), objfile->psymbol_cache); @@ -3706,5 +3712,4 @@ Usage: set extension-language .foo bar", &setlist)); add_show_from_set (c, &showlist); set_cmd_completer (c, filename_completer); - } diff --git a/gdb/symtab.c b/gdb/symtab.c index 9d8bdc0..606a538 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -41,6 +41,8 @@ #include "source.h" #include "filenames.h" /* for FILENAME_CMP */ +#include "hashtab.h" + #include "gdb_obstack.h" #include <sys/types.h> @@ -425,22 +427,35 @@ symbol_init_language_specific (struct general_symbol_info *gsymbol, } } -/* Initialize a symbol's mangled name. */ +/* Functions to initialize a symbol's mangled name. */ + +/* Create the hash table used for demangled names. Each hash entry is + a pair of strings; one for the mangled name and one for the demangled + name. The entry is hashed via just the mangled name. */ -/* Try to initialize the demangled name for a symbol, based on the +static void +create_demangled_names_hash (struct objfile *objfile) +{ + /* Choose 256 as the starting size of the hash table, somewhat arbitrarily. + The hash table code will round this up to the next prime number. + Choosing a much larger table size wastes memory, and saves only about + 1% in symbol reading. */ + + objfile->demangled_names_hash = htab_create_alloc_ex + (256, htab_hash_string, (int (*) (const void *, const void *)) streq, + NULL, objfile->md, xmcalloc, xmfree); +} + +/* Try to determine the demangled name for a symbol, based on the language of that symbol. If the language is set to language_auto, it will attempt to find any demangling algorithm that works and - then set the language appropriately. If no demangling of any kind - is found, the language is set back to language_unknown, so we can - avoid doing this work again the next time we encounter the symbol. - Any required space to store the name is obtained from the specified - obstack. */ + then set the language appropriately. The returned name is allocated + by the demangler and should be xfree'd. */ -void -symbol_init_demangled_name (struct general_symbol_info *gsymbol, - struct obstack *obstack) +static char * +symbol_find_demangled_name (struct general_symbol_info *gsymbol, + const char *mangled) { - char *mangled = gsymbol->name; char *demangled = NULL; if (gsymbol->language == language_unknown) @@ -449,35 +464,116 @@ symbol_init_demangled_name (struct general_symbol_info *gsymbol, || gsymbol->language == language_auto) { demangled = - cplus_demangle (gsymbol->name, DMGL_PARAMS | DMGL_ANSI); + cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); if (demangled != NULL) - { - gsymbol->language = language_cplus; - gsymbol->language_specific.cplus_specific.demangled_name = - obsavestring (demangled, strlen (demangled), obstack); - xfree (demangled); - } - else - { - gsymbol->language_specific.cplus_specific.demangled_name = NULL; - } + { + gsymbol->language = language_cplus; + return demangled; + } } if (gsymbol->language == language_java) { demangled = - cplus_demangle (gsymbol->name, + cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA); if (demangled != NULL) - { - gsymbol->language = language_java; - gsymbol->language_specific.cplus_specific.demangled_name = - obsavestring (demangled, strlen (demangled), obstack); - xfree (demangled); - } + { + gsymbol->language = language_java; + return demangled; + } + } + return NULL; +} + +/* Set both the mangled and demangled (if any) names for GSYMBOL based on + NAME and LEN. The hash table corresponding to OBJFILE is used, and the + memory comes from that objfile's symbol_obstack. NAME is copied, so the + pointer can be discarded after calling this function. */ + +void +symbol_set_names (struct general_symbol_info *gsymbol, + const char *name, int len, struct objfile *objfile) +{ + char **slot; + const char *tmpname; + + if (objfile->demangled_names_hash == NULL) + create_demangled_names_hash (objfile); + + /* The stabs reader generally provides names that are not NULL-terminated; + most of the other readers don't do this, so we can just use the given + copy. */ + if (name[len] != 0) + { + char *alloc_name = alloca (len + 1); + memcpy (alloc_name, name, len); + alloc_name[len] = 0; + tmpname = alloc_name; + } + else + tmpname = name; + + slot = (char **) htab_find_slot (objfile->demangled_names_hash, tmpname, INSERT); + + /* If this name is not in the hash table, add it. */ + if (*slot == NULL) + { + char *demangled_name = symbol_find_demangled_name (gsymbol, tmpname); + int demangled_len = demangled_name ? strlen (demangled_name) : 0; + + /* If there is a demangled name, place it right after the mangled name. + Otherwise, just place a second zero byte after the end of the mangled + name. */ + *slot = obstack_alloc (&objfile->symbol_obstack, + len + demangled_len + 2); + memcpy (*slot, tmpname, len + 1); + if (demangled_name) + { + memcpy (*slot + len + 1, demangled_name, demangled_len + 1); + xfree (demangled_name); + } + else + (*slot)[len + 1] = 0; + } + + gsymbol->name = *slot; + if ((*slot)[len + 1]) + gsymbol->language_specific.cplus_specific.demangled_name + = &(*slot)[len + 1]; + else + gsymbol->language_specific.cplus_specific.demangled_name = NULL; +} + +/* Initialize the demangled name of GSYMBOL if possible. Any required space + to store the name is obtained from the specified obstack. The function + symbol_set_names, above, should be used instead where possible for more + efficient memory usage. */ + +void +symbol_init_demangled_name (struct general_symbol_info *gsymbol, + struct obstack *obstack) +{ + char *mangled = gsymbol->name; + char *demangled = NULL; + + demangled = symbol_find_demangled_name (gsymbol, mangled); + if (gsymbol->language == language_cplus + || gsymbol->language == language_java) + { + if (demangled) + { + gsymbol->language_specific.cplus_specific.demangled_name + = obsavestring (demangled, strlen (demangled), obstack); + xfree (demangled); + } else - { - gsymbol->language_specific.cplus_specific.demangled_name = NULL; - } + gsymbol->language_specific.cplus_specific.demangled_name = NULL; + } + else + { + /* Unknown language; just clean up quietly. */ + if (demangled) + xfree (demangled); } } diff --git a/gdb/symtab.h b/gdb/symtab.h index 8d851a2..b21081d 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -149,10 +149,16 @@ extern void symbol_init_language_specific (struct general_symbol_info *symbol, enum language language); #define SYMBOL_INIT_DEMANGLED_NAME(symbol,obstack) \ - (symbol_init_demangled_name (&symbol->ginfo, (obstack))) + (symbol_init_demangled_name (&(symbol)->ginfo, (obstack))) extern void symbol_init_demangled_name (struct general_symbol_info *symbol, struct obstack *obstack); +#define SYMBOL_SET_NAMES(symbol,name,len,objfile) \ + symbol_set_names (&(symbol)->ginfo, name, len, objfile) +extern void symbol_set_names (struct general_symbol_info *symbol, + const char *name, int len, + struct objfile *objfile); + /* Return the demangled name for a symbol based on the language for that symbol. If no demangled name exists, return NULL. */ #define SYMBOL_DEMANGLED_NAME(symbol) \ diff --git a/gdb/utils.c b/gdb/utils.c index 0e92b21..77855ae 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -2357,6 +2357,14 @@ strcmp_iw (const char *string1, const char *string2) } return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0'); } + +/* A simple comparison function with opposite semantics to strcmp. */ + +int +streq (const char *lhs, const char *rhs) +{ + return !strcmp (lhs, rhs); +} /* |