From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32082 invoked by alias); 14 Feb 2002 23:55:08 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 31983 invoked from network); 14 Feb 2002 23:55:04 -0000 Received: from unknown (HELO nevyn.them.org) (128.2.145.6) by sources.redhat.com with SMTP; 14 Feb 2002 23:55:04 -0000 Received: from drow by nevyn.them.org with local (Exim 3.34 #1 (Debian)) id 16bViR-0007a5-00 for ; Thu, 14 Feb 2002 18:55:03 -0500 Date: Thu, 14 Feb 2002 15:55:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sources.redhat.com Subject: [RFA] Select a particular mangling of a demangled symbol in lookup_block_symbol Message-ID: <20020214185503.A28610@nevyn.them.org> Mail-Followup-To: gdb-patches@sources.redhat.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.23i X-SW-Source: 2002-02/txt/msg00425.txt.bz2 I just described the problem this patch addresses in my testsuite patch; perhaps not the best place :) Here's the relevant bit: - Multiple symbols with the same demangled name. We can work around this for stabs, because we have the physname. We don't have that option for DWARF-2, and we shouldn't need to for stabs. I have a patch for the workaround. We get the [not-in-charge] constructor by default, unfortunately. What this means is that we call lookup_block_symbol on something like: _ZN3fooC1ERS_ but get the information for: _ZN3fooC2ERS_ The breakpoint ends up on the base-not-in-charge constructor. What we really SHOULD do is set it on both constructors silently, without even acknowledging that they are different functions, or else offer the user the choice. My preference is actually for the former. That requires support for a single function existing in multiple places, which will also give us nice things like better support for inlined functions with DWARF-2 (which will always be somewhat shoddy due to the nature of inlining, in that it only occurs with lots of other optimization - but we can do much better than we do). Is this patch OK, or is it deemed too gross? -- Daniel Jacobowitz Carnegie Mellon University MontaVista Software Debian GNU/Linux Developer 2002-02-14 Daniel Jacobowitz * symtab.h (lookup_block_symbol): Add mangled_name argument to prototype. * symmisc.c (maintenance_check_symtabs): Call lookup_block_symbol with new mangled_name argument. * linespec.c (decode_line_1): Likewise. * valops (value_of_this): Likewise. * symtab.c (lookup_transparent_type): Likewise. (lookup_symbol_aux): Likewise. Accept new mangled_name argument. (lookup_symbol): If we are given a mangled name, pass it down to lookup_symbol_aux. (lookup_block_symbol): If we are given a mangled name to check against, only return symbols which match it. Index: linespec.c =================================================================== RCS file: /cvs/src/src/gdb/linespec.c,v retrieving revision 1.14 diff -p -u -r1.14 linespec.c --- linespec.c 2002/02/02 03:42:58 1.14 +++ linespec.c 2002/02/14 23:34:24 @@ -1180,7 +1180,7 @@ symbol_found: /* We also jump here fro { struct blockvector *bv = BLOCKVECTOR (sym_symtab); struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - if (lookup_block_symbol (b, copy, VAR_NAMESPACE) != NULL) + if (lookup_block_symbol (b, copy, NULL, VAR_NAMESPACE) != NULL) build_canonical_line_spec (values.sals, copy, canonical); } return values; Index: symmisc.c =================================================================== RCS file: /cvs/src/src/gdb/symmisc.c,v retrieving revision 1.7 diff -p -u -r1.7 symmisc.c --- symmisc.c 2001/12/02 22:38:23 1.7 +++ symmisc.c 2002/02/14 23:34:24 @@ -959,7 +959,7 @@ maintenance_check_symtabs (char *ignore, while (length--) { sym = lookup_block_symbol (b, SYMBOL_NAME (*psym), - SYMBOL_NAMESPACE (*psym)); + NULL, SYMBOL_NAMESPACE (*psym)); if (!sym) { printf_filtered ("Static symbol `"); @@ -976,7 +976,7 @@ maintenance_check_symtabs (char *ignore, while (length--) { sym = lookup_block_symbol (b, SYMBOL_NAME (*psym), - SYMBOL_NAMESPACE (*psym)); + NULL, SYMBOL_NAMESPACE (*psym)); if (!sym) { printf_filtered ("Global symbol `"); Index: symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.54 diff -p -u -r1.54 symtab.c --- symtab.c 2002/02/11 03:21:53 1.54 +++ symtab.c 2002/02/14 23:34:24 @@ -80,11 +80,12 @@ static struct partial_symbol *lookup_par 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); @@ -567,6 +568,7 @@ lookup_symbol (const char *name, const s { char *modified_name = NULL; char *modified_name2 = NULL; + const char *mangled_name = NULL; int needtofreename = 0; struct symbol *returnval; @@ -592,13 +594,14 @@ lookup_symbol (const char *name, const s 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); @@ -606,9 +609,9 @@ lookup_symbol (const char *name, const s } 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; @@ -623,7 +626,7 @@ lookup_symbol_aux (const char *name, con while (block != 0) { - sym = lookup_block_symbol (block, name, namespace); + sym = lookup_block_symbol (block, name, mangled_name, namespace); if (sym) { block_found = block; @@ -676,7 +679,7 @@ lookup_symbol_aux (const char *name, con 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; @@ -714,7 +717,7 @@ lookup_symbol_aux (const char *name, con { 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; @@ -743,14 +746,14 @@ lookup_symbol_aux (const char *name, con 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 @@ -776,7 +779,7 @@ lookup_symbol_aux (const char *name, con { /* 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 @@ -794,7 +797,7 @@ lookup_symbol_aux (const char *name, con 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 @@ -803,7 +806,7 @@ lookup_symbol_aux (const char *name, con * 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\ @@ -827,7 +830,7 @@ lookup_symbol_aux (const char *name, con { 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; @@ -844,7 +847,7 @@ lookup_symbol_aux (const char *name, con 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 @@ -853,7 +856,7 @@ lookup_symbol_aux (const char *name, con * 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\ @@ -910,14 +913,14 @@ lookup_symbol_aux (const char *name, con 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) @@ -954,8 +957,9 @@ lookup_symbol_aux (const char *name, con && 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); } } } @@ -1081,7 +1085,7 @@ lookup_transparent_type (const char *nam { 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); @@ -1095,7 +1099,7 @@ lookup_transparent_type (const char *nam 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 @@ -1104,7 +1108,7 @@ lookup_transparent_type (const char *nam * 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\ @@ -1128,7 +1132,7 @@ lookup_transparent_type (const char *nam { 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); @@ -1142,7 +1146,7 @@ lookup_transparent_type (const char *nam 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 @@ -1151,7 +1155,7 @@ lookup_transparent_type (const char *nam * 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\ @@ -1195,10 +1199,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; @@ -1258,14 +1267,19 @@ lookup_block_symbol (register const stru 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; } @@ -1297,8 +1311,10 @@ lookup_block_symbol (register const stru 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 Index: symtab.h =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.26 diff -p -u -r1.26 symtab.h --- symtab.h 2001/12/21 22:32:37 1.26 +++ symtab.h 2002/02/14 23:34:24 @@ -1095,6 +1095,7 @@ extern struct symbol *lookup_symbol (con /* lookup a symbol by name, within a specified block */ extern struct symbol *lookup_block_symbol (const struct block *, const char *, + const char *, const namespace_enum); /* lookup a [struct, union, enum] by name, within a specified block */ Index: valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.51 diff -p -u -r1.51 valops.c --- valops.c 2002/02/10 05:50:34 1.51 +++ valops.c 2002/02/14 23:34:25 @@ -3249,7 +3249,7 @@ value_of_this (int complain) /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER symbol instead of the LOC_ARG one (if both exist). */ - sym = lookup_block_symbol (b, funny_this, VAR_NAMESPACE); + sym = lookup_block_symbol (b, funny_this, NULL, VAR_NAMESPACE); if (sym == NULL) { if (complain)