diff options
Diffstat (limited to 'libjava/gnu/gcj/runtime')
-rw-r--r-- | libjava/gnu/gcj/runtime/NameFinder.java | 20 | ||||
-rw-r--r-- | libjava/gnu/gcj/runtime/natNameFinder.cc | 33 |
2 files changed, 53 insertions, 0 deletions
diff --git a/libjava/gnu/gcj/runtime/NameFinder.java b/libjava/gnu/gcj/runtime/NameFinder.java index 4089411..19820c1 100644 --- a/libjava/gnu/gcj/runtime/NameFinder.java +++ b/libjava/gnu/gcj/runtime/NameFinder.java @@ -103,6 +103,11 @@ public class NameFinder private BufferedReader addr2lineIn; /** + * 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. */ @@ -142,6 +147,7 @@ public class NameFinder { String[] exec = new String[] {"addr2name.awk", executable}; addr2line = runtime.exec(exec); + usingAddr2name = true; } catch (IOException ioe2) { addr2line = null; } } @@ -181,6 +187,11 @@ public class NameFinder native private String getAddrAsString(RawData addrs, int n); /** + * 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. */ @@ -212,6 +223,15 @@ public class NameFinder addr2lineOut.flush(); 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; } } diff --git a/libjava/gnu/gcj/runtime/natNameFinder.cc b/libjava/gnu/gcj/runtime/natNameFinder.cc index 29687cb..6605e38 100644 --- a/libjava/gnu/gcj/runtime/natNameFinder.cc +++ b/libjava/gnu/gcj/runtime/natNameFinder.cc @@ -15,6 +15,8 @@ details. */ #include <config.h> +#include <string.h> + #include <gcj/cni.h> #include <jvm.h> #include <java/lang/String.h> @@ -28,6 +30,37 @@ details. */ #include <dlfcn.h> #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) { |