// natNameFinder.cc - native helper methods for NameFinder.java

/* Copyright (C) 2002, 2003, 2004  Free Software Foundation, Inc

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

/**
 * @author Mark Wielaard (mark@klomp.org)
 * Based on the old name-finder.cc by Andrew Haley <aph@cygnus.com>.
 */

#include <config.h>

#include <string.h>

#include <gcj/cni.h>
#include <jvm.h>
#include <java/lang/String.h>
#include <java/lang/StackTraceElement.h>
#include <java/lang/StringBuffer.h>
#include <java-interp.h>

#include <gnu/gcj/runtime/NameFinder.h>

#ifdef HAVE_DLFCN_H
#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::StackTraceElement*
gnu::gcj::runtime::NameFinder::newElement (java::lang::String* fileName,
                                           jint lineNumber,
                                           java::lang::String* className,
                                           java::lang::String* methName,
                                           jboolean isNative)
{
  return new java::lang::StackTraceElement( fileName, lineNumber,
                                            className, methName, isNative);
}
                                          
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, name->length(), newName + pfxLen);
  *(newName + pfxLen + nameLen) = '\0';
  return JvNewStringLatin1 (newName);
}

java::lang::String*
gnu::gcj::runtime::NameFinder::getExecutable (void)
{
  return JvNewStringLatin1 (_Jv_ThisExecutable ());
}

java::lang::String*
gnu::gcj::runtime::NameFinder::getAddrAsString(RawData* addrs, jint n)
{
  _Jv_frame_info *p = (_Jv_frame_info *) addrs;
  typedef unsigned word_t __attribute ((mode (word)));
  word_t w = (word_t) p[n].addr;
  int digits = sizeof (void *) * 2;
  char hex[digits+5];

  strcpy (hex, "0x");
  for (int i = digits - 1; i >= 0; i--)
    {
      int digit = w % 16;

      w /= 16;
      hex[i+2] = digit > 9 ? 'a' + digit - 10 : '0' + digit;
    }
  hex [digits+2] = 0;

  return JvNewStringLatin1(hex);
}

java::lang::StackTraceElement*
gnu::gcj::runtime::NameFinder::dladdrLookup(RawData* addrs, jint n)
{
#if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
  extern char **_Jv_argv;
  char name[1024];
  char file_name[1024];
  _Jv_frame_info *stack = (_Jv_frame_info *) addrs;
  void* p = stack[n].addr;
  Dl_info dl_info;
   
  if (dladdr (p, &dl_info))
    {
      if (dl_info.dli_fname)
        strncpy (file_name, dl_info.dli_fname, sizeof file_name);
      if (dl_info.dli_sname)
        strncpy (name, dl_info.dli_sname, sizeof name);
     
     /* Don't trust dladdr() if the address is from the main program. */
     if (dl_info.dli_fname != NULL
         && dl_info.dli_sname != NULL
         && (_Jv_argv == NULL || strcmp (file_name, _Jv_argv[0]) != 0))
       return createStackTraceElement (JvNewStringLatin1 (name),
				       JvNewStringLatin1 (file_name));
    }
#endif
  return NULL;
}

java::lang::StackTraceElement *
gnu::gcj::runtime::NameFinder::lookupInterp(RawData* addrs, jint n)
{
#ifdef INTERPRETER
  _Jv_frame_info *stack = (_Jv_frame_info *) addrs;
  if (stack[n].interp == NULL)
    return NULL;

  _Jv_InterpMethod *meth
    = reinterpret_cast<_Jv_InterpMethod *> (stack[n].interp);
  java::lang::StringBuffer *sb = new java::lang::StringBuffer();
  sb->append(_Jv_NewStringUtf8Const(meth->self->name));
  sb->append(_Jv_NewStringUtf8Const(meth->self->signature));
  // FIXME: source file name and line number can be found from
  // bytecode debug information.  But currently we don't keep that
  // around.
  // FIXME: is using the defining class correct here?
  java::lang::String *className = meth->defining_class->getName();
  java::lang::String *methodName
	  = demangleInterpreterMethod(sb->toString(), className);
  return new java::lang::StackTraceElement(NULL, -1,
					   className, methodName, false);
#else // INTERPRETER
  return NULL;
#endif // INTERPRETER
}
