This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [rfa] fix pr java/1039
- From: Elena Zannoni <ezannoni at redhat dot com>
- To: David Carlton <carlton at math dot stanford dot edu>
- Cc: gdb-patches at sources dot redhat dot com, Jim Blandy <jimb at redhat dot com>, Elena Zannoni <ezannoni at redhat dot com>
- Date: Mon, 14 Apr 2003 13:55:21 -0400
- Subject: Re: [rfa] fix pr java/1039
- References: <ro1ptouo72g.fsf@jackfruit.Stanford.EDU>
David Carlton writes:
> The enclosed patch fixes the Java regression mentioned in PR gdb/1039,
> where 'break jmisc.main(java.lang.String[])' stopped working under GCJ
> 3.2. It was broken by the demangled symbols cache, by the following
> chain of events: when creating minimal symbols, you don't know the
> language. So the demangler tries to demangle the linkage name as a
> C++ name, notices that it worked, and sets the minimal symbol to a C++
> symbol. That's unfortunate, but there's not much we can do about it;
> what's really unfortunate, though, is that the resulting inappropriate
> demangled name is cached, so when it comes to partial symbols and
> regular symbols, we reuse the C++ demangled name, even though by then
> we know it's a Java symbol.
>
> It's not at all clear how to fix this well. But here's a patch that
> hacks symbol_set_names to create a separate cache for names of Java
> symbols, so we don't use a non-Java name for Java symbols. It really
> is a hack: it reuses the regular demangled name cache, but when
> looking up Java linkage names in it, it prepends the linkage name by
> ##JAVA$$. (This prefix doesn't actually get added to the linkage
> names of symbols, of course, it's just used to modify the hash table
> lookup.) But it's a localized hack: symbol_set_names has to know
> about it, and nobody else does. I've done a context diff instead of a
> unidiff because I think it's a little easier to read in this case.
>
> Tested on i686-pc-linux-gnu, GCC 3.2, DWARF-2; no new regressions, and
> it fixes an existing regression. This or some other way of solving
> the problem should definitely go in before 5.4 is released. OK to
> apply?
>
Yes, but...
could you do it in 2 passes? First pass with the format changes and the
variables renaming. Second pass with the actual juicy Java fixes.
elena
> David Carlton
> carlton at math dot stanford dot edu
>
> 2003-03-13 David Carlton <carlton at math dot stanford dot edu>
>
> * symtab.c (symbol_set_names): Add prefix when storing Java names
> in hash table. Fix for PR java/1039.
> * symtab.h: Change 'name' argument in declaration of
> symbol_set_names to 'linkage_name'.
> (SYMBOL_SET_NAMES): Change 'name' argument to 'linkage_name'.
>
> Index: symtab.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/symtab.c,v
> retrieving revision 1.99
> diff -u -p -c -p -r1.99 symtab.c
> *** symtab.c 4 Mar 2003 17:06:21 -0000 1.99
> --- symtab.c 14 Mar 2003 05:13:43 -0000
> *************** symbol_find_demangled_name (struct gener
> *** 484,544 ****
> 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. */
>
> void
> symbol_set_names (struct general_symbol_info *gsymbol,
> ! const char *name, int len, struct objfile *objfile)
> {
> char **slot;
> ! const char *tmpname;
>
> 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)
> {
> ! char *alloc_name = alloca (len + 1);
> ! memcpy (alloc_name, name, len);
> ! alloc_name[len] = 0;
> ! tmpname = alloc_name;
> }
> else
> ! tmpname = name;
>
> ! slot = (char **) htab_find_slot (objfile->demangled_names_hash, tmpname, INSERT);
>
> /* If this name is not in the hash table, add it. */
> if (*slot == NULL)
> {
> ! char *demangled_name = symbol_find_demangled_name (gsymbol, tmpname);
> 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)
> {
> ! memcpy (*slot + len + 1, demangled_name, demangled_len + 1);
> xfree (demangled_name);
> }
> else
> ! (*slot)[len + 1] = 0;
> }
>
> ! gsymbol->name = *slot;
> ! if ((*slot)[len + 1])
> gsymbol->language_specific.cplus_specific.demangled_name
> ! = &(*slot)[len + 1];
> else
> gsymbol->language_specific.cplus_specific.demangled_name = NULL;
> }
> --- 484,594 ----
> return NULL;
> }
>
> ! /* 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 *linkage_name, int len, struct objfile *objfile)
> {
> char **slot;
> ! /* 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
> ! 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;
> ! 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
> ! {
> ! lookup_len = len;
> ! lookup_name = linkage_name;
> ! linkage_name_copy = linkage_name;
> ! }
>
> ! 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,
> ! 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,
> ! lookup_len + demangled_len + 2);
> ! memcpy (*slot, lookup_name, lookup_len + 1);
> ! if (demangled_name != NULL)
> {
> ! memcpy (*slot + lookup_len + 1, demangled_name, demangled_len + 1);
> xfree (demangled_name);
> }
> else
> ! (*slot)[lookup_len + 1] = '\0';
> }
>
> ! gsymbol->name = *slot + lookup_len - len;
> ! if ((*slot)[lookup_len + 1] != '\0')
> gsymbol->language_specific.cplus_specific.demangled_name
> ! = &(*slot)[lookup_len + 1];
> else
> gsymbol->language_specific.cplus_specific.demangled_name = NULL;
> }
> Index: symtab.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/symtab.h,v
> retrieving revision 1.65
> diff -u -p -r1.65 symtab.h
> --- symtab.h 3 Mar 2003 18:34:12 -0000 1.65
> +++ symtab.h 13 Mar 2003 22:59:05 -0000
> @@ -156,10 +156,10 @@ extern void symbol_init_language_specifi
> extern void symbol_init_demangled_name (struct general_symbol_info *symbol,
> struct obstack *obstack);
>
> -#define SYMBOL_SET_NAMES(symbol,name,len,objfile) \
> - symbol_set_names (&(symbol)->ginfo, name, len, objfile)
> +#define SYMBOL_SET_NAMES(symbol,linkage_name,len,objfile) \
> + symbol_set_names (&(symbol)->ginfo, linkage_name, len, objfile)
> extern void symbol_set_names (struct general_symbol_info *symbol,
> - const char *name, int len,
> + const char *linkage_name, int len,
> struct objfile *objfile);
>
> /* Now come lots of name accessor macros. Short version as to when to