This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[rfa] fix pr java/1039


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?

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]