From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2753 invoked by alias); 13 Aug 2004 00:06:03 -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 2734 invoked from network); 13 Aug 2004 00:06:01 -0000 Received: from unknown (HELO primx.cistron.nl) (62.216.30.74) by sourceware.org with SMTP; 13 Aug 2004 00:06:01 -0000 Received: from picard.cistron.nl ([62.216.30.70] ident=mail) by primx.cistron.nl with esmtp (Exim 4.33 #1) id 1BvPa5-0007yF-5w for ; Fri, 13 Aug 2004 02:06:01 +0200 Received: from v-overbeek (helo=localhost) by picard.cistron.nl with local-esmtp (Exim 3.35 #1 (Debian)) id 1BvPa4-0006MJ-00 for ; Fri, 13 Aug 2004 02:06:00 +0200 Date: Fri, 13 Aug 2004 00:06:00 -0000 From: Ton van Overbeek To: gdb-patches@sources.redhat.com Subject: [PATCH] Fix coff symbol table reading problem for C code compiled by g++ Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-SW-Source: 2004-08/txt/msg00479.txt.bz2 I found a bug/problem in the symbol reading code in symtab.c in gdb-6.2. The problem occurs when reading symbols from a coff object file produced from a C source file compiled by g++ (not by gcc). The particular compiler is m68k-palmos-gcc, which is still based on gcc-2.95.3. See http://prc-tools.sourceforge.net. I know this gcc version is very old, but I believe the problem may also exist for other compilers. When compiling normal C code by g++ it produces mangled function names. The coff symbol reader first reads the function name and inserts this in the minimal symbol table and in a demangled name hash table in symtab_set_names(). When reading the '.bf' symbol the function name is inserted in the real symbol table. This time the symbol is already in the hash table in symtab_set_names() and symbol_find_demangled_name() is not called. A side effect of symbol_find_demangled_name() is that it changes/corrects the gsymbol->language field. In the case of 'C compiled by g++' it changes it from language_auto to language_cplus. Because symbol_find_demangled_name() is not called, the gsymbol->language field in the full symbol table stays set to language_auto. This causes all kinds of problems when looking up symbols later, since the stored name is the mangled name and the demangled name is empty: the symbol is not found in the full symbol table and the code falls back on the minimal symbol table or e.g. function names. When trying to set a breakpoint on a function, the breakpoint is then set on the last line of the preceding function. I have applied the following fix to ensure that symbol_find_demangled_name() is also called in this case. It is working for me. I do not know if something else is needed for other languages/compilers/compiler versions. The patch below is against the 6.2 code. =============================================================================== --- symtab.c.orig 2004-07-08 07:18:27.000000000 -0400 +++ symtab.c 2004-08-12 19:13:12.920308800 -0400 @@ -524,6 +524,7 @@ symbol_set_names (struct general_symbol_ const char *lookup_name; /* The length of lookup_name. */ int lookup_len; + char *demangled_name = NULL; if (objfile->demangled_names_hash == NULL) create_demangled_names_hash (objfile); @@ -569,9 +570,10 @@ symbol_set_names (struct general_symbol_ /* If this name is not in the hash table, add it. */ if (*slot == NULL) { - char *demangled_name = symbol_find_demangled_name (gsymbol, - linkage_name_copy); - int demangled_len = demangled_name ? strlen (demangled_name) : 0; + int demangled_len; + + demangled_name = symbol_find_demangled_name (gsymbol, linkage_name_copy); + 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 @@ -582,7 +584,6 @@ symbol_set_names (struct general_symbol_ if (demangled_name != NULL) { memcpy (*slot + lookup_len + 1, demangled_name, demangled_len + 1); - xfree (demangled_name); } else (*slot)[lookup_len + 1] = '\0'; @@ -590,10 +591,20 @@ symbol_set_names (struct general_symbol_ gsymbol->name = *slot + lookup_len - len; if ((*slot)[lookup_len + 1] != '\0') - gsymbol->language_specific.cplus_specific.demangled_name - = &(*slot)[lookup_len + 1]; + { + gsymbol->language_specific.cplus_specific.demangled_name + = &(*slot)[lookup_len + 1]; + /* In case we found the demangled name in the hash table we still have + to call SYMBOL_FIND_DEMANGLED_NAME in order to set the + gsymbol->language field correctly. */ + if (demangled_name == NULL) + demangled_name = symbol_find_demangled_name (gsymbol, + linkage_name_copy); + } else gsymbol->language_specific.cplus_specific.demangled_name = NULL; + + if (demangled_name != NULL) xfree (demangled_name); } /* Initialize the demangled name of GSYMBOL if possible. Any required space =============================================================================== Please let me know if I should submit this as a PR and/or if there is a better fix for this problem. Ton van Overbeek