Patch: Improve demangling w.r.t. possible underscore prefix

Ranjit Mathew rmathew@hotmail.com
Mon Feb 17 19:24:00 GMT 2003


Andrew Haley wrote:
> Ranjit Mathew writes:
>  > >Why can't you just cat __USER_LABEL_PREFIX__ to the start of the name?
>  > >Surround the whole thing by #ifdef __USER_LABEL_PREFIX__.
>  >
>  > By "cat" if you mean the "##" preprocessor operator, it does not work.
> 
> No, I mean that you can stringify __USER_LABEL_PREFIX__ by using the #
> token.
...
> I haven't tested this, but you get the idea.  It doesn't use gotos or
> onstruct special symbols and it's won't break if ever
> __USER_LABEL_PREFIX__ is "$" or somesuch.

Ok, the following is a patch based on your idea - tested on 3.3/MinGW,
would request someone to test on some other platform.

Index: ChangeLog
from  Ranjit Mathew  <rmathew@hotmail.com>

	* gnu/gcj/runtime/NameFinder.java (usingAddr2name): New flag
	that is set if we are using addr2name.awk instead of addr2line.
	(NameFinder): Set usingAddr2name if using addr2name.awk.
	(getExternalLabel): New native method to convert a method 
	name to an external label.
	(lookup): Convert name given by addr2line to an external label
	before demangling.

	* gnu/gcj/runtime/natNameFinder.cc (LABEL_PREFIX): New string
	constant representing the prefix attached to method names to
	convert them to an external label.
	(gnu::gcj::runtime::NameFinder::getExternalLabel): Define 
	using LABEL_PREFIX.

Index: gnu/gcj/runtime/NameFinder.java
===================================================================
--- gnu/gcj/runtime/NameFinder.java	2003-02-13 00:14:40.000000000 +0530
+++ gnu/gcj/runtime/NameFinder.java	2003-02-18 00:19:36.000000000 +0530
@@ -104,4 +104,9 @@
 
   /**
+   * Flag set if using addr2name.awk instead of addr2line from binutils.
+   */
+  private boolean usingAddr2name = false;
+
+  /**
    * Creates a new NameFinder. Call close to get rid of any resources
    * created while using the <code>lookup</code> methods.
@@ -143,4 +148,5 @@
 		String[] exec = new String[] {"addr2name.awk", executable};
 		addr2line = runtime.exec(exec);
+		usingAddr2name = true;
 	      }
 	    catch (IOException ioe2) { addr2line = null; }
@@ -182,4 +188,9 @@
 
   /**
+   * Returns the label that is exported for the given method name.
+   */
+  native private String getExternalLabel(String name);
+
+  /**
    * If nth element of stack is an interpreted frame, return the
    * element representing the method being interpreted.
@@ -213,4 +224,13 @@
 		name = addr2lineIn.readLine();
 		file = addr2lineIn.readLine();
+
+                // addr2line uses symbolic debugging information instead
+                // of the actually exported labels as addr2name.awk does.
+                // This name might need some modification, depending on 
+                // the system, to make it a label like that returned 
+                // by addr2name.awk or dladdr.
+                if (! usingAddr2name)
+                  if (name != null && ! "??".equals (name))
+                    name = getExternalLabel (name);
 	      }
 	    catch (IOException ioe) { addr2line = null; }
Index: gnu/gcj/runtime/natNameFinder.cc
===================================================================
--- gnu/gcj/runtime/natNameFinder.cc	2003-02-16 13:57:19.000000000 +0530
+++ gnu/gcj/runtime/natNameFinder.cc	2003-02-18 00:24:55.000000000 +0530
@@ -16,4 +16,6 @@
 #include <config.h>
 
+#include <string.h>
+
 #include <gcj/cni.h>
 #include <jvm.h>
@@ -29,4 +31,35 @@
 #endif
 
+// On some systems, a prefix is attached to a method name before
+// it is exported as a label. The GCC preprocessor predefines 
+// this prefix as the macro __USER_LABEL_PREFIX__ which expands to
+// a string (not string constant) representing the prefix, if any.
+#undef LABEL_PREFIX
+#ifdef __USER_LABEL_PREFIX__
+
+#define USER_LABEL_PREFIX_STRING_0(s) #s
+#define USER_LABEL_PREFIX_STRING(s) USER_LABEL_PREFIX_STRING_0(s)
+
+#define LABEL_PREFIX USER_LABEL_PREFIX_STRING(__USER_LABEL_PREFIX__)
+
+#else /* __USER_LABEL_PREFIX__ */
+
+#define LABEL_PREFIX ""
+
+#endif /* ! __USER_LABEL_PREFIX__ */
+
+java::lang::String*
+gnu::gcj::runtime::NameFinder::getExternalLabel (java::lang::String* name)
+{
+  jsize nameLen = JvGetStringUTFLength (name);
+  jsize pfxLen = strlen (LABEL_PREFIX);
+  char *newName = (char *) JvMalloc (pfxLen + nameLen + 1);
+  *(newName + 0) = '\0';
+  strcpy (newName, LABEL_PREFIX);
+  JvGetStringUTFRegion (name, 0, nameLen, newName + pfxLen);
+  *(newName + pfxLen + nameLen) = '\0';
+  return JvNewStringLatin1 (newName);
+}
+
 java::lang::String*
 gnu::gcj::runtime::NameFinder::getExecutable (void)



More information about the Java mailing list