summaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c100
1 files changed, 75 insertions, 25 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 173d08a48f9..e144197d606 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -484,61 +484,111 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
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. */
+/* Set both the mangled and demangled (if any) names for GSYMBOL based
+ on LINKAGE_NAME and LEN. The hash table corresponding to OBJFILE
+ is used, and the memory comes from that objfile's symbol_obstack.
+ LINKAGE_NAME is copied, so the pointer can be discarded after
+ calling this function. */
+
+/* We have to be careful when dealing with Java names: when we run
+ into a Java minimal symbol, we don't know it's a Java symbol, so it
+ gets demangled as a C++ name. This is unfortunate, but there's not
+ much we can do about it: but when demangling partial symbols and
+ regular symbols, we'd better not reuse the wrong demangled name.
+ (See PR gdb/1039.) We solve this by putting a distinctive prefix
+ on Java names when storing them in the hash table. */
+
+/* FIXME: carlton/2003-03-13: This is an unfortunate situation. I
+ don't mind the Java prefix so much: different languages have
+ different demangling requirements, so it's only natural that we
+ need to keep language data around in our demangling cache. But
+ it's not good that the minimal symbol has the wrong demangled name.
+ Unfortunately, I can't think of any easy solution to that
+ problem. */
+
+#define JAVA_PREFIX "##JAVA$$"
+#define JAVA_PREFIX_LEN 8
void
symbol_set_names (struct general_symbol_info *gsymbol,
- const char *name, int len, struct objfile *objfile)
+ const char *linkage_name, int len, struct objfile *objfile)
{
char **slot;
- const char *tmpname;
+ /* A 0-terminated copy of the linkage name. */
+ const char *linkage_name_copy;
+ /* A copy of the linkage name that might have a special Java prefix
+ added to it, for use when looking names up in the hash table. */
+ const char *lookup_name;
+ /* The length of lookup_name. */
+ int lookup_len;
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)
+ /* The stabs reader generally provides names that are not
+ NUL-terminated; most of the other readers don't do this, so we
+ can just use the given copy, unless we're in the Java case. */
+ if (gsymbol->language == language_java)
+ {
+ char *alloc_name;
+ lookup_len = len + JAVA_PREFIX_LEN;
+
+ alloc_name = alloca (lookup_len + 1);
+ memcpy (alloc_name, JAVA_PREFIX, JAVA_PREFIX_LEN);
+ memcpy (alloc_name + JAVA_PREFIX_LEN, linkage_name, len);
+ alloc_name[lookup_len] = '\0';
+
+ lookup_name = alloc_name;
+ linkage_name_copy = alloc_name + JAVA_PREFIX_LEN;
+ }
+ else if (linkage_name[len] != '\0')
{
- char *alloc_name = alloca (len + 1);
- memcpy (alloc_name, name, len);
- alloc_name[len] = 0;
- tmpname = alloc_name;
+ char *alloc_name;
+ lookup_len = len;
+
+ alloc_name = alloca (lookup_len + 1);
+ memcpy (alloc_name, linkage_name, len);
+ alloc_name[lookup_len] = '\0';
+
+ lookup_name = alloc_name;
+ linkage_name_copy = alloc_name;
}
else
- tmpname = name;
+ {
+ lookup_len = len;
+ lookup_name = linkage_name;
+ linkage_name_copy = linkage_name;
+ }
- slot = (char **) htab_find_slot (objfile->demangled_names_hash, tmpname, INSERT);
+ slot = (char **) htab_find_slot (objfile->demangled_names_hash,
+ lookup_name, INSERT);
/* If this name is not in the hash table, add it. */
if (*slot == NULL)
{
- char *demangled_name = symbol_find_demangled_name (gsymbol, tmpname);
+ char *demangled_name = symbol_find_demangled_name (gsymbol,
+ linkage_name_copy);
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)
+ lookup_len + demangled_len + 2);
+ memcpy (*slot, lookup_name, lookup_len + 1);
+ if (demangled_name != NULL)
{
- memcpy (*slot + len + 1, demangled_name, demangled_len + 1);
+ memcpy (*slot + lookup_len + 1, demangled_name, demangled_len + 1);
xfree (demangled_name);
}
else
- (*slot)[len + 1] = 0;
+ (*slot)[lookup_len + 1] = '\0';
}
- gsymbol->name = *slot;
- if ((*slot)[len + 1])
+ gsymbol->name = *slot + lookup_len - len;
+ if ((*slot)[lookup_len + 1] != '\0')
gsymbol->language_specific.cplus_specific.demangled_name
- = &(*slot)[len + 1];
+ = &(*slot)[lookup_len + 1];
else
gsymbol->language_specific.cplus_specific.demangled_name = NULL;
}