diff options
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r-- | gdb/symtab.c | 230 |
1 files changed, 178 insertions, 52 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c index e464b0b..3a42867 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -80,11 +80,12 @@ static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *, const char *, int, namespace_enum); -static struct symbol *lookup_symbol_aux (const char *name, const - struct block *block, const - namespace_enum namespace, int - *is_a_field_of_this, struct - symtab **symtab); +static struct symbol *lookup_symbol_aux (const char *name, + const char *mangled_name, + const struct block *block, + const namespace_enum namespace, + int *is_a_field_of_this, + struct symtab **symtab); static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr); @@ -143,11 +144,17 @@ lookup_symtab (const char *name) register struct partial_symtab *ps; register struct objfile *objfile; char *real_path = NULL; + char *full_path = NULL; /* Here we are interested in canonicalizing an absolute path, not absolutizing a relative path. */ if (IS_ABSOLUTE_PATH (name)) - real_path = gdb_realpath (name); + { + full_path = xfullpath (name); + make_cleanup (xfree, full_path); + real_path = gdb_realpath (name); + make_cleanup (xfree, real_path); + } got_symtab: @@ -157,24 +164,32 @@ got_symtab: { if (FILENAME_CMP (name, s->filename) == 0) { - xfree (real_path); return s; } + /* If the user gave us an absolute path, try to find the file in this symtab and use its absolute path. */ + + if (full_path != NULL) + { + const char *fp = symtab_to_filename (s); + if (FILENAME_CMP (full_path, fp) == 0) + { + return s; + } + } + if (real_path != NULL) { - char *rp = symtab_to_filename (s); + char *rp = gdb_realpath (symtab_to_filename (s)); + make_cleanup (xfree, rp); if (FILENAME_CMP (real_path, rp) == 0) { - xfree (real_path); return s; } } } - xfree (real_path); - /* Now, search for a matching tail (only if name doesn't have any dirs) */ if (lbasename (name) == name) @@ -220,36 +235,55 @@ lookup_partial_symtab (const char *name) { register struct partial_symtab *pst; register struct objfile *objfile; + char *full_path = NULL; char *real_path = NULL; /* Here we are interested in canonicalizing an absolute path, not absolutizing a relative path. */ if (IS_ABSOLUTE_PATH (name)) - real_path = gdb_realpath (name); + { + full_path = xfullpath (name); + make_cleanup (xfree, full_path); + real_path = gdb_realpath (name); + make_cleanup (xfree, real_path); + } ALL_PSYMTABS (objfile, pst) { if (FILENAME_CMP (name, pst->filename) == 0) { - xfree (real_path); return (pst); } + /* If the user gave us an absolute path, try to find the file in this symtab and use its absolute path. */ - if (real_path != NULL) + if (full_path != NULL) { if (pst->fullname == NULL) source_full_path_of (pst->filename, &pst->fullname); if (pst->fullname != NULL - && FILENAME_CMP (real_path, pst->fullname) == 0) + && FILENAME_CMP (full_path, pst->fullname) == 0) { - xfree (real_path); return pst; } } - } - xfree (real_path); + if (real_path != NULL) + { + char *rp = NULL; + if (pst->fullname == NULL) + source_full_path_of (pst->filename, &pst->fullname); + if (pst->fullname != NULL) + { + rp = gdb_realpath (pst->fullname); + make_cleanup (xfree, rp); + } + if (rp != NULL && FILENAME_CMP (real_path, rp) == 0) + { + return pst; + } + } + } /* Now, search for a matching tail (only if name doesn't have any dirs) */ @@ -348,6 +382,83 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id) strcat (mangled_name, physname); return (mangled_name); } + + +/* Initialize a symbol's mangled name. */ + +/* Try to initialize 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. */ + +void +symbol_init_demangled_name (struct general_symbol_info *gsymbol, + struct obstack *obstack) +{ + char *mangled = gsymbol->name; + char *demangled = NULL; + + if (gsymbol->language == language_unknown) + gsymbol->language = language_auto; + if (gsymbol->language == language_cplus + || gsymbol->language == language_auto) + { + demangled = + cplus_demangle (gsymbol->name, 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; + } + } + if (gsymbol->language == language_java) + { + demangled = + cplus_demangle (gsymbol->name, + 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); + } + else + { + gsymbol->language_specific.cplus_specific.demangled_name = NULL; + } + } + if (demangled == NULL + && (gsymbol->language == language_chill + || gsymbol->language == language_auto)) + { + demangled = + chill_demangle (gsymbol->name); + if (demangled != NULL) + { + gsymbol->language = language_chill; + gsymbol->language_specific.chill_specific.demangled_name = + obsavestring (demangled, strlen (demangled), obstack); + xfree (demangled); + } + else + { + gsymbol->language_specific.chill_specific.demangled_name = NULL; + } + } +} + + @@ -570,6 +681,7 @@ lookup_symbol (const char *name, const struct block *block, { char *modified_name = NULL; char *modified_name2 = NULL; + const char *mangled_name = NULL; int needtofreename = 0; struct symbol *returnval; @@ -595,13 +707,14 @@ lookup_symbol (const char *name, const struct block *block, modified_name2 = cplus_demangle (modified_name, DMGL_ANSI | DMGL_PARAMS); if (modified_name2) { + mangled_name = name; modified_name = modified_name2; needtofreename = 1; } } - returnval = lookup_symbol_aux (modified_name, block, namespace, - is_a_field_of_this, symtab); + returnval = lookup_symbol_aux (modified_name, mangled_name, block, + namespace, is_a_field_of_this, symtab); if (needtofreename) xfree (modified_name2); @@ -609,9 +722,9 @@ lookup_symbol (const char *name, const struct block *block, } static struct symbol * -lookup_symbol_aux (const char *name, const struct block *block, - const namespace_enum namespace, int *is_a_field_of_this, - struct symtab **symtab) +lookup_symbol_aux (const char *name, const char *mangled_name, + const struct block *block, const namespace_enum namespace, + int *is_a_field_of_this, struct symtab **symtab) { register struct symbol *sym; register struct symtab *s = NULL; @@ -626,7 +739,7 @@ lookup_symbol_aux (const char *name, const struct block *block, while (block != 0) { - sym = lookup_block_symbol (block, name, namespace); + sym = lookup_block_symbol (block, name, mangled_name, namespace); if (sym) { block_found = block; @@ -679,7 +792,7 @@ lookup_symbol_aux (const char *name, const struct block *block, if (BLOCK_START (b) <= BLOCK_START (block) && BLOCK_END (b) > BLOCK_START (block)) { - sym = lookup_block_symbol (b, name, VAR_NAMESPACE); + sym = lookup_block_symbol (b, name, mangled_name, VAR_NAMESPACE); if (sym) { block_found = b; @@ -717,7 +830,7 @@ lookup_symbol_aux (const char *name, const struct block *block, { bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, namespace); + sym = lookup_block_symbol (block, name, mangled_name, namespace); if (sym) { block_found = block; @@ -746,14 +859,14 @@ lookup_symbol_aux (const char *name, const struct block *block, bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol), - namespace); + mangled_name, namespace); /* We kept static functions in minimal symbol table as well as in static scope. We want to find them in the symbol table. */ if (!sym) { block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol), - namespace); + mangled_name, namespace); } /* sym == 0 if symbol was found in the minimal symbol table @@ -779,7 +892,7 @@ lookup_symbol_aux (const char *name, const struct block *block, { /* This is a mangled variable, look it up by its mangled name. */ - return lookup_symbol_aux (SYMBOL_NAME (msymbol), block, + return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name, block, namespace, is_a_field_of_this, symtab); } /* There are no debug symbols for this file, or we are looking @@ -797,7 +910,7 @@ lookup_symbol_aux (const char *name, const struct block *block, s = PSYMTAB_TO_SYMTAB (ps); bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, namespace); + sym = lookup_block_symbol (block, name, mangled_name, namespace); if (!sym) { /* This shouldn't be necessary, but as a last resort @@ -806,7 +919,7 @@ lookup_symbol_aux (const char *name, const struct block *block, * the psymtab gets it wrong in some cases. */ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, namespace); + sym = lookup_block_symbol (block, name, mangled_name, namespace); if (!sym) error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\ %s may be an inlined function, or may be a template function\n\ @@ -830,7 +943,7 @@ lookup_symbol_aux (const char *name, const struct block *block, { bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, namespace); + sym = lookup_block_symbol (block, name, mangled_name, namespace); if (sym) { block_found = block; @@ -847,7 +960,7 @@ lookup_symbol_aux (const char *name, const struct block *block, s = PSYMTAB_TO_SYMTAB (ps); bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, namespace); + sym = lookup_block_symbol (block, name, mangled_name, namespace); if (!sym) { /* This shouldn't be necessary, but as a last resort @@ -856,7 +969,7 @@ lookup_symbol_aux (const char *name, const struct block *block, * the psymtab gets it wrong in some cases. */ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, namespace); + sym = lookup_block_symbol (block, name, mangled_name, namespace); if (!sym) error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\ %s may be an inlined function, or may be a template function\n\ @@ -913,14 +1026,14 @@ lookup_symbol_aux (const char *name, const struct block *block, bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol), - namespace); + mangled_name, namespace); /* We kept static functions in minimal symbol table as well as in static scope. We want to find them in the symbol table. */ if (!sym) { block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol), - namespace); + mangled_name, namespace); } /* If we found one, return it */ if (sym) @@ -957,8 +1070,9 @@ lookup_symbol_aux (const char *name, const struct block *block, && MSYMBOL_TYPE (msymbol) != mst_file_text && !STREQ (name, SYMBOL_NAME (msymbol))) { - return lookup_symbol_aux (SYMBOL_NAME (msymbol), block, - namespace, is_a_field_of_this, symtab); + return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name, + block, namespace, is_a_field_of_this, + symtab); } } } @@ -1084,7 +1198,7 @@ lookup_transparent_type (const char *name) { bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE); if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) { return SYMBOL_TYPE (sym); @@ -1098,7 +1212,7 @@ lookup_transparent_type (const char *name) s = PSYMTAB_TO_SYMTAB (ps); bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE); if (!sym) { /* This shouldn't be necessary, but as a last resort @@ -1107,7 +1221,7 @@ lookup_transparent_type (const char *name) * the psymtab gets it wrong in some cases. */ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE); if (!sym) error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\ %s may be an inlined function, or may be a template function\n\ @@ -1131,7 +1245,7 @@ lookup_transparent_type (const char *name) { bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE); if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) { return SYMBOL_TYPE (sym); @@ -1145,7 +1259,7 @@ lookup_transparent_type (const char *name) s = PSYMTAB_TO_SYMTAB (ps); bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE); if (!sym) { /* This shouldn't be necessary, but as a last resort @@ -1154,7 +1268,7 @@ lookup_transparent_type (const char *name) * the psymtab gets it wrong in some cases. */ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE); + sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE); if (!sym) error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\ %s may be an inlined function, or may be a template function\n\ @@ -1198,10 +1312,15 @@ find_main_psymtab (void) binary search terminates, we drop through and do a straight linear search on the symbols. Each symbol which is marked as being a C++ symbol (language_cplus set) has both the encoded and non-encoded names - tested for a match. */ + tested for a match. + + If MANGLED_NAME is non-NULL, verify that any symbol we find has this + particular mangled name. +*/ struct symbol * lookup_block_symbol (register const struct block *block, const char *name, + const char *mangled_name, const namespace_enum namespace) { register int bot, top, inc; @@ -1261,14 +1380,19 @@ lookup_block_symbol (register const struct block *block, const char *name, return the first one; I believe it is now impossible for us to encounter two symbols with the same name and namespace here, because blocks containing argument symbols are no - longer sorted. */ + longer sorted. The exception is for C++, where multiple functions + (cloned constructors / destructors, in particular) can have + the same demangled name. So if we have a particular + mangled name to match, try to do so. */ top = BLOCK_NSYMS (block); while (bot < top) { sym = BLOCK_SYM (block, bot); - if (SYMBOL_NAMESPACE (sym) == namespace && - SYMBOL_MATCHES_NAME (sym, name)) + if (SYMBOL_NAMESPACE (sym) == namespace + && (mangled_name + ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0 + : SYMBOL_MATCHES_NAME (sym, name))) { return sym; } @@ -1300,8 +1424,10 @@ lookup_block_symbol (register const struct block *block, const char *name, while (bot < top) { sym = BLOCK_SYM (block, bot); - if (SYMBOL_NAMESPACE (sym) == namespace && - SYMBOL_MATCHES_NAME (sym, name)) + if (SYMBOL_NAMESPACE (sym) == namespace + && (mangled_name + ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0 + : SYMBOL_MATCHES_NAME (sym, name))) { /* If SYM has aliases, then use any alias that is active at the current PC. If no alias is active at the current @@ -3186,7 +3312,7 @@ make_symbol_completion_list (char *text, char *word) /* Search upwards from currently selected frame (so that we can complete on local vars. */ - for (b = get_selected_block (); b != NULL; b = BLOCK_SUPERBLOCK (b)) + for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b)) { if (!BLOCK_SUPERBLOCK (b)) { @@ -3719,7 +3845,7 @@ make_symbol_overload_list (struct symbol *fsym) /* Search upwards from currently selected frame (so that we can complete on local vars. */ - for (b = get_selected_block (); b != NULL; b = BLOCK_SUPERBLOCK (b)) + for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b)) { if (!BLOCK_SUPERBLOCK (b)) { |