[PATCH] Fix coff symbol table reading problem for C code compiled by g++

Ton van Overbeek
2004-08-13T00:06:03Z

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