changeset 10624:035a63c92f39

Merge
author duke
date Wed, 05 Jul 2017 17:52:13 +0200
parents c074b109d708 ead6243ebe4f
children fd9842aaa2b0
files hotspot/agent/src/os/solaris/dbx/Makefile hotspot/agent/src/os/solaris/dbx/README hotspot/agent/src/os/solaris/dbx/README-commands.txt hotspot/agent/src/os/solaris/dbx/helloWorld.cpp hotspot/agent/src/os/solaris/dbx/proc_service_2.h hotspot/agent/src/os/solaris/dbx/shell_imp.h hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.cpp hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.hpp hotspot/agent/src/os/win32/BasicList.hpp hotspot/agent/src/os/win32/Buffer.cpp hotspot/agent/src/os/win32/Buffer.hpp hotspot/agent/src/os/win32/Dispatcher.cpp hotspot/agent/src/os/win32/Dispatcher.hpp hotspot/agent/src/os/win32/Handler.hpp hotspot/agent/src/os/win32/IOBuf.cpp hotspot/agent/src/os/win32/IOBuf.hpp hotspot/agent/src/os/win32/LockableList.hpp hotspot/agent/src/os/win32/Makefile hotspot/agent/src/os/win32/Message.hpp hotspot/agent/src/os/win32/Monitor.cpp hotspot/agent/src/os/win32/Monitor.hpp hotspot/agent/src/os/win32/README-commands.txt hotspot/agent/src/os/win32/README.txt hotspot/agent/src/os/win32/Reaper.cpp hotspot/agent/src/os/win32/Reaper.hpp hotspot/agent/src/os/win32/SwDbgSrv.cpp hotspot/agent/src/os/win32/SwDbgSrv.dsp hotspot/agent/src/os/win32/SwDbgSrv.dsw hotspot/agent/src/os/win32/SwDbgSub.cpp hotspot/agent/src/os/win32/SwDbgSub.dsp hotspot/agent/src/os/win32/initWinsock.cpp hotspot/agent/src/os/win32/initWinsock.hpp hotspot/agent/src/os/win32/ioUtils.cpp hotspot/agent/src/os/win32/ioUtils.hpp hotspot/agent/src/os/win32/isNT4.cpp hotspot/agent/src/os/win32/isNT4.hpp hotspot/agent/src/os/win32/libInfo.cpp hotspot/agent/src/os/win32/libInfo.hpp hotspot/agent/src/os/win32/nt4internals.cpp hotspot/agent/src/os/win32/nt4internals.hpp hotspot/agent/src/os/win32/ports.h hotspot/agent/src/os/win32/procList.cpp hotspot/agent/src/os/win32/procList.hpp hotspot/agent/src/os/win32/serverLists.cpp hotspot/agent/src/os/win32/serverLists.hpp hotspot/agent/src/os/win32/toolHelp.cpp hotspot/agent/src/os/win32/toolHelp.hpp hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxAddress.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxDebugger.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxDebuggerLocal.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxOopHandle.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxThreadFactory.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/sparc/DbxSPARCThread.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/sparc/DbxSPARCThreadContext.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/sparc/DbxSPARCThreadFactory.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/x86/DbxX86Thread.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/x86/DbxX86ThreadContext.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/x86/DbxX86ThreadFactory.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/AddressDataSource.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/DLL.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/TestDebugger.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/TestHelloWorld.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Address.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32CDebugInfoBuilder.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32CDebugger.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Debugger.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32DebuggerLocal.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32LDTEntry.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32LDTEntryConstants.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32OopHandle.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Thread.java hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32ThreadContext.java hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64Frame.java hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64RegisterMap.java hotspot/make/solaris/makefiles/mapfile-vers-nonproduct hotspot/src/share/vm/runtime/reflectionCompat.hpp jdk/src/share/classes/java/util/XMLUtils.java jdk/src/share/classes/sun/tools/jar/JarImageSource.java jdk/src/share/native/sun/awt/libpng/pnggccrd.c jdk/src/share/native/sun/awt/libpng/pngvcrd.c
diffstat 990 files changed, 62733 insertions(+), 42250 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags-top-repo	Thu Sep 29 18:53:49 2011 -0700
+++ b/.hgtags-top-repo	Wed Jul 05 17:52:13 2017 +0200
@@ -128,3 +128,4 @@
 0b66a233bfb9ba2ebda1e5cdfdb0373d6c1e3c69 jdk8-b04
 b910aac18c772b823b1f7da03e2c6528725cc6de jdk8-b05
 28cf2aec4dd7c3c75efc1c15078522467c781a6d jdk8-b06
+0db7ae9f2b1017124c779bccd016c976928859a0 jdk8-b07
--- a/corba/.hgtags	Thu Sep 29 18:53:49 2011 -0700
+++ b/corba/.hgtags	Wed Jul 05 17:52:13 2017 +0200
@@ -128,3 +128,4 @@
 60a68d688e24473cf84dedd1e60901a61ab82555 jdk8-b04
 cc1b599b986a37cb57de4584c5e58169766ca535 jdk8-b05
 45c43dde7ba7f176333a51a98f086275478836fa jdk8-b06
+3d61f0856f349e2163bf98146465dab3b7437f63 jdk8-b07
--- a/hotspot/.hgtags	Thu Sep 29 18:53:49 2011 -0700
+++ b/hotspot/.hgtags	Wed Jul 05 17:52:13 2017 +0200
@@ -180,3 +180,11 @@
 0fa3ace511fe98fe948e751531f3e2b7c60c8376 jdk8-b04
 dce7d24674f4d0bed00de24f00119057fdce7cfb jdk8-b05
 0db80d8e77fccddf5e6fa49963226b54ac7d0f62 jdk8-b06
+3f0cf875af83f55ec5e1a5cea80455315f9322a2 jdk8-b07
+3a2fb61165dfc72e6de2adab1f2649a408f5e577 hs22-b01
+7c29742c41b44fb0cd5a13c7ac8834f3f2ca649e hs22-b02
+3a2fb61165dfc72e398179a2796d740c8da5b8c0 hs22-b03
+ce9bde819dcba4a5d2822229d9183e69c74326ca hs22-b04
+513a84dd0f8b56dc0836b4e0bdd5dd0a778fc634 hs22-b05
+650d15d8f37255d3b805aa00c5bd1c30984b203d hs22-b06
+da883b9e6d3788057f9577e72712998ed82c9b7e hs23-b01
--- a/hotspot/agent/make/Makefile	Thu Sep 29 18:53:49 2011 -0700
+++ b/hotspot/agent/make/Makefile	Wed Jul 05 17:52:13 2017 +0200
@@ -48,17 +48,18 @@
 sun.jvm.hotspot.bugspot \
 sun.jvm.hotspot.bugspot.tree \
 sun.jvm.hotspot.c1 \
+sun.jvm.hotspot.ci \
 sun.jvm.hotspot.code \
 sun.jvm.hotspot.compiler \
 sun.jvm.hotspot.debugger \
 sun.jvm.hotspot.debugger.amd64 \
+sun.jvm.hotspot.debugger.bsd \
+sun.jvm.hotspot.debugger.bsd.amd64 \
+sun.jvm.hotspot.debugger.bsd.x86 \
 sun.jvm.hotspot.debugger.cdbg \
 sun.jvm.hotspot.debugger.cdbg.basic \
 sun.jvm.hotspot.debugger.cdbg.basic.amd64 \
 sun.jvm.hotspot.debugger.cdbg.basic.x86 \
-sun.jvm.hotspot.debugger.dbx \
-sun.jvm.hotspot.debugger.dbx.sparc \
-sun.jvm.hotspot.debugger.dbx.x86 \
 sun.jvm.hotspot.debugger.dummy \
 sun.jvm.hotspot.debugger.ia64 \
 sun.jvm.hotspot.debugger.linux \
@@ -76,7 +77,6 @@
 sun.jvm.hotspot.debugger.remote.sparc \
 sun.jvm.hotspot.debugger.remote.x86 \
 sun.jvm.hotspot.debugger.sparc \
-sun.jvm.hotspot.debugger.win32 \
 sun.jvm.hotspot.debugger.win32.coff \
 sun.jvm.hotspot.debugger.windbg \
 sun.jvm.hotspot.debugger.windbg.amd64 \
@@ -91,9 +91,14 @@
 sun.jvm.hotspot.jdi \
 sun.jvm.hotspot.livejvm \
 sun.jvm.hotspot.memory \
+sun.jvm.hotspot.opto \
 sun.jvm.hotspot.oops \
+sun.jvm.hotspot.prims \
 sun.jvm.hotspot.runtime \
 sun.jvm.hotspot.runtime.amd64 \
+sun.jvm.hotspot.runtime.bsd \
+sun.jvm.hotspot.runtime.bsd_amd64 \
+sun.jvm.hotspot.runtime.bsd_x86 \
 sun.jvm.hotspot.runtime.ia64 \
 sun.jvm.hotspot.runtime.linux \
 sun.jvm.hotspot.runtime.linux_amd64 \
@@ -139,17 +144,18 @@
 sun/jvm/hotspot/bugspot/*.java \
 sun/jvm/hotspot/bugspot/tree/*.java \
 sun/jvm/hotspot/c1/*.java \
+sun/jvm/hotspot/ci/*.java \
 sun/jvm/hotspot/code/*.java \
 sun/jvm/hotspot/compiler/*.java \
 sun/jvm/hotspot/debugger/*.java \
 sun/jvm/hotspot/debugger/amd64/*.java \
+sun/jvm/hotspot/debugger/bsd/*.java \
+sun/jvm/hotspot/debugger/bsd/amd64/*.java \
+sun/jvm/hotspot/debugger/bsd/x86/*.java \
 sun/jvm/hotspot/debugger/cdbg/*.java \
 sun/jvm/hotspot/debugger/cdbg/basic/*.java \
 sun/jvm/hotspot/debugger/cdbg/basic/amd64/*.java \
 sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \
-sun/jvm/hotspot/debugger/dbx/*.java \
-sun/jvm/hotspot/debugger/dbx/sparc/*.java \
-sun/jvm/hotspot/debugger/dbx/x86/*.java \
 sun/jvm/hotspot/debugger/dummy/*.java \
 sun/jvm/hotspot/debugger/ia64/*.java \
 sun/jvm/hotspot/debugger/linux/*.java \
@@ -165,7 +171,6 @@
 sun/jvm/hotspot/debugger/remote/sparc/*.java \
 sun/jvm/hotspot/debugger/remote/x86/*.java \
 sun/jvm/hotspot/debugger/sparc/*.java \
-sun/jvm/hotspot/debugger/win32/*.java \
 sun/jvm/hotspot/debugger/win32/coff/*.java \
 sun/jvm/hotspot/debugger/windbg/*.java \
 sun/jvm/hotspot/debugger/windbg/ia64/*.java \
@@ -176,8 +181,13 @@
 sun/jvm/hotspot/livejvm/*.java \
 sun/jvm/hotspot/memory/*.java \
 sun/jvm/hotspot/oops/*.java \
+sun/jvm/hotspot/opto/*.java \
+sun/jvm/hotspot/prims/*.java \
 sun/jvm/hotspot/runtime/*.java \
 sun/jvm/hotspot/runtime/amd64/*.java \
+sun/jvm/hotspot/runtime/bsd/*.java \
+sun/jvm/hotspot/runtime/bsd_amd64/*.java \
+sun/jvm/hotspot/runtime/bsd_x86/*.java \
 sun/jvm/hotspot/runtime/ia64/*.java \
 sun/jvm/hotspot/runtime/linux/*.java \
 sun/jvm/hotspot/runtime/linux_amd64/*.java \
--- a/hotspot/agent/make/saenv.sh	Thu Sep 29 18:53:49 2011 -0700
+++ b/hotspot/agent/make/saenv.sh	Wed Jul 05 17:52:13 2017 +0200
@@ -70,6 +70,14 @@
 
 SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/js.jar
 
+if [ ! -z "$SA_TYPEDB" ]; then
+  if [ ! -f $SA_TYPEDB ]; then
+    echo "$SA_TYPEDB is unreadable"
+    exit 1
+  fi
+  OPTIONS="-Dsun.jvm.hotspot.typedb=$SA_TYPEDB ${OPTIONS}"
+fi
+
 OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}"
 
 SA_JAVA_CMD="$SA_PREFIX_CMD $SA_JAVA -showversion ${OPTIONS} -cp $SA_CLASSPATH $SA_OPTIONS"
--- a/hotspot/agent/make/saenv64.sh	Thu Sep 29 18:53:49 2011 -0700
+++ b/hotspot/agent/make/saenv64.sh	Wed Jul 05 17:52:13 2017 +0200
@@ -67,6 +67,14 @@
 
 SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar::$STARTDIR/lib/js.jar
 
+if [ ! -z "$SA_TYPEDB" ]; then
+  if [ ! -f $SA_TYPEDB ]; then
+    echo "$SA_TYPEDB is unreadable"
+    exit 1
+  fi
+  OPTIONS="-Dsun.jvm.hotspot.typedb=$SA_TYPEDB ${OPTIONS}"
+fi
+
 OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}"
 
 SA_JAVA_CMD="$SA_PREFIX_CMD $SA_JAVA -d64 -showversion ${OPTIONS} -cp $SA_CLASSPATH $SA_OPTIONS"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/BsdDebuggerLocal.c	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <stdlib.h>
+#include <jni.h>
+#include "libproc.h"
+
+#if defined(x86_64) && !defined(amd64)
+#define amd64 1
+#endif
+
+#ifdef i386
+#include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"
+#endif
+
+#ifdef amd64
+#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
+#endif
+
+#if defined(sparc) || defined(sparcv9)
+#include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"
+#endif
+
+static jfieldID p_ps_prochandle_ID = 0;
+static jfieldID threadList_ID = 0;
+static jfieldID loadObjectList_ID = 0;
+
+static jmethodID createClosestSymbol_ID = 0;
+static jmethodID createLoadObject_ID = 0;
+static jmethodID getThreadForThreadId_ID = 0;
+static jmethodID listAdd_ID = 0;
+
+#define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }
+#define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}
+#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
+#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
+
+static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
+  (*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
+}
+
+static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
+  jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);
+  return (struct ps_prochandle*)(intptr_t)ptr;
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    init0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0
+  (JNIEnv *env, jclass cls) {
+  jclass listClass;
+
+  if (init_libproc(getenv("LIBSAPROC_DEBUG") != NULL) != true) {
+     THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");
+  }
+
+  // fields we use
+  p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J");
+  CHECK_EXCEPTION;
+  threadList_ID = (*env)->GetFieldID(env, cls, "threadList", "Ljava/util/List;");
+  CHECK_EXCEPTION;
+  loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;");
+  CHECK_EXCEPTION;
+
+  // methods we use
+  createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol",
+                    "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");
+  CHECK_EXCEPTION;
+  createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject",
+                    "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");
+  CHECK_EXCEPTION;
+  getThreadForThreadId_ID = (*env)->GetMethodID(env, cls, "getThreadForThreadId",
+                                                     "(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");
+  CHECK_EXCEPTION;
+  // java.util.List method we call
+  listClass = (*env)->FindClass(env, "java/util/List");
+  CHECK_EXCEPTION;
+  listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z");
+  CHECK_EXCEPTION;
+}
+
+JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize
+  (JNIEnv *env, jclass cls)
+{
+#ifdef _LP64
+ return 8;
+#else
+ return 4;
+#endif
+
+}
+
+
+static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
+  int n = 0, i = 0;
+
+  // add threads
+  n = get_num_threads(ph);
+  for (i = 0; i < n; i++) {
+    jobject thread;
+    jobject threadList;
+    lwpid_t lwpid;
+
+    lwpid = get_lwp_id(ph, i);
+    thread = (*env)->CallObjectMethod(env, this_obj, getThreadForThreadId_ID,
+                                      (jlong)lwpid);
+    CHECK_EXCEPTION;
+    threadList = (*env)->GetObjectField(env, this_obj, threadList_ID);
+    CHECK_EXCEPTION;
+    (*env)->CallBooleanMethod(env, threadList, listAdd_ID, thread);
+    CHECK_EXCEPTION;
+  }
+
+  // add load objects
+  n = get_num_libs(ph);
+  for (i = 0; i < n; i++) {
+     uintptr_t base;
+     const char* name;
+     jobject loadObject;
+     jobject loadObjectList;
+
+     base = get_lib_base(ph, i);
+     name = get_lib_name(ph, i);
+     loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID,
+                                   (*env)->NewStringUTF(env, name), (jlong)0, (jlong)base);
+     CHECK_EXCEPTION;
+     loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID);
+     CHECK_EXCEPTION;
+     (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject);
+     CHECK_EXCEPTION;
+  }
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    attach0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I
+  (JNIEnv *env, jobject this_obj, jint jpid) {
+
+  struct ps_prochandle* ph;
+  if ( (ph = Pgrab(jpid)) == NULL) {
+    THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
+  }
+  (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
+  fillThreadsAndLoadObjects(env, this_obj, ph);
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    attach0
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
+  (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {
+  const char *execName_cstr;
+  const char *coreName_cstr;
+  jboolean isCopy;
+  struct ps_prochandle* ph;
+
+  execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy);
+  CHECK_EXCEPTION;
+  coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);
+  CHECK_EXCEPTION;
+
+  if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {
+    (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
+    (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
+    THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
+  }
+  (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
+  (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
+  (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
+  fillThreadsAndLoadObjects(env, this_obj, ph);
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    detach0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0
+  (JNIEnv *env, jobject this_obj) {
+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+  if (ph != NULL) {
+     Prelease(ph);
+  }
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    lookupByName0
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0
+  (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {
+  const char *objectName_cstr, *symbolName_cstr;
+  jlong addr;
+  jboolean isCopy;
+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+
+  objectName_cstr = NULL;
+  if (objectName != NULL) {
+    objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy);
+    CHECK_EXCEPTION_(0);
+  }
+  symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy);
+  CHECK_EXCEPTION_(0);
+
+  addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr);
+
+  if (objectName_cstr != NULL) {
+    (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr);
+  }
+  (*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr);
+  return addr;
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    lookupByAddress0
+ * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
+ */
+JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0
+  (JNIEnv *env, jobject this_obj, jlong addr) {
+  uintptr_t offset;
+  const char* sym = NULL;
+
+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+  sym = symbol_for_pc(ph, (uintptr_t) addr, &offset);
+  if (sym == NULL) return 0;
+  return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID,
+                          (*env)->NewStringUTF(env, sym), (jlong)offset);
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    readBytesFromProcess0
+ * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0
+  (JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) {
+
+  jboolean isCopy;
+  jbyteArray array;
+  jbyte *bufPtr;
+  ps_err_e err;
+
+  array = (*env)->NewByteArray(env, numBytes);
+  CHECK_EXCEPTION_(0);
+  bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy);
+  CHECK_EXCEPTION_(0);
+
+  err = ps_pread(get_proc_handle(env, this_obj), (psaddr_t) (uintptr_t)addr, bufPtr, numBytes);
+  (*env)->ReleaseByteArrayElements(env, array, bufPtr, 0);
+  return (err == PS_OK)? array : 0;
+}
+
+JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0
+  (JNIEnv *env, jobject this_obj, jint lwp_id) {
+
+  struct reg gregs;
+  jboolean isCopy;
+  jlongArray array;
+  jlong *regs;
+
+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+  if (get_lwp_regs(ph, lwp_id, &gregs) != true) {
+     THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0);
+  }
+
+#undef NPRGREG
+#ifdef i386
+#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
+#endif
+#ifdef ia64
+#define NPRGREG IA64_REG_COUNT
+#endif
+#ifdef amd64
+#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
+#endif
+#if defined(sparc) || defined(sparcv9)
+#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
+#endif
+
+  array = (*env)->NewLongArray(env, NPRGREG);
+  CHECK_EXCEPTION_(0);
+  regs = (*env)->GetLongArrayElements(env, array, &isCopy);
+
+#undef REG_INDEX
+
+#ifdef i386
+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg
+
+  regs[REG_INDEX(GS)]  = (uintptr_t) gregs.r_gs;
+  regs[REG_INDEX(FS)]  = (uintptr_t) gregs.r_fs;
+  regs[REG_INDEX(ES)]  = (uintptr_t) gregs.r_es;
+  regs[REG_INDEX(DS)]  = (uintptr_t) gregs.r_ds;
+  regs[REG_INDEX(EDI)] = (uintptr_t) gregs.r_edi;
+  regs[REG_INDEX(ESI)] = (uintptr_t) gregs.r_esi;
+  regs[REG_INDEX(FP)] = (uintptr_t) gregs.r_ebp;
+  regs[REG_INDEX(SP)] = (uintptr_t) gregs.r_isp;
+  regs[REG_INDEX(EBX)] = (uintptr_t) gregs.r_ebx;
+  regs[REG_INDEX(EDX)] = (uintptr_t) gregs.r_edx;
+  regs[REG_INDEX(ECX)] = (uintptr_t) gregs.r_ecx;
+  regs[REG_INDEX(EAX)] = (uintptr_t) gregs.r_eax;
+  regs[REG_INDEX(PC)] = (uintptr_t) gregs.r_eip;
+  regs[REG_INDEX(CS)]  = (uintptr_t) gregs.r_cs;
+  regs[REG_INDEX(SS)]  = (uintptr_t) gregs.r_ss;
+
+#endif /* i386 */
+
+#if ia64
+  regs = (*env)->GetLongArrayElements(env, array, &isCopy);
+  int i;
+  for (i = 0; i < NPRGREG; i++ ) {
+    regs[i] = 0xDEADDEAD;
+  }
+#endif /* ia64 */
+
+#ifdef amd64
+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
+
+  regs[REG_INDEX(R15)] = gregs.r_r15;
+  regs[REG_INDEX(R14)] = gregs.r_r14;
+  regs[REG_INDEX(R13)] = gregs.r_r13;
+  regs[REG_INDEX(R12)] = gregs.r_r12;
+  regs[REG_INDEX(RBP)] = gregs.r_rbp;
+  regs[REG_INDEX(RBX)] = gregs.r_rbx;
+  regs[REG_INDEX(R11)] = gregs.r_r11;
+  regs[REG_INDEX(R10)] = gregs.r_r10;
+  regs[REG_INDEX(R9)] = gregs.r_r9;
+  regs[REG_INDEX(R8)] = gregs.r_r8;
+  regs[REG_INDEX(RAX)] = gregs.r_rax;
+  regs[REG_INDEX(RCX)] = gregs.r_rcx;
+  regs[REG_INDEX(RDX)] = gregs.r_rdx;
+  regs[REG_INDEX(RSI)] = gregs.r_rsi;
+  regs[REG_INDEX(RDI)] = gregs.r_rdi;
+  regs[REG_INDEX(RIP)] = gregs.r_rip;
+  regs[REG_INDEX(CS)] = gregs.r_cs;
+  regs[REG_INDEX(RSP)] = gregs.r_rsp;
+  regs[REG_INDEX(SS)] = gregs.r_ss;
+//  regs[REG_INDEX(FSBASE)] = gregs.fs_base;
+//  regs[REG_INDEX(GSBASE)] = gregs.gs_base;
+//  regs[REG_INDEX(DS)] = gregs.ds;
+//  regs[REG_INDEX(ES)] = gregs.es;
+//  regs[REG_INDEX(FS)] = gregs.fs;
+//  regs[REG_INDEX(GS)] = gregs.gs;
+
+#endif /* amd64 */
+
+#if defined(sparc) || defined(sparcv9)
+
+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_##reg
+
+#ifdef _LP64
+  regs[REG_INDEX(R_PSR)] = gregs.tstate;
+  regs[REG_INDEX(R_PC)]  = gregs.tpc;
+  regs[REG_INDEX(R_nPC)] = gregs.tnpc;
+  regs[REG_INDEX(R_Y)]   = gregs.y;
+#else
+  regs[REG_INDEX(R_PSR)] = gregs.psr;
+  regs[REG_INDEX(R_PC)]  = gregs.pc;
+  regs[REG_INDEX(R_nPC)] = gregs.npc;
+  regs[REG_INDEX(R_Y)]   = gregs.y;
+#endif
+  regs[REG_INDEX(R_G0)]  =            0 ;
+  regs[REG_INDEX(R_G1)]  = gregs.u_regs[0];
+  regs[REG_INDEX(R_G2)]  = gregs.u_regs[1];
+  regs[REG_INDEX(R_G3)]  = gregs.u_regs[2];
+  regs[REG_INDEX(R_G4)]  = gregs.u_regs[3];
+  regs[REG_INDEX(R_G5)]  = gregs.u_regs[4];
+  regs[REG_INDEX(R_G6)]  = gregs.u_regs[5];
+  regs[REG_INDEX(R_G7)]  = gregs.u_regs[6];
+  regs[REG_INDEX(R_O0)]  = gregs.u_regs[7];
+  regs[REG_INDEX(R_O1)]  = gregs.u_regs[8];
+  regs[REG_INDEX(R_O2)]  = gregs.u_regs[ 9];
+  regs[REG_INDEX(R_O3)]  = gregs.u_regs[10];
+  regs[REG_INDEX(R_O4)]  = gregs.u_regs[11];
+  regs[REG_INDEX(R_O5)]  = gregs.u_regs[12];
+  regs[REG_INDEX(R_O6)]  = gregs.u_regs[13];
+  regs[REG_INDEX(R_O7)]  = gregs.u_regs[14];
+#endif /* sparc */
+
+
+  (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);
+  return array;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/Makefile	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,78 @@
+#
+# Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#  
+#
+
+ARCH := $(shell if ([ `uname -m` = "ia64" ])  ; then echo ia64 ; elif ([ `uname -m` = "amd64" ]) ; then echo amd64; elif ([ `uname -m` = "sparc64" ]) ; then echo sparc; else echo i386 ; fi )
+GCC      = gcc
+
+JAVAH    = ${JAVA_HOME}/bin/javah
+
+SOURCES  = salibelf.c   \
+        symtab.c        \
+	libproc_impl.c  \
+	ps_proc.c       \
+	ps_core.c       \
+	hsearch_r.c     \
+	BsdDebuggerLocal.c
+
+INCLUDES = -I${JAVA_HOME}/include -I${JAVA_HOME}/include/$(shell uname -s | tr "[:upper:]" "[:lower:]")
+
+OBJS     = $(SOURCES:.c=.o)
+
+LIBS     = -lutil -lthread_db
+
+CFLAGS   = -c -fPIC -g -Wall -D_ALLBSD_SOURCE -D_GNU_SOURCE -D$(ARCH) $(INCLUDES)
+
+LIBSA = $(ARCH)/libsaproc.so
+
+all: $(LIBSA)
+
+BsdDebuggerLocal.o: BsdDebuggerLocal.c
+	$(JAVAH) -jni -classpath ../../../../../build/bsd-i586/hotspot/outputdir/bsd_i486_compiler2/generated/saclasses  \
+		sun.jvm.hotspot.debugger.x86.X86ThreadContext \
+		sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
+	$(GCC) $(CFLAGS) $<
+
+.c.obj:
+	$(GCC) $(CFLAGS)
+
+ifndef LDNOMAP
+  LFLAGS_LIBSA = -Xlinker --version-script=mapfile
+endif
+
+$(LIBSA): $(OBJS) mapfile
+	if [ ! -d $(ARCH) ] ; then mkdir $(ARCH) ; fi
+	$(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(OBJS) $(LIBS)
+
+test.o: $(LIBSA) test.c
+	$(GCC) -c -o test.o -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) test.c
+
+test: test.o
+	$(GCC) -o test test.o -L$(ARCH) -lsaproc $(LIBS)
+
+clean:
+	rm -f $(LIBSA)
+	rm -f $(OBJS)
+	rm -f test.o
+	-rmdir $(ARCH)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/StubDebuggerLocal.c	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <stdlib.h>
+#include <jni.h>
+
+#define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }
+#define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}
+#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
+#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
+
+static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
+  (*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    init0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0
+  (JNIEnv *env, jclass cls) {
+}
+
+JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize
+  (JNIEnv *env, jclass cls)
+{
+#ifdef _LP64
+ return 8;
+#else
+ return 4;
+#endif
+
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    attach0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I
+  (JNIEnv *env, jobject this_obj, jint jpid) {
+
+  THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    attach0
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
+  (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {
+  THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    detach0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0
+  (JNIEnv *env, jobject this_obj) {
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    lookupByName0
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0
+  (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {
+  return 0;
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    lookupByAddress0
+ * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
+ */
+JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0
+  (JNIEnv *env, jobject this_obj, jlong addr) {
+  return 0;
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    readBytesFromProcess0
+ * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0
+  (JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) {
+  return 0;
+}
+
+JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0
+  (JNIEnv *env, jobject this_obj, jint lwp_id) {
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/elfmacros.h	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef _ELFMACROS_H_
+#define _ELFMACROS_H_
+
+#define ELF_NHDR        Elf_Note
+
+#if defined(_LP64)
+#define ELF_EHDR        Elf64_Ehdr
+#define ELF_SHDR        Elf64_Shdr
+#define ELF_PHDR        Elf64_Phdr
+#define ELF_SYM         Elf64_Sym
+#define ELF_DYN         Elf64_Dyn
+#define ELF_ADDR        Elf64_Addr
+
+#ifndef ELF_ST_TYPE
+#define ELF_ST_TYPE     ELF64_ST_TYPE
+#endif
+
+#else
+
+#define ELF_EHDR        Elf32_Ehdr
+#define ELF_SHDR        Elf32_Shdr
+#define ELF_PHDR        Elf32_Phdr
+#define ELF_SYM         Elf32_Sym
+#define ELF_DYN         Elf32_Dyn
+#define ELF_ADDR        Elf32_Addr
+
+#ifndef ELF_ST_TYPE
+#define ELF_ST_TYPE     ELF32_ST_TYPE
+#endif
+
+#endif
+
+
+#endif /* _ELFMACROS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/libproc.h	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef _LIBPROC_H_
+#define _LIBPROC_H_
+
+#include <unistd.h>
+#include <stdint.h>
+#include <machine/reg.h>
+#include <proc_service.h>
+
+#if defined(sparc) || defined(sparcv9)
+/*
+  If _LP64 is defined ptrace.h should be taken from /usr/include/asm-sparc64
+  otherwise it should be from /usr/include/asm-sparc
+  These two files define pt_regs structure differently
+*/
+#ifdef _LP64
+#include "asm-sparc64/ptrace.h"
+#else
+#include "asm-sparc/ptrace.h"
+#endif
+
+#endif //sparc or sparcv9
+
+/************************************************************************************
+
+0. This is very minimal subset of Solaris libproc just enough for current application.
+Please note that the bulk of the functionality is from proc_service interface. This
+adds Pgrab__ and some missing stuff. We hide the difference b/w live process and core
+file by this interface.
+
+1. pthread_id is unique. We store this in OSThread::_pthread_id in JVM code.
+
+2. All threads see the same pid when they call getpid().
+We used to save the result of ::getpid() call in OSThread::_thread_id.
+Because gettid returns actual pid of thread (lwp id), this is
+unique again. We therefore use OSThread::_thread_id as unique identifier.
+
+3. There is a unique LWP id under both thread libraries. libthread_db  maps pthread_id
+to its underlying lwp_id under both the thread libraries. thread_info.lwp_id stores
+lwp_id of the thread. The lwp id is nothing but the actual pid of clone'd processes. But
+unfortunately libthread_db does not work very well for core dumps. So, we get pthread_id
+only for processes. For core dumps, we don't use libthread_db at all (like gdb).
+
+4. ptrace operates on this LWP id under both the thread libraries. When we say 'pid' for
+ptrace call, we refer to lwp_id of the thread.
+
+5. for core file, we parse ELF files and read data from them. For processes we  use
+combination of ptrace and /proc calls.
+
+*************************************************************************************/
+
+// This C bool type must be int for compatibility with BSD calls and
+// it would be a mistake to equivalence it to C++ bool on many platforms
+
+typedef int bool;
+#define true  1
+#define false 0
+
+struct ps_prochandle;
+
+// attach to a process
+struct ps_prochandle* Pgrab(pid_t pid);
+
+// attach to a core dump
+struct ps_prochandle* Pgrab_core(const char* execfile, const char* corefile);
+
+// release a process or core
+void Prelease(struct ps_prochandle* ph);
+
+// functions not directly available in Solaris libproc
+
+// initialize libproc (call this only once per app)
+// pass true to make library verbose
+bool init_libproc(bool verbose);
+
+// get number of threads
+int get_num_threads(struct ps_prochandle* ph);
+
+// get lwp_id of n'th thread
+lwpid_t get_lwp_id(struct ps_prochandle* ph, int index);
+
+// get regs for a given lwp
+bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lid, struct reg* regs);
+
+// get number of shared objects
+int get_num_libs(struct ps_prochandle* ph);
+
+// get name of n'th lib
+const char* get_lib_name(struct ps_prochandle* ph, int index);
+
+// get base of lib
+uintptr_t get_lib_base(struct ps_prochandle* ph, int index);
+
+// returns true if given library is found in lib list
+bool find_lib(struct ps_prochandle* ph, const char *lib_name);
+
+// symbol lookup
+uintptr_t lookup_symbol(struct ps_prochandle* ph,  const char* object_name,
+                       const char* sym_name);
+
+// address->nearest symbol lookup. return NULL for no symbol
+const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset);
+
+#endif //__LIBPROC_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/libproc_impl.c	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <thread_db.h>
+#include "libproc_impl.h"
+
+static const char* alt_root = NULL;
+static int alt_root_len = -1;
+
+#define SA_ALTROOT "SA_ALTROOT"
+
+static void init_alt_root() {
+   if (alt_root_len == -1) {
+      alt_root = getenv(SA_ALTROOT);
+      if (alt_root) {
+         alt_root_len = strlen(alt_root);
+      } else {
+         alt_root_len = 0;
+      }
+   }
+}
+
+int pathmap_open(const char* name) {
+   int fd;
+   char alt_path[PATH_MAX + 1];
+
+   init_alt_root();
+   fd = open(name, O_RDONLY);
+   if (fd >= 0) {
+      return fd;
+   }
+
+   if (alt_root_len > 0) {
+      strcpy(alt_path, alt_root);
+      strcat(alt_path, name);
+      fd = open(alt_path, O_RDONLY);
+      if (fd >= 0) {
+         print_debug("path %s substituted for %s\n", alt_path, name);
+         return fd;
+      }
+
+      if (strrchr(name, '/')) {
+         strcpy(alt_path, alt_root);
+         strcat(alt_path, strrchr(name, '/'));
+         fd = open(alt_path, O_RDONLY);
+         if (fd >= 0) {
+            print_debug("path %s substituted for %s\n", alt_path, name);
+            return fd;
+         }
+      }
+   }
+
+   return -1;
+}
+
+static bool _libsaproc_debug;
+
+void print_debug(const char* format,...) {
+   if (_libsaproc_debug) {
+     va_list alist;
+
+     va_start(alist, format);
+     fputs("libsaproc DEBUG: ", stderr);
+     vfprintf(stderr, format, alist);
+     va_end(alist);
+   }
+}
+
+bool is_debug() {
+   return _libsaproc_debug;
+}
+
+// initialize libproc
+bool init_libproc(bool debug) {
+   // init debug mode
+   _libsaproc_debug = debug;
+
+   // initialize the thread_db library
+   if (td_init() != TD_OK) {
+     print_debug("libthread_db's td_init failed\n");
+     return false;
+   }
+
+   return true;
+}
+
+static void destroy_lib_info(struct ps_prochandle* ph) {
+   lib_info* lib = ph->libs;
+   while (lib) {
+     lib_info *next = lib->next;
+     if (lib->symtab) {
+        destroy_symtab(lib->symtab);
+     }
+     free(lib);
+     lib = next;
+   }
+}
+
+static void destroy_thread_info(struct ps_prochandle* ph) {
+   thread_info* thr = ph->threads;
+   while (thr) {
+     thread_info *next = thr->next;
+     free(thr);
+     thr = next;
+   }
+}
+
+// ps_prochandle cleanup
+
+// ps_prochandle cleanup
+void Prelease(struct ps_prochandle* ph) {
+   // do the "derived class" clean-up first
+   ph->ops->release(ph);
+   destroy_lib_info(ph);
+   destroy_thread_info(ph);
+   free(ph);
+}
+
+lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base) {
+   return add_lib_info_fd(ph, libname, -1, base);
+}
+
+lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) {
+   lib_info* newlib;
+
+   if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) {
+      print_debug("can't allocate memory for lib_info\n");
+      return NULL;
+   }
+
+   strncpy(newlib->name, libname, sizeof(newlib->name));
+   newlib->base = base;
+
+   if (fd == -1) {
+      if ( (newlib->fd = pathmap_open(newlib->name)) < 0) {
+         print_debug("can't open shared object %s\n", newlib->name);
+         free(newlib);
+         return NULL;
+      }
+   } else {
+      newlib->fd = fd;
+   }
+
+   // check whether we have got an ELF file. /proc/<pid>/map
+   // gives out all file mappings and not just shared objects
+   if (is_elf_file(newlib->fd) == false) {
+      close(newlib->fd);
+      free(newlib);
+      return NULL;
+   }
+
+   newlib->symtab = build_symtab(newlib->fd);
+   if (newlib->symtab == NULL) {
+      print_debug("symbol table build failed for %s\n", newlib->name);
+   }
+   else {
+      print_debug("built symbol table for %s\n", newlib->name);
+   }
+
+   // even if symbol table building fails, we add the lib_info.
+   // This is because we may need to read from the ELF file for core file
+   // address read functionality. lookup_symbol checks for NULL symtab.
+   if (ph->libs) {
+      ph->lib_tail->next = newlib;
+      ph->lib_tail = newlib;
+   }  else {
+      ph->libs = ph->lib_tail = newlib;
+   }
+   ph->num_libs++;
+
+   return newlib;
+}
+
+// lookup for a specific symbol
+uintptr_t lookup_symbol(struct ps_prochandle* ph,  const char* object_name,
+                       const char* sym_name) {
+   // ignore object_name. search in all libraries
+   // FIXME: what should we do with object_name?? The library names are obtained
+   // by parsing /proc/<pid>/maps, which may not be the same as object_name.
+   // What we need is a utility to map object_name to real file name, something
+   // dlopen() does by looking at LD_LIBRARY_PATH and /etc/ld.so.cache. For
+   // now, we just ignore object_name and do a global search for the symbol.
+
+   lib_info* lib = ph->libs;
+   while (lib) {
+      if (lib->symtab) {
+         uintptr_t res = search_symbol(lib->symtab, lib->base, sym_name, NULL);
+         if (res) return res;
+      }
+      lib = lib->next;
+   }
+
+   print_debug("lookup failed for symbol '%s' in obj '%s'\n",
+                          sym_name, object_name);
+   return (uintptr_t) NULL;
+}
+
+
+const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset) {
+   const char* res = NULL;
+   lib_info* lib = ph->libs;
+   while (lib) {
+      if (lib->symtab && addr >= lib->base) {
+         res = nearest_symbol(lib->symtab, addr - lib->base, poffset);
+         if (res) return res;
+      }
+      lib = lib->next;
+   }
+   return NULL;
+}
+
+// add a thread to ps_prochandle
+thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
+   thread_info* newthr;
+   if ( (newthr = (thread_info*) calloc(1, sizeof(thread_info))) == NULL) {
+      print_debug("can't allocate memory for thread_info\n");
+      return NULL;
+   }
+
+   // initialize thread info
+   newthr->pthread_id = pthread_id;
+   newthr->lwp_id = lwp_id;
+
+   // add new thread to the list
+   newthr->next = ph->threads;
+   ph->threads = newthr;
+   ph->num_threads++;
+   return newthr;
+}
+
+
+// struct used for client data from thread_db callback
+struct thread_db_client_data {
+   struct ps_prochandle* ph;
+   thread_info_callback callback;
+};
+
+// callback function for libthread_db
+static int thread_db_callback(const td_thrhandle_t *th_p, void *data) {
+  struct thread_db_client_data* ptr = (struct thread_db_client_data*) data;
+  td_thrinfo_t ti;
+  td_err_e err;
+
+  memset(&ti, 0, sizeof(ti));
+  err = td_thr_get_info(th_p, &ti);
+  if (err != TD_OK) {
+    print_debug("libthread_db : td_thr_get_info failed, can't get thread info\n");
+    return err;
+  }
+
+  print_debug("thread_db : pthread %d (lwp %d)\n", ti.ti_tid, ti.ti_lid);
+
+  if (ptr->callback(ptr->ph, (pthread_t)ti.ti_tid, ti.ti_lid) != true)
+    return TD_ERR;
+
+  return TD_OK;
+}
+
+// read thread_info using libthread_db
+bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb) {
+  struct thread_db_client_data mydata;
+  td_thragent_t* thread_agent = NULL;
+  if (td_ta_new(ph, &thread_agent) != TD_OK) {
+     print_debug("can't create libthread_db agent\n");
+     return false;
+  }
+
+  mydata.ph = ph;
+  mydata.callback = cb;
+
+  // we use libthread_db iterator to iterate thru list of threads.
+  if (td_ta_thr_iter(thread_agent, thread_db_callback, &mydata,
+                 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
+                 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS) != TD_OK) {
+     td_ta_delete(thread_agent);
+     return false;
+  }
+
+  // delete thread agent
+  td_ta_delete(thread_agent);
+  return true;
+}
+
+
+// get number of threads
+int get_num_threads(struct ps_prochandle* ph) {
+   return ph->num_threads;
+}
+
+// get lwp_id of n'th thread
+lwpid_t get_lwp_id(struct ps_prochandle* ph, int index) {
+   int count = 0;
+   thread_info* thr = ph->threads;
+   while (thr) {
+      if (count == index) {
+         return thr->lwp_id;
+      }
+      count++;
+      thr = thr->next;
+   }
+   return -1;
+}
+
+// get regs for a given lwp
+bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs) {
+  return ph->ops->get_lwp_regs(ph, lwp_id, regs);
+}
+
+// get number of shared objects
+int get_num_libs(struct ps_prochandle* ph) {
+   return ph->num_libs;
+}
+
+// get name of n'th solib
+const char* get_lib_name(struct ps_prochandle* ph, int index) {
+   int count = 0;
+   lib_info* lib = ph->libs;
+   while (lib) {
+      if (count == index) {
+         return lib->name;
+      }
+      count++;
+      lib = lib->next;
+   }
+   return NULL;
+}
+
+// get base address of a lib
+uintptr_t get_lib_base(struct ps_prochandle* ph, int index) {
+   int count = 0;
+   lib_info* lib = ph->libs;
+   while (lib) {
+      if (count == index) {
+         return lib->base;
+      }
+      count++;
+      lib = lib->next;
+   }
+   return (uintptr_t)NULL;
+}
+
+bool find_lib(struct ps_prochandle* ph, const char *lib_name) {
+  lib_info *p = ph->libs;
+  while (p) {
+    if (strcmp(p->name, lib_name) == 0) {
+      return true;
+    }
+    p = p->next;
+  }
+  return false;
+}
+
+//--------------------------------------------------------------------------
+// proc service functions
+
+// ps_pglobal_lookup() looks up the symbol sym_name in the symbol table
+// of the load object object_name in the target process identified by ph.
+// It returns the symbol's value as an address in the target process in
+// *sym_addr.
+
+ps_err_e ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name,
+                    const char *sym_name, psaddr_t *sym_addr) {
+  *sym_addr = (psaddr_t) lookup_symbol(ph, object_name, sym_name);
+  return (*sym_addr ? PS_OK : PS_NOSYM);
+}
+
+// read "size" bytes info "buf" from address "addr"
+ps_err_e ps_pread(struct ps_prochandle *ph, psaddr_t  addr,
+                  void *buf, size_t size) {
+  return ph->ops->p_pread(ph, (uintptr_t) addr, buf, size)? PS_OK: PS_ERR;
+}
+
+// write "size" bytes of data to debuggee at address "addr"
+ps_err_e ps_pwrite(struct ps_prochandle *ph, psaddr_t addr,
+                   const void *buf, size_t size) {
+  return ph->ops->p_pwrite(ph, (uintptr_t)addr, buf, size)? PS_OK: PS_ERR;
+}
+
+// fill in ptrace_lwpinfo for lid
+ps_err_e ps_linfo(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
+  return ph->ops->get_lwp_info(ph, lwp_id, linfo)? PS_OK: PS_ERR;
+}
+
+// needed for when libthread_db is compiled with TD_DEBUG defined
+void
+ps_plog (const char *format, ...)
+{
+  va_list alist;
+
+  va_start(alist, format);
+  vfprintf(stderr, format, alist);
+  va_end(alist);
+}
+
+// ------------------------------------------------------------------------
+// Functions below this point are not yet implemented. They are here only
+// to make the linker happy.
+
+ps_err_e ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lid, const prfpregset_t *fpregs) {
+  print_debug("ps_lsetfpregs not implemented\n");
+  return PS_OK;
+}
+
+ps_err_e ps_lsetregs(struct ps_prochandle *ph, lwpid_t lid, const prgregset_t gregset) {
+  print_debug("ps_lsetregs not implemented\n");
+  return PS_OK;
+}
+
+ps_err_e  ps_lgetfpregs(struct  ps_prochandle  *ph,  lwpid_t lid, prfpregset_t *fpregs) {
+  print_debug("ps_lgetfpregs not implemented\n");
+  return PS_OK;
+}
+
+ps_err_e ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset) {
+  print_debug("ps_lgetfpregs not implemented\n");
+  return PS_OK;
+}
+
+ps_err_e ps_lstop(struct ps_prochandle *ph, lwpid_t lid) {
+  print_debug("ps_lstop not implemented\n");
+  return PS_OK;
+}
+
+ps_err_e ps_pcontinue(struct ps_prochandle *ph) {
+  print_debug("ps_pcontinue not implemented\n");
+  return PS_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/libproc_impl.h	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef _LIBPROC_IMPL_H_
+#define _LIBPROC_IMPL_H_
+
+#include <unistd.h>
+#include <limits.h>
+#include "libproc.h"
+#include "symtab.h"
+
+// data structures in this file mimic those of Solaris 8.0 - libproc's Pcontrol.h
+
+#define BUF_SIZE     (PATH_MAX + NAME_MAX + 1)
+
+// list of shared objects
+typedef struct lib_info {
+  char             name[BUF_SIZE];
+  uintptr_t        base;
+  struct symtab*   symtab;
+  int              fd;        // file descriptor for lib
+  struct lib_info* next;
+} lib_info;
+
+// list of threads
+typedef struct thread_info {
+   lwpid_t                  lwp_id;
+   pthread_t                pthread_id; // not used cores, always -1
+   struct reg               regs;       // not for process, core uses for caching regset
+   struct thread_info*      next;
+} thread_info;
+
+// list of virtual memory maps
+typedef struct map_info {
+   int              fd;       // file descriptor
+   off_t            offset;   // file offset of this mapping
+   uintptr_t        vaddr;    // starting virtual address
+   size_t           memsz;    // size of the mapping
+   struct map_info* next;
+} map_info;
+
+// vtable for ps_prochandle
+typedef struct ps_prochandle_ops {
+   // "derived class" clean-up
+   void (*release)(struct ps_prochandle* ph);
+   // read from debuggee
+   bool (*p_pread)(struct ps_prochandle *ph,
+            uintptr_t addr, char *buf, size_t size);
+   // write into debuggee
+   bool (*p_pwrite)(struct ps_prochandle *ph,
+            uintptr_t addr, const char *buf , size_t size);
+   // get integer regset of a thread
+   bool (*get_lwp_regs)(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs);
+   // get info on thread
+   bool (*get_lwp_info)(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo);
+} ps_prochandle_ops;
+
+// the ps_prochandle
+
+struct core_data {
+   int                core_fd;   // file descriptor of core file
+   int                exec_fd;   // file descriptor of exec file
+   int                interp_fd; // file descriptor of interpreter (ld-elf.so.1)
+   // part of the class sharing workaround
+   int                classes_jsa_fd; // file descriptor of class share archive
+   uintptr_t          dynamic_addr;  // address of dynamic section of a.out
+   uintptr_t          ld_base_addr;  // base address of ld.so
+   size_t             num_maps;  // number of maps.
+   map_info*          maps;      // maps in a linked list
+   // part of the class sharing workaround
+   map_info*          class_share_maps;// class share maps in a linked list
+   map_info**         map_array; // sorted (by vaddr) array of map_info pointers
+};
+
+struct ps_prochandle {
+   ps_prochandle_ops* ops;       // vtable ptr
+   pid_t              pid;
+   int                num_libs;
+   lib_info*          libs;      // head of lib list
+   lib_info*          lib_tail;  // tail of lib list - to append at the end
+   int                num_threads;
+   thread_info*       threads;   // head of thread list
+   struct core_data*  core;      // data only used for core dumps, NULL for process
+};
+
+int pathmap_open(const char* name);
+
+void print_debug(const char* format,...);
+bool is_debug();
+
+typedef bool (*thread_info_callback)(struct ps_prochandle* ph, pthread_t pid, lwpid_t lwpid);
+
+// reads thread info using libthread_db and calls above callback for each thread
+bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb);
+
+// adds a new shared object to lib list, returns NULL on failure
+lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base);
+
+// adds a new shared object to lib list, supply open lib file descriptor as well
+lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd,
+                          uintptr_t base);
+
+// adds a new thread to threads list, returns NULL on failure
+thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id);
+
+// a test for ELF signature without using libelf
+bool is_elf_file(int fd);
+
+#endif //_LIBPROC_IMPL_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/mapfile	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,66 @@
+#
+
+#
+# Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#  
+#
+
+# Define public interface.
+
+SUNWprivate_1.1 {
+        global:
+
+		# native methods of BsdDebuggerLocal class
+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0;
+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize;
+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I;
+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2;
+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0;
+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0;
+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0;
+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0;
+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0;
+	
+		# proc_service.h functions - to be used by libthread_db
+		ps_getpid;
+		ps_pglobal_lookup;
+		ps_pread;
+		ps_pwrite;
+		ps_lsetfpregs;
+		ps_lsetregs;
+		ps_lgetfpregs;
+		ps_lgetregs;
+		ps_lcontinue;
+		ps_lgetxmmregs;
+		ps_lsetxmmregs;
+		ps_lstop;
+		ps_linfo;
+
+                # used by attach test program
+                init_libproc;
+                Pgrab;
+                Pgrab_core;
+                Prelease;
+	
+	local:
+		*;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/ps_core.c	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,1023 @@
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <jni.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <elf.h>
+#include <link.h>
+#include "libproc_impl.h"
+#include "salibelf.h"
+
+// This file has the libproc implementation to read core files.
+// For live processes, refer to ps_proc.c. Portions of this is adapted
+// /modelled after Solaris libproc.so (in particular Pcore.c)
+
+//----------------------------------------------------------------------
+// ps_prochandle cleanup helper functions
+
+// close all file descriptors
+static void close_elf_files(struct ps_prochandle* ph) {
+   lib_info* lib = NULL;
+
+   // close core file descriptor
+   if (ph->core->core_fd >= 0)
+     close(ph->core->core_fd);
+
+   // close exec file descriptor
+   if (ph->core->exec_fd >= 0)
+     close(ph->core->exec_fd);
+
+   // close interp file descriptor
+   if (ph->core->interp_fd >= 0)
+     close(ph->core->interp_fd);
+
+   // close class share archive file
+   if (ph->core->classes_jsa_fd >= 0)
+     close(ph->core->classes_jsa_fd);
+
+   // close all library file descriptors
+   lib = ph->libs;
+   while (lib) {
+      int fd = lib->fd;
+      if (fd >= 0 && fd != ph->core->exec_fd) close(fd);
+      lib = lib->next;
+   }
+}
+
+// clean all map_info stuff
+static void destroy_map_info(struct ps_prochandle* ph) {
+  map_info* map = ph->core->maps;
+  while (map) {
+     map_info* next = map->next;
+     free(map);
+     map = next;
+  }
+
+  if (ph->core->map_array) {
+     free(ph->core->map_array);
+  }
+
+  // Part of the class sharing workaround
+  map = ph->core->class_share_maps;
+  while (map) {
+     map_info* next = map->next;
+     free(map);
+     map = next;
+  }
+}
+
+// ps_prochandle operations
+static void core_release(struct ps_prochandle* ph) {
+   if (ph->core) {
+      close_elf_files(ph);
+      destroy_map_info(ph);
+      free(ph->core);
+   }
+}
+
+static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
+   map_info* map;
+   if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
+      print_debug("can't allocate memory for map_info\n");
+      return NULL;
+   }
+
+   // initialize map
+   map->fd     = fd;
+   map->offset = offset;
+   map->vaddr  = vaddr;
+   map->memsz  = memsz;
+   return map;
+}
+
+// add map info with given fd, offset, vaddr and memsz
+static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
+                             uintptr_t vaddr, size_t memsz) {
+   map_info* map;
+   if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
+      return NULL;
+   }
+
+   // add this to map list
+   map->next  = ph->core->maps;
+   ph->core->maps   = map;
+   ph->core->num_maps++;
+
+   return map;
+}
+
+// Part of the class sharing workaround
+static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
+                             uintptr_t vaddr, size_t memsz) {
+   map_info* map;
+   if ((map = allocate_init_map(ph->core->classes_jsa_fd,
+                                offset, vaddr, memsz)) == NULL) {
+      return NULL;
+   }
+
+   map->next = ph->core->class_share_maps;
+   ph->core->class_share_maps = map;
+   return map;
+}
+
+// Return the map_info for the given virtual address.  We keep a sorted
+// array of pointers in ph->map_array, so we can binary search.
+static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr)
+{
+   int mid, lo = 0, hi = ph->core->num_maps - 1;
+   map_info *mp;
+
+   while (hi - lo > 1) {
+     mid = (lo + hi) / 2;
+      if (addr >= ph->core->map_array[mid]->vaddr)
+         lo = mid;
+      else
+         hi = mid;
+   }
+
+   if (addr < ph->core->map_array[hi]->vaddr)
+      mp = ph->core->map_array[lo];
+   else
+      mp = ph->core->map_array[hi];
+
+   if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz)
+      return (mp);
+
+
+   // Part of the class sharing workaround
+   // Unfortunately, we have no way of detecting -Xshare state.
+   // Check out the share maps atlast, if we don't find anywhere.
+   // This is done this way so to avoid reading share pages
+   // ahead of other normal maps. For eg. with -Xshare:off we don't
+   // want to prefer class sharing data to data from core.
+   mp = ph->core->class_share_maps;
+   if (mp) {
+      print_debug("can't locate map_info at 0x%lx, trying class share maps\n",
+             addr);
+   }
+   while (mp) {
+      if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
+         print_debug("located map_info at 0x%lx from class share maps\n",
+                  addr);
+         return (mp);
+      }
+      mp = mp->next;
+   }
+
+   print_debug("can't locate map_info at 0x%lx\n", addr);
+   return (NULL);
+}
+
+//---------------------------------------------------------------
+// Part of the class sharing workaround:
+//
+// With class sharing, pages are mapped from classes[_g].jsa file.
+// The read-only class sharing pages are mapped as MAP_SHARED,
+// PROT_READ pages. These pages are not dumped into core dump.
+// With this workaround, these pages are read from classes[_g].jsa.
+
+// FIXME: !HACK ALERT!
+// The format of sharing achive file header is needed to read shared heap
+// file mappings. For now, I am hard coding portion of FileMapHeader here.
+// Refer to filemap.hpp.
+
+// FileMapHeader describes the shared space data in the file to be
+// mapped.  This structure gets written to a file.  It is not a class,
+// so that the compilers don't add any compiler-private data to it.
+
+// Refer to CompactingPermGenGen::n_regions in compactingPermGenGen.hpp
+#define NUM_SHARED_MAPS 4
+
+// Refer to FileMapInfo::_current_version in filemap.hpp
+#define CURRENT_ARCHIVE_VERSION 1
+
+struct FileMapHeader {
+  int   _magic;              // identify file type.
+  int   _version;            // (from enum, above.)
+  size_t _alignment;         // how shared archive should be aligned
+
+  struct space_info {
+    int    _file_offset;     // sizeof(this) rounded to vm page size
+    char*  _base;            // copy-on-write base address
+    size_t _capacity;        // for validity checking
+    size_t _used;            // for setting space top on read
+
+    // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
+    // the C type matching the C++ bool type on any given platform. For
+    // Hotspot on BSD we assume the corresponding C type is char but
+    // licensees on BSD versions may need to adjust the type of these fields.
+    char   _read_only;       // read only space?
+    char   _allow_exec;      // executable code in space?
+
+  } _space[NUM_SHARED_MAPS]; // was _space[CompactingPermGenGen::n_regions];
+
+  // Ignore the rest of the FileMapHeader. We don't need those fields here.
+};
+
+static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
+   jboolean i;
+   if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
+      *pvalue = i;
+      return true;
+   } else {
+      return false;
+   }
+}
+
+static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
+   uintptr_t uip;
+   if (ps_pread(ph, (psaddr_t) addr, &uip, sizeof(uip)) == PS_OK) {
+      *pvalue = uip;
+      return true;
+   } else {
+      return false;
+   }
+}
+
+// used to read strings from debuggee
+static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
+   size_t i = 0;
+   char  c = ' ';
+
+   while (c != '\0') {
+     if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK)
+         return false;
+      if (i < size - 1)
+         buf[i] = c;
+      else // smaller buffer
+         return false;
+      i++; addr++;
+   }
+
+   buf[i] = '\0';
+   return true;
+}
+
+#define USE_SHARED_SPACES_SYM "UseSharedSpaces"
+// mangled name of Arguments::SharedArchivePath
+#define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
+
+static bool init_classsharing_workaround(struct ps_prochandle* ph) {
+   lib_info* lib = ph->libs;
+   while (lib != NULL) {
+      // we are iterating over shared objects from the core dump. look for
+      // libjvm[_g].so.
+      const char *jvm_name = 0;
+      if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 ||
+          (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0) {
+         char classes_jsa[PATH_MAX];
+         struct FileMapHeader header;
+         size_t n = 0;
+         int fd = -1, m = 0;
+         uintptr_t base = 0, useSharedSpacesAddr = 0;
+         uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
+         jboolean useSharedSpaces = 0;
+
+         memset(classes_jsa, 0, sizeof(classes_jsa));
+         jvm_name = lib->name;
+         useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
+         if (useSharedSpacesAddr == 0) {
+            print_debug("can't lookup 'UseSharedSpaces' flag\n");
+            return false;
+         }
+
+         // Hotspot vm types are not exported to build this library. So
+         // using equivalent type jboolean to read the value of
+         // UseSharedSpaces which is same as hotspot type "bool".
+         if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
+            print_debug("can't read the value of 'UseSharedSpaces' flag\n");
+            return false;
+         }
+
+         if ((int)useSharedSpaces == 0) {
+            print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
+            return true;
+         }
+
+         sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
+         if (sharedArchivePathAddrAddr == 0) {
+            print_debug("can't lookup shared archive path symbol\n");
+            return false;
+         }
+
+         if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
+            print_debug("can't read shared archive path pointer\n");
+            return false;
+         }
+
+         if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
+            print_debug("can't read shared archive path value\n");
+            return false;
+         }
+
+         print_debug("looking for %s\n", classes_jsa);
+         // open the class sharing archive file
+         fd = pathmap_open(classes_jsa);
+         if (fd < 0) {
+            print_debug("can't open %s!\n", classes_jsa);
+            ph->core->classes_jsa_fd = -1;
+            return false;
+         } else {
+            print_debug("opened %s\n", classes_jsa);
+         }
+
+         // read FileMapHeader from the file
+         memset(&header, 0, sizeof(struct FileMapHeader));
+         if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
+              != sizeof(struct FileMapHeader)) {
+            print_debug("can't read shared archive file map header from %s\n", classes_jsa);
+            close(fd);
+            return false;
+         }
+
+         // check file magic
+         if (header._magic != 0xf00baba2) {
+            print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
+                        classes_jsa, header._magic);
+            close(fd);
+            return false;
+         }
+
+         // check version
+         if (header._version != CURRENT_ARCHIVE_VERSION) {
+            print_debug("%s has wrong shared archive file version %d, expecting %d\n",
+                        classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
+            close(fd);
+            return false;
+         }
+
+         ph->core->classes_jsa_fd = fd;
+         // add read-only maps from classes[_g].jsa to the list of maps
+         for (m = 0; m < NUM_SHARED_MAPS; m++) {
+            if (header._space[m]._read_only) {
+               base = (uintptr_t) header._space[m]._base;
+               // no need to worry about the fractional pages at-the-end.
+               // possible fractional pages are handled by core_read_data.
+               add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
+                         base, (size_t) header._space[m]._used);
+               print_debug("added a share archive map at 0x%lx\n", base);
+            }
+         }
+         return true;
+      }
+      lib = lib->next;
+   }
+   return true;
+}
+
+
+//---------------------------------------------------------------------------
+// functions to handle map_info
+
+// Order mappings based on virtual address.  We use this function as the
+// callback for sorting the array of map_info pointers.
+static int core_cmp_mapping(const void *lhsp, const void *rhsp)
+{
+   const map_info *lhs = *((const map_info **)lhsp);
+   const map_info *rhs = *((const map_info **)rhsp);
+
+   if (lhs->vaddr == rhs->vaddr)
+      return (0);
+
+   return (lhs->vaddr < rhs->vaddr ? -1 : 1);
+}
+
+// we sort map_info by starting virtual address so that we can do
+// binary search to read from an address.
+static bool sort_map_array(struct ps_prochandle* ph) {
+   size_t num_maps = ph->core->num_maps;
+   map_info* map = ph->core->maps;
+   int i = 0;
+
+   // allocate map_array
+   map_info** array;
+   if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
+      print_debug("can't allocate memory for map array\n");
+      return false;
+   }
+
+   // add maps to array
+   while (map) {
+      array[i] = map;
+      i++;
+      map = map->next;
+   }
+
+   // sort is called twice. If this is second time, clear map array
+   if (ph->core->map_array) free(ph->core->map_array);
+   ph->core->map_array = array;
+   // sort the map_info array by base virtual address.
+   qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
+            core_cmp_mapping);
+
+   // print map
+   if (is_debug()) {
+      int j = 0;
+      print_debug("---- sorted virtual address map ----\n");
+      for (j = 0; j < ph->core->num_maps; j++) {
+        print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
+                                         ph->core->map_array[j]->memsz);
+      }
+   }
+
+   return true;
+}
+
+#ifndef MIN
+#define MIN(x, y) (((x) < (y))? (x): (y))
+#endif
+
+static bool core_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
+   ssize_t resid = size;
+   int page_size=sysconf(_SC_PAGE_SIZE);
+   while (resid != 0) {
+      map_info *mp = core_lookup(ph, addr);
+      uintptr_t mapoff;
+      ssize_t len, rem;
+      off_t off;
+      int fd;
+
+      if (mp == NULL)
+         break;  /* No mapping for this address */
+
+      fd = mp->fd;
+      mapoff = addr - mp->vaddr;
+      len = MIN(resid, mp->memsz - mapoff);
+      off = mp->offset + mapoff;
+
+      if ((len = pread(fd, buf, len, off)) <= 0)
+         break;
+
+      resid -= len;
+      addr += len;
+      buf = (char *)buf + len;
+
+      // mappings always start at page boundary. But, may end in fractional
+      // page. fill zeros for possible fractional page at the end of a mapping.
+      rem = mp->memsz % page_size;
+      if (rem > 0) {
+         rem = page_size - rem;
+         len = MIN(resid, rem);
+         resid -= len;
+         addr += len;
+         // we are not assuming 'buf' to be zero initialized.
+         memset(buf, 0, len);
+         buf += len;
+      }
+   }
+
+   if (resid) {
+      print_debug("core read failed for %d byte(s) @ 0x%lx (%d more bytes)\n",
+              size, addr, resid);
+      return false;
+   } else {
+      return true;
+   }
+}
+
+// null implementation for write
+static bool core_write_data(struct ps_prochandle* ph,
+                             uintptr_t addr, const char *buf , size_t size) {
+   return false;
+}
+
+static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id,
+                          struct reg* regs) {
+   // for core we have cached the lwp regs from NOTE section
+   thread_info* thr = ph->threads;
+   while (thr) {
+     if (thr->lwp_id == lwp_id) {
+       memcpy(regs, &thr->regs, sizeof(struct reg));
+       return true;
+     }
+     thr = thr->next;
+   }
+   return false;
+}
+
+static bool core_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
+   print_debug("core_get_lwp_info not implemented\n");
+   return false;
+}
+
+static ps_prochandle_ops core_ops = {
+   .release=  core_release,
+   .p_pread=  core_read_data,
+   .p_pwrite= core_write_data,
+   .get_lwp_regs= core_get_lwp_regs,
+   .get_lwp_info= core_get_lwp_info
+};
+
+// read regs and create thread from NT_PRSTATUS entries from core file
+static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size_t nbytes) {
+   // we have to read prstatus_t from buf
+   // assert(nbytes == sizeof(prstaus_t), "size mismatch on prstatus_t");
+   prstatus_t* prstat = (prstatus_t*) buf;
+   thread_info* newthr;
+   print_debug("got integer regset for lwp %d\n", prstat->pr_pid);
+   // we set pthread_t to -1 for core dump
+   if((newthr = add_thread_info(ph, (pthread_t) -1,  prstat->pr_pid)) == NULL)
+      return false;
+
+   // copy regs
+   memcpy(&newthr->regs, &prstat->pr_reg, sizeof(struct reg));
+
+   if (is_debug()) {
+      print_debug("integer regset\n");
+#ifdef i386
+      // print the regset
+      print_debug("\teax = 0x%x\n", newthr->regs.r_eax);
+      print_debug("\tebx = 0x%x\n", newthr->regs.r_ebx);
+      print_debug("\tecx = 0x%x\n", newthr->regs.r_ecx);
+      print_debug("\tedx = 0x%x\n", newthr->regs.r_edx);
+      print_debug("\tesp = 0x%x\n", newthr->regs.r_esp);
+      print_debug("\tebp = 0x%x\n", newthr->regs.r_ebp);
+      print_debug("\tesi = 0x%x\n", newthr->regs.r_esi);
+      print_debug("\tedi = 0x%x\n", newthr->regs.r_edi);
+      print_debug("\teip = 0x%x\n", newthr->regs.r_eip);
+#endif
+
+#if defined(amd64) || defined(x86_64)
+      // print the regset
+      print_debug("\tr15 = 0x%lx\n", newthr->regs.r_r15);
+      print_debug("\tr14 = 0x%lx\n", newthr->regs.r_r14);
+      print_debug("\tr13 = 0x%lx\n", newthr->regs.r_r13);
+      print_debug("\tr12 = 0x%lx\n", newthr->regs.r_r12);
+      print_debug("\trbp = 0x%lx\n", newthr->regs.r_rbp);
+      print_debug("\trbx = 0x%lx\n", newthr->regs.r_rbx);
+      print_debug("\tr11 = 0x%lx\n", newthr->regs.r_r11);
+      print_debug("\tr10 = 0x%lx\n", newthr->regs.r_r10);
+      print_debug("\tr9 = 0x%lx\n", newthr->regs.r_r9);
+      print_debug("\tr8 = 0x%lx\n", newthr->regs.r_r8);
+      print_debug("\trax = 0x%lx\n", newthr->regs.r_rax);
+      print_debug("\trcx = 0x%lx\n", newthr->regs.r_rcx);
+      print_debug("\trdx = 0x%lx\n", newthr->regs.r_rdx);
+      print_debug("\trsi = 0x%lx\n", newthr->regs.r_rsi);
+      print_debug("\trdi = 0x%lx\n", newthr->regs.r_rdi);
+      //print_debug("\torig_rax = 0x%lx\n", newthr->regs.orig_rax);
+      print_debug("\trip = 0x%lx\n", newthr->regs.r_rip);
+      print_debug("\tcs = 0x%lx\n", newthr->regs.r_cs);
+      //print_debug("\teflags = 0x%lx\n", newthr->regs.eflags);
+      print_debug("\trsp = 0x%lx\n", newthr->regs.r_rsp);
+      print_debug("\tss = 0x%lx\n", newthr->regs.r_ss);
+      //print_debug("\tfs_base = 0x%lx\n", newthr->regs.fs_base);
+      //print_debug("\tgs_base = 0x%lx\n", newthr->regs.gs_base);
+      //print_debug("\tds = 0x%lx\n", newthr->regs.ds);
+      //print_debug("\tes = 0x%lx\n", newthr->regs.es);
+      //print_debug("\tfs = 0x%lx\n", newthr->regs.fs);
+      //print_debug("\tgs = 0x%lx\n", newthr->regs.gs);
+#endif
+   }
+
+   return true;
+}
+
+#define ROUNDUP(x, y)  ((((x)+((y)-1))/(y))*(y))
+
+// read NT_PRSTATUS entries from core NOTE segment
+static bool core_handle_note(struct ps_prochandle* ph, ELF_PHDR* note_phdr) {
+   char* buf = NULL;
+   char* p = NULL;
+   size_t size = note_phdr->p_filesz;
+
+   // we are interested in just prstatus entries. we will ignore the rest.
+   // Advance the seek pointer to the start of the PT_NOTE data
+   if (lseek(ph->core->core_fd, note_phdr->p_offset, SEEK_SET) == (off_t)-1) {
+      print_debug("failed to lseek to PT_NOTE data\n");
+      return false;
+   }
+
+   // Now process the PT_NOTE structures.  Each one is preceded by
+   // an Elf{32/64}_Nhdr structure describing its type and size.
+   if ( (buf = (char*) malloc(size)) == NULL) {
+      print_debug("can't allocate memory for reading core notes\n");
+      goto err;
+   }
+
+   // read notes into buffer
+   if (read(ph->core->core_fd, buf, size) != size) {
+      print_debug("failed to read notes, core file must have been truncated\n");
+      goto err;
+   }
+
+   p = buf;
+   while (p < buf + size) {
+      ELF_NHDR* notep = (ELF_NHDR*) p;
+      char* descdata  = p + sizeof(ELF_NHDR) + ROUNDUP(notep->n_namesz, 4);
+      print_debug("Note header with n_type = %d and n_descsz = %u\n",
+                                   notep->n_type, notep->n_descsz);
+
+      if (notep->n_type == NT_PRSTATUS) {
+         if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true)
+            return false;
+      }
+      p = descdata + ROUNDUP(notep->n_descsz, 4);
+   }
+
+   free(buf);
+   return true;
+
+err:
+   if (buf) free(buf);
+   return false;
+}
+
+// read all segments from core file
+static bool read_core_segments(struct ps_prochandle* ph, ELF_EHDR* core_ehdr) {
+   int i = 0;
+   ELF_PHDR* phbuf = NULL;
+   ELF_PHDR* core_php = NULL;
+
+   if ((phbuf =  read_program_header_table(ph->core->core_fd, core_ehdr)) == NULL)
+      return false;
+
+   /*
+    * Now iterate through the program headers in the core file.
+    * We're interested in two types of Phdrs: PT_NOTE (which
+    * contains a set of saved /proc structures), and PT_LOAD (which
+    * represents a memory mapping from the process's address space).
+    *
+    * Difference b/w Solaris PT_NOTE and BSD PT_NOTE:
+    *
+    *     In Solaris there are two PT_NOTE segments the first PT_NOTE (if present)
+    *     contains /proc structs in the pre-2.6 unstructured /proc format. the last
+    *     PT_NOTE has data in new /proc format.
+    *
+    *     In Solaris, there is only one pstatus (process status). pstatus contains
+    *     integer register set among other stuff. For each LWP, we have one lwpstatus
+    *     entry that has integer regset for that LWP.
+    *
+    *     Linux threads are actually 'clone'd processes. To support core analysis
+    *     of "multithreaded" process, Linux creates more than one pstatus (called
+    *     "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
+    *     "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
+    *     function "elf_core_dump".
+    */
+
+    for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
+      switch (core_php->p_type) {
+         case PT_NOTE:
+            if (core_handle_note(ph, core_php) != true) goto err;
+            break;
+
+         case PT_LOAD: {
+            if (core_php->p_filesz != 0) {
+               if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
+                  core_php->p_vaddr, core_php->p_filesz) == NULL) goto err;
+            }
+            break;
+         }
+      }
+
+      core_php++;
+   }
+
+   free(phbuf);
+   return true;
+err:
+   free(phbuf);
+   return false;
+}
+
+// read segments of a shared object
+static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
+   int i = 0;
+   ELF_PHDR* phbuf;
+   ELF_PHDR* lib_php = NULL;
+
+   if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL)
+      return false;
+
+   // we want to process only PT_LOAD segments that are not writable.
+   // i.e., text segments. The read/write/exec (data) segments would
+   // have been already added from core file segments.
+   for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
+      if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
+         if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL)
+            goto err;
+      }
+      lib_php++;
+   }
+
+   free(phbuf);
+   return true;
+err:
+   free(phbuf);
+   return false;
+}
+
+// process segments from interpreter (ld-elf.so.1)
+static bool read_interp_segments(struct ps_prochandle* ph) {
+   ELF_EHDR interp_ehdr;
+
+   if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
+       print_debug("interpreter is not a valid ELF file\n");
+       return false;
+   }
+
+   if (read_lib_segments(ph, ph->core->interp_fd, &interp_ehdr, ph->core->ld_base_addr) != true) {
+       print_debug("can't read segments of interpreter\n");
+       return false;
+   }
+
+   return true;
+}
+
+// process segments of a a.out
+static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
+   int i = 0;
+   ELF_PHDR* phbuf = NULL;
+   ELF_PHDR* exec_php = NULL;
+
+   if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL)
+      return false;
+
+   for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
+      switch (exec_php->p_type) {
+
+         // add mappings for PT_LOAD segments
+         case PT_LOAD: {
+            // add only non-writable segments of non-zero filesz
+            if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
+               if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
+            }
+            break;
+         }
+
+         // read the interpreter and it's segments
+         case PT_INTERP: {
+            char interp_name[BUF_SIZE];
+
+            pread(ph->core->exec_fd, interp_name, MIN(exec_php->p_filesz, BUF_SIZE), exec_php->p_offset);
+            print_debug("ELF interpreter %s\n", interp_name);
+            // read interpreter segments as well
+            if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
+               print_debug("can't open runtime loader\n");
+               goto err;
+            }
+            break;
+         }
+
+         // from PT_DYNAMIC we want to read address of first link_map addr
+         case PT_DYNAMIC: {
+            ph->core->dynamic_addr = exec_php->p_vaddr;
+            print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
+            break;
+         }
+
+      } // switch
+      exec_php++;
+   } // for
+
+   free(phbuf);
+   return true;
+err:
+   free(phbuf);
+   return false;
+}
+
+
+#define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug,  r_map)
+#define LD_BASE_OFFSET        offsetof(struct r_debug,  r_ldbase)
+#define LINK_MAP_ADDR_OFFSET  offsetof(struct link_map, l_addr)
+#define LINK_MAP_NAME_OFFSET  offsetof(struct link_map, l_name)
+#define LINK_MAP_NEXT_OFFSET  offsetof(struct link_map, l_next)
+
+// read shared library info from runtime linker's data structures.
+// This work is done by librtlb_db in Solaris
+static bool read_shared_lib_info(struct ps_prochandle* ph) {
+   uintptr_t addr = ph->core->dynamic_addr;
+   uintptr_t debug_base;
+   uintptr_t first_link_map_addr;
+   uintptr_t ld_base_addr;
+   uintptr_t link_map_addr;
+   uintptr_t lib_base_diff;
+   uintptr_t lib_base;
+   uintptr_t lib_name_addr;
+   char lib_name[BUF_SIZE];
+   ELF_DYN dyn;
+   ELF_EHDR elf_ehdr;
+   int lib_fd;
+
+   // _DYNAMIC has information of the form
+   //         [tag] [data] [tag] [data] .....
+   // Both tag and data are pointer sized.
+   // We look for dynamic info with DT_DEBUG. This has shared object info.
+   // refer to struct r_debug in link.h
+
+   dyn.d_tag = DT_NULL;
+   while (dyn.d_tag != DT_DEBUG) {
+      if (ps_pread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
+         print_debug("can't read debug info from _DYNAMIC\n");
+         return false;
+      }
+      addr += sizeof(ELF_DYN);
+   }
+
+   // we have got Dyn entry with DT_DEBUG
+   debug_base = dyn.d_un.d_ptr;
+   // at debug_base we have struct r_debug. This has first link map in r_map field
+   if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
+                 &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
+      print_debug("can't read first link map address\n");
+      return false;
+   }
+
+   // read ld_base address from struct r_debug
+   // XXX: There is no r_ldbase member on BSD
+/*
+   if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
+                 sizeof(uintptr_t)) != PS_OK) {
+      print_debug("can't read ld base address\n");
+      return false;
+   }
+   ph->core->ld_base_addr = ld_base_addr;
+*/
+   ph->core->ld_base_addr = 0;
+
+   print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
+
+   // now read segments from interp (i.e ld-elf.so.1)
+   if (read_interp_segments(ph) != true)
+      return false;
+
+   // after adding interpreter (ld.so) mappings sort again
+   if (sort_map_array(ph) != true)
+      return false;
+
+   print_debug("first link map is at 0x%lx\n", first_link_map_addr);
+
+   link_map_addr = first_link_map_addr;
+   while (link_map_addr != 0) {
+      // read library base address of the .so. Note that even though <sys/link.h> calls
+      // link_map->l_addr as "base address",  this is * not * really base virtual
+      // address of the shared object. This is actually the difference b/w the virtual
+      // address mentioned in shared object and the actual virtual base where runtime
+      // linker loaded it. We use "base diff" in read_lib_segments call below.
+
+      if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET,
+                   &lib_base_diff, sizeof(uintptr_t)) != PS_OK) {
+         print_debug("can't read shared object base address diff\n");
+         return false;
+      }
+
+      // read address of the name
+      if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET,
+                    &lib_name_addr, sizeof(uintptr_t)) != PS_OK) {
+         print_debug("can't read address of shared object name\n");
+         return false;
+      }
+
+      // read name of the shared object
+      if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) {
+         print_debug("can't read shared object name\n");
+         return false;
+      }
+
+      if (lib_name[0] != '\0') {
+         // ignore empty lib names
+         lib_fd = pathmap_open(lib_name);
+
+         if (lib_fd < 0) {
+            print_debug("can't open shared object %s\n", lib_name);
+            // continue with other libraries...
+         } else {
+            if (read_elf_header(lib_fd, &elf_ehdr)) {
+               lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
+               print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
+                           lib_name, lib_base, lib_base_diff);
+               // while adding library mappings we need to use "base difference".
+               if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {
+                  print_debug("can't read shared object's segments\n");
+                  close(lib_fd);
+                  return false;
+               }
+               add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
+               // Map info is added for the library (lib_name) so
+               // we need to re-sort it before calling the p_pdread.
+               if (sort_map_array(ph) != true)
+                  return false;
+            } else {
+               print_debug("can't read ELF header for shared object %s\n", lib_name);
+               close(lib_fd);
+               // continue with other libraries...
+            }
+         }
+      }
+
+      // read next link_map address
+      if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
+                        &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
+         print_debug("can't read next link in link_map\n");
+         return false;
+      }
+   }
+
+   return true;
+}
+
+// the one and only one exposed stuff from this file
+struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
+   ELF_EHDR core_ehdr;
+   ELF_EHDR exec_ehdr;
+
+   struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
+   if (ph == NULL) {
+      print_debug("can't allocate ps_prochandle\n");
+      return NULL;
+   }
+
+   if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
+      free(ph);
+      print_debug("can't allocate ps_prochandle\n");
+      return NULL;
+   }
+
+   // initialize ph
+   ph->ops = &core_ops;
+   ph->core->core_fd   = -1;
+   ph->core->exec_fd   = -1;
+   ph->core->interp_fd = -1;
+
+   // open the core file
+   if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
+      print_debug("can't open core file\n");
+      goto err;
+   }
+
+   // read core file ELF header
+   if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
+      print_debug("core file is not a valid ELF ET_CORE file\n");
+      goto err;
+   }
+
+   if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
+      print_debug("can't open executable file\n");
+      goto err;
+   }
+
+   if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
+      print_debug("executable file is not a valid ELF ET_EXEC file\n");
+      goto err;
+   }
+
+   // process core file segments
+   if (read_core_segments(ph, &core_ehdr) != true)
+      goto err;
+
+   // process exec file segments
+   if (read_exec_segments(ph, &exec_ehdr) != true)
+      goto err;
+
+   // exec file is also treated like a shared object for symbol search
+   if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
+                       (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
+      goto err;
+
+   // allocate and sort maps into map_array, we need to do this
+   // here because read_shared_lib_info needs to read from debuggee
+   // address space
+   if (sort_map_array(ph) != true)
+      goto err;
+
+   if (read_shared_lib_info(ph) != true)
+      goto err;
+
+   // sort again because we have added more mappings from shared objects
+   if (sort_map_array(ph) != true)
+      goto err;
+
+   if (init_classsharing_workaround(ph) != true)
+      goto err;
+
+   return ph;
+
+err:
+   Prelease(ph);
+   return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/ps_proc.c	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,444 @@
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ptrace.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <elf.h>
+#include <sys/elf_common.h>
+#include <sys/link_elf.h>
+#include <libutil.h>
+#include "libproc_impl.h"
+#include "elfmacros.h"
+
+// This file has the libproc implementation specific to live process
+// For core files, refer to ps_core.c
+
+static inline uintptr_t align(uintptr_t ptr, size_t size) {
+  return (ptr & ~(size - 1));
+}
+
+// ---------------------------------------------
+// ptrace functions
+// ---------------------------------------------
+
+// read "size" bytes of data from "addr" within the target process.
+// unlike the standard ptrace() function, process_read_data() can handle
+// unaligned address - alignment check, if required, should be done
+// before calling process_read_data.
+
+static bool process_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
+  int rslt;
+  size_t i, words;
+  uintptr_t end_addr = addr + size;
+  uintptr_t aligned_addr = align(addr, sizeof(int));
+
+  if (aligned_addr != addr) {
+    char *ptr = (char *)&rslt;
+    errno = 0;
+    rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
+    if (errno) {
+      print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
+      return false;
+    }
+    for (; aligned_addr != addr; aligned_addr++, ptr++);
+    for (; ((intptr_t)aligned_addr % sizeof(int)) && aligned_addr < end_addr;
+        aligned_addr++)
+       *(buf++) = *(ptr++);
+  }
+
+  words = (end_addr - aligned_addr) / sizeof(int);
+
+  // assert((intptr_t)aligned_addr % sizeof(int) == 0);
+  for (i = 0; i < words; i++) {
+    errno = 0;
+    rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
+    if (errno) {
+      print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
+      return false;
+    }
+    *(int *)buf = rslt;
+    buf += sizeof(int);
+    aligned_addr += sizeof(int);
+  }
+
+  if (aligned_addr != end_addr) {
+    char *ptr = (char *)&rslt;
+    errno = 0;
+    rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
+    if (errno) {
+      print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
+      return false;
+    }
+    for (; aligned_addr != end_addr; aligned_addr++)
+       *(buf++) = *(ptr++);
+  }
+  return true;
+}
+
+// null implementation for write
+static bool process_write_data(struct ps_prochandle* ph,
+                             uintptr_t addr, const char *buf , size_t size) {
+  return false;
+}
+
+// "user" should be a pointer to a reg
+static bool process_get_lwp_regs(struct ps_prochandle* ph, pid_t pid, struct reg *user) {
+  // we have already attached to all thread 'pid's, just use ptrace call
+  // to get regset now. Note that we don't cache regset upfront for processes.
+ if (ptrace(PT_GETREGS, pid, (caddr_t) user, 0) < 0) {
+   print_debug("ptrace(PTRACE_GETREGS, ...) failed for lwp %d\n", pid);
+   return false;
+ }
+ return true;
+}
+
+// fill in ptrace_lwpinfo for lid
+static bool process_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
+  errno = 0;
+  ptrace(PT_LWPINFO, lwp_id, linfo, sizeof(struct ptrace_lwpinfo));
+
+  return (errno == 0)? true: false;
+}
+
+// attach to a process/thread specified by "pid"
+static bool ptrace_attach(pid_t pid) {
+  if (ptrace(PT_ATTACH, pid, NULL, 0) < 0) {
+    print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
+    return false;
+  } else {
+    int ret;
+    int status;
+    do {
+      // Wait for debuggee to stop.
+      ret = waitpid(pid, &status, 0);
+      if (ret >= 0) {
+        if (WIFSTOPPED(status)) {
+          // Debuggee stopped.
+          return true;
+        } else {
+          print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
+          return false;
+        }
+      } else {
+        switch (errno) {
+          case EINTR:
+            continue;
+            break;
+          case ECHILD:
+            print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
+            break;
+          case EINVAL:
+            print_debug("waitpid() failed. Invalid options argument.\n");
+            break;
+          default:
+            print_debug("waitpid() failed. Unexpected error %d\n",errno);
+        }
+        return false;
+      }
+    } while(true);
+  }
+}
+
+// -------------------------------------------------------
+// functions for obtaining library information
+// -------------------------------------------------------
+
+// callback for read_thread_info
+static bool add_new_thread(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
+  return add_thread_info(ph, pthread_id, lwp_id) != NULL;
+}
+
+#if defined(__FreeBSD__) && __FreeBSD_version < 701000
+/*
+ * TEXT_START_ADDR from binutils/ld/emulparams/<arch_spec>.sh
+ * Not the most robust but good enough.
+ */
+
+#if defined(amd64) || defined(x86_64)
+#define TEXT_START_ADDR 0x400000
+#elif defined(i386)
+#define TEXT_START_ADDR 0x8048000
+#else
+#error TEXT_START_ADDR not defined
+#endif
+
+#define BUF_SIZE (PATH_MAX + NAME_MAX + 1)
+
+uintptr_t linkmap_addr(struct ps_prochandle *ph) {
+  uintptr_t ehdr_addr, phdr_addr, dyn_addr, dmap_addr, lmap_addr;
+  ELF_EHDR ehdr;
+  ELF_PHDR *phdrs, *phdr;
+  ELF_DYN *dyns, *dyn;
+  struct r_debug dmap;
+  unsigned long hdrs_size;
+  unsigned int i;
+
+  /* read ELF_EHDR at TEXT_START_ADDR and validate */
+
+  ehdr_addr = (uintptr_t)TEXT_START_ADDR;
+
+  if (process_read_data(ph, ehdr_addr, (char *)&ehdr, sizeof(ehdr)) != true) {
+    print_debug("process_read_data failed for ehdr_addr %p\n", ehdr_addr);
+    return (0);
+  }
+
+  if (!IS_ELF(ehdr) ||
+        ehdr.e_ident[EI_CLASS] != ELF_TARG_CLASS ||
+        ehdr.e_ident[EI_DATA] != ELF_TARG_DATA ||
+        ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
+        ehdr.e_phentsize != sizeof(ELF_PHDR) ||
+        ehdr.e_version != ELF_TARG_VER ||
+        ehdr.e_machine != ELF_TARG_MACH) {
+    print_debug("not an ELF_EHDR at %p\n", ehdr_addr);
+    return (0);
+  }
+
+  /* allocate space for all ELF_PHDR's and read */
+
+  phdr_addr = ehdr_addr + ehdr.e_phoff;
+  hdrs_size = ehdr.e_phnum * sizeof(ELF_PHDR);
+
+  if ((phdrs = malloc(hdrs_size)) == NULL)
+    return (0);
+
+  if (process_read_data(ph, phdr_addr, (char *)phdrs, hdrs_size) != true) {
+    print_debug("process_read_data failed for phdr_addr %p\n", phdr_addr);
+    return (0);
+  }
+
+  /* find PT_DYNAMIC section */
+
+  for (i = 0, phdr = phdrs; i < ehdr.e_phnum; i++, phdr++) {
+    if (phdr->p_type == PT_DYNAMIC)
+      break;
+  }
+
+  if (i >= ehdr.e_phnum) {
+    print_debug("PT_DYNAMIC section not found!\n");
+    free(phdrs);
+    return (0);
+  }
+
+  /* allocate space and read in ELF_DYN headers */
+
+  dyn_addr = phdr->p_vaddr;
+  hdrs_size = phdr->p_memsz;
+  free(phdrs);
+
+  if ((dyns = malloc(hdrs_size)) == NULL)
+    return (0);
+
+  if (process_read_data(ph, dyn_addr, (char *)dyns, hdrs_size) != true) {
+    print_debug("process_read_data failed for dyn_addr %p\n", dyn_addr);
+    free(dyns);
+    return (0);
+  }
+
+  /* find DT_DEBUG */
+
+  dyn = dyns;
+  while (dyn->d_tag != DT_DEBUG && dyn->d_tag != DT_NULL) {
+    dyn++;
+  }
+
+  if (dyn->d_tag != DT_DEBUG) {
+    print_debug("failed to find DT_DEBUG\n");
+    free(dyns);
+    return (0);
+  }
+
+  /* read struct r_debug into dmap */
+
+  dmap_addr = (uintptr_t)dyn->d_un.d_ptr;
+  free(dyns);
+
+  if (process_read_data(ph, dmap_addr, (char *)&dmap, sizeof(dmap)) != true) {
+    print_debug("process_read_data failed for dmap_addr %p\n", dmap_addr);
+    return (0);
+  }
+
+  lmap_addr = (uintptr_t)dmap.r_map;
+
+  return (lmap_addr);
+}
+#endif // __FreeBSD__ && __FreeBSD_version < 701000
+
+static bool read_lib_info(struct ps_prochandle* ph) {
+#if defined(__FreeBSD__) && __FreeBSD_version >= 701000
+  struct kinfo_vmentry *freep, *kve;
+  int i, cnt;
+
+  freep = kinfo_getvmmap(ph->pid, &cnt);
+  if (freep == NULL) {
+      print_debug("can't get vm map for pid\n", ph->pid);
+      return false;
+  }
+
+  for (i = 0; i < cnt; i++) {
+    kve = &freep[i];
+    if ((kve->kve_flags & KVME_FLAG_COW) &&
+        kve->kve_path != NULL &&
+        strlen(kve->kve_path) > 0) {
+
+      if (find_lib(ph, kve->kve_path) == false) {
+        lib_info* lib;
+        if ((lib = add_lib_info(ph, kve->kve_path,
+                                (uintptr_t) kve->kve_start)) == NULL)
+          continue; // ignore, add_lib_info prints error
+
+        // we don't need to keep the library open, symtab is already
+        // built. Only for core dump we need to keep the fd open.
+        close(lib->fd);
+        lib->fd = -1;
+      }
+    }
+  }
+
+  free(freep);
+
+  return true;
+#else
+  char *l_name;
+  struct link_map *lmap;
+  uintptr_t lmap_addr;
+
+  if ((l_name = malloc(BUF_SIZE)) == NULL)
+    return false;
+
+  if ((lmap = malloc(sizeof(*lmap))) == NULL) {
+    free(l_name);
+    return false;
+  }
+
+  lmap_addr = linkmap_addr(ph);
+
+  if (lmap_addr == 0) {
+    free(l_name);
+    free(lmap);
+    return false;
+  }
+
+  do {
+    if (process_read_data(ph, lmap_addr, (char *)lmap, sizeof(*lmap)) != true) {
+      print_debug("process_read_data failed for lmap_addr %p\n", lmap_addr);
+      free (l_name);
+      free (lmap);
+      return false;
+    }
+
+    if (process_read_data(ph, (uintptr_t)lmap->l_name, l_name,
+        BUF_SIZE) != true) {
+      print_debug("process_read_data failed for lmap->l_name %p\n",
+          lmap->l_name);
+      free (l_name);
+      free (lmap);
+      return false;
+    }
+
+    if (find_lib(ph, l_name) == false) {
+      lib_info* lib;
+      if ((lib = add_lib_info(ph, l_name,
+                              (uintptr_t) lmap->l_addr)) == NULL)
+        continue; // ignore, add_lib_info prints error
+
+      // we don't need to keep the library open, symtab is already
+      // built. Only for core dump we need to keep the fd open.
+      close(lib->fd);
+      lib->fd = -1;
+    }
+    lmap_addr = (uintptr_t)lmap->l_next;
+  } while (lmap->l_next != NULL);
+
+  free (l_name);
+  free (lmap);
+
+  return true;
+#endif
+}
+
+// detach a given pid
+static bool ptrace_detach(pid_t pid) {
+  if (pid && ptrace(PT_DETACH, pid, (caddr_t)1, 0) < 0) {
+    print_debug("ptrace(PTRACE_DETACH, ..) failed for %d\n", pid);
+    return false;
+  } else {
+    return true;
+  }
+}
+
+static void process_cleanup(struct ps_prochandle* ph) {
+  ptrace_detach(ph->pid);
+}
+
+static ps_prochandle_ops process_ops = {
+  .release=  process_cleanup,
+  .p_pread=  process_read_data,
+  .p_pwrite= process_write_data,
+  .get_lwp_regs= process_get_lwp_regs,
+  .get_lwp_info= process_get_lwp_info
+};
+
+// attach to the process. One and only one exposed stuff
+struct ps_prochandle* Pgrab(pid_t pid) {
+  struct ps_prochandle* ph = NULL;
+  thread_info* thr = NULL;
+
+  if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
+     print_debug("can't allocate memory for ps_prochandle\n");
+     return NULL;
+  }
+
+  if (ptrace_attach(pid) != true) {
+     free(ph);
+     return NULL;
+  }
+
+  // initialize ps_prochandle
+  ph->pid = pid;
+
+  // initialize vtable
+  ph->ops = &process_ops;
+
+  // read library info and symbol tables, must do this before attaching threads,
+  // as the symbols in the pthread library will be used to figure out
+  // the list of threads within the same process.
+  if (read_lib_info(ph) != true) {
+     ptrace_detach(pid);
+     free(ph);
+     return NULL;
+  }
+
+  // read thread info
+  read_thread_info(ph, add_new_thread);
+
+  return ph;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/salibelf.c	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "salibelf.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+extern void print_debug(const char*,...);
+
+// ELF file parsing helpers. Note that we do *not* use libelf here.
+int read_elf_header(int fd, ELF_EHDR* ehdr) {
+   if (pread(fd, ehdr, sizeof (ELF_EHDR), 0) != sizeof (ELF_EHDR) ||
+            memcmp(&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0 ||
+            ehdr->e_version != EV_CURRENT) {
+        return 0;
+   }
+   return 1;
+}
+
+bool is_elf_file(int fd) {
+   ELF_EHDR ehdr;
+   return read_elf_header(fd, &ehdr);
+}
+
+// read program header table of an ELF file
+ELF_PHDR* read_program_header_table(int fd, ELF_EHDR* hdr) {
+   ELF_PHDR* phbuf = 0;
+   // allocate memory for program header table
+   size_t nbytes = hdr->e_phnum * hdr->e_phentsize;
+
+   if ((phbuf = (ELF_PHDR*) malloc(nbytes)) == NULL) {
+      print_debug("can't allocate memory for reading program header table\n");
+      return NULL;
+   }
+
+   if (pread(fd, phbuf, nbytes, hdr->e_phoff) != nbytes) {
+      print_debug("ELF file is truncated! can't read program header table\n");
+      free(phbuf);
+      return NULL;
+   }
+
+   return phbuf;
+}
+
+// read section header table of an ELF file
+ELF_SHDR* read_section_header_table(int fd, ELF_EHDR* hdr) {
+   ELF_SHDR* shbuf = 0;
+   // allocate memory for section header table
+   size_t nbytes = hdr->e_shnum * hdr->e_shentsize;
+
+   if ((shbuf = (ELF_SHDR*) malloc(nbytes)) == NULL) {
+      print_debug("can't allocate memory for reading section header table\n");
+      return NULL;
+   }
+
+   if (pread(fd, shbuf, nbytes, hdr->e_shoff) != nbytes) {
+      print_debug("ELF file is truncated! can't read section header table\n");
+      free(shbuf);
+      return NULL;
+   }
+
+   return shbuf;
+}
+
+// read a particular section's data
+void* read_section_data(int fd, ELF_EHDR* ehdr, ELF_SHDR* shdr) {
+  void *buf = NULL;
+  if (shdr->sh_type == SHT_NOBITS || shdr->sh_size == 0) {
+     return buf;
+  }
+  if ((buf = calloc(shdr->sh_size, 1)) == NULL) {
+     print_debug("can't allocate memory for reading section data\n");
+     return NULL;
+  }
+  if (pread(fd, buf, shdr->sh_size, shdr->sh_offset) != shdr->sh_size) {
+     free(buf);
+     print_debug("section data read failed\n");
+     return NULL;
+  }
+  return buf;
+}
+
+uintptr_t find_base_address(int fd, ELF_EHDR* ehdr) {
+  uintptr_t baseaddr = (uintptr_t)-1;
+  int cnt;
+  ELF_PHDR *phbuf, *phdr;
+
+  // read program header table
+  if ((phbuf = read_program_header_table(fd, ehdr)) == NULL) {
+    goto quit;
+  }
+
+  // the base address of a shared object is the lowest vaddr of
+  // its loadable segments (PT_LOAD)
+  for (phdr = phbuf, cnt = 0; cnt < ehdr->e_phnum; cnt++, phdr++) {
+    if (phdr->p_type == PT_LOAD && phdr->p_vaddr < baseaddr) {
+      baseaddr = phdr->p_vaddr;
+    }
+  }
+
+quit:
+  if (phbuf) free(phbuf);
+  return baseaddr;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/salibelf.h	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef _SALIBELF_H_
+#define _SALIBELF_H_
+
+#include <elf.h>
+#include "elfmacros.h"
+#include "libproc_impl.h"
+
+// read ELF file header.
+int read_elf_header(int fd, ELF_EHDR* ehdr);
+
+// is given file descriptor corresponds to an ELF file?
+bool is_elf_file(int fd);
+
+// read program header table of an ELF file. caller has to
+// free the result pointer after use. NULL on failure.
+ELF_PHDR* read_program_header_table(int fd, ELF_EHDR* hdr);
+
+// read section header table of an ELF file. caller has to
+// free the result pointer after use. NULL on failure.
+ELF_SHDR* read_section_header_table(int fd, ELF_EHDR* hdr);
+
+// read a particular section's data. caller has to free the
+// result pointer after use. NULL on failure.
+void* read_section_data(int fd, ELF_EHDR* ehdr, ELF_SHDR* shdr);
+
+// find the base address at which the library wants to load itself
+uintptr_t find_base_address(int fd, ELF_EHDR* ehdr);
+#endif /* _SALIBELF_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/symtab.c	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <unistd.h>
+#include <search.h>
+#include <stdlib.h>
+#include <string.h>
+#include <db.h>
+#include <fcntl.h>
+#include "symtab.h"
+#include "salibelf.h"
+
+
+// ----------------------------------------------------
+// functions for symbol lookups
+// ----------------------------------------------------
+
+struct elf_section {
+  ELF_SHDR   *c_shdr;
+  void       *c_data;
+};
+
+struct elf_symbol {
+  char *name;
+  uintptr_t offset;
+  uintptr_t size;
+};
+
+typedef struct symtab {
+  char *strs;
+  size_t num_symbols;
+  struct elf_symbol *symbols;
+  DB* hash_table;
+} symtab_t;
+
+// read symbol table from given fd.
+struct symtab* build_symtab(int fd) {
+  ELF_EHDR ehdr;
+  struct symtab* symtab = NULL;
+
+  // Reading of elf header
+  struct elf_section *scn_cache = NULL;
+  int cnt = 0;
+  ELF_SHDR* shbuf = NULL;
+  ELF_SHDR* cursct = NULL;
+  ELF_PHDR* phbuf = NULL;
+  int symtab_found = 0;
+  int dynsym_found = 0;
+  uint32_t symsection = SHT_SYMTAB;
+
+  uintptr_t baseaddr = (uintptr_t)-1;
+
+  lseek(fd, (off_t)0L, SEEK_SET);
+  if (! read_elf_header(fd, &ehdr)) {
+    // not an elf
+    return NULL;
+  }
+
+  // read ELF header
+  if ((shbuf = read_section_header_table(fd, &ehdr)) == NULL) {
+    goto quit;
+  }
+
+  baseaddr = find_base_address(fd, &ehdr);
+
+  scn_cache = calloc(ehdr.e_shnum, sizeof(*scn_cache));
+  if (scn_cache == NULL) {
+    goto quit;
+  }
+
+  for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) {
+    scn_cache[cnt].c_shdr = cursct;
+    if (cursct->sh_type == SHT_SYMTAB ||
+        cursct->sh_type == SHT_STRTAB ||
+        cursct->sh_type == SHT_DYNSYM) {
+      if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) {
+         goto quit;
+      }
+    }
+
+    if (cursct->sh_type == SHT_SYMTAB)
+       symtab_found++;
+
+    if (cursct->sh_type == SHT_DYNSYM)
+       dynsym_found++;
+
+    cursct++;
+  }
+
+  if (!symtab_found && dynsym_found)
+     symsection = SHT_DYNSYM;
+
+  for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
+    ELF_SHDR *shdr = scn_cache[cnt].c_shdr;
+
+    if (shdr->sh_type == symsection) {
+      ELF_SYM  *syms;
+      int j, n, rslt;
+      size_t size;
+
+      // FIXME: there could be multiple data buffers associated with the
+      // same ELF section. Here we can handle only one buffer. See man page
+      // for elf_getdata on Solaris.
+
+      // guarantee(symtab == NULL, "multiple symtab");
+      symtab = calloc(1, sizeof(*symtab));
+      if (symtab == NULL) {
+         goto quit;
+      }
+      // the symbol table
+      syms = (ELF_SYM *)scn_cache[cnt].c_data;
+
+      // number of symbols
+      n = shdr->sh_size / shdr->sh_entsize;
+
+      // create hash table, we use berkeley db to
+      // manipulate the hash table.
+      symtab->hash_table = dbopen(NULL, O_CREAT | O_RDWR, 0600, DB_HASH, NULL);
+      // guarantee(symtab->hash_table, "unexpected failure: dbopen");
+
+      // shdr->sh_link points to the section that contains the actual strings
+      // for symbol names. the st_name field in ELF_SYM is just the
+      // string table index. we make a copy of the string table so the
+      // strings will not be destroyed by elf_end.
+      size = scn_cache[shdr->sh_link].c_shdr->sh_size;
+      symtab->strs = malloc(size);
+      memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data, size);
+
+      // allocate memory for storing symbol offset and size;
+      symtab->num_symbols = n;
+      symtab->symbols = calloc(n , sizeof(*symtab->symbols));
+
+      // copy symbols info our symtab and enter them info the hash table
+      for (j = 0; j < n; j++, syms++) {
+        DBT key, value;
+        char *sym_name = symtab->strs + syms->st_name;
+
+        // skip non-object and non-function symbols
+        int st_type = ELF_ST_TYPE(syms->st_info);
+        if ( st_type != STT_FUNC && st_type != STT_OBJECT)
+           continue;
+        // skip empty strings and undefined symbols
+        if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue;
+
+        symtab->symbols[j].name   = sym_name;
+        symtab->symbols[j].offset = syms->st_value - baseaddr;
+        symtab->symbols[j].size   = syms->st_size;
+
+        key.data = sym_name;
+        key.size = strlen(sym_name) + 1;
+        value.data = &(symtab->symbols[j]);
+        value.size = sizeof(void *);
+        (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0);
+      }
+    }
+  }
+
+quit:
+  if (shbuf) free(shbuf);
+  if (phbuf) free(phbuf);
+  if (scn_cache) {
+    for (cnt = 0; cnt < ehdr.e_shnum; cnt++) {
+      if (scn_cache[cnt].c_data != NULL) {
+        free(scn_cache[cnt].c_data);
+      }
+    }
+    free(scn_cache);
+  }
+  return symtab;
+}
+
+void destroy_symtab(struct symtab* symtab) {
+  if (!symtab) return;
+  if (symtab->strs) free(symtab->strs);
+  if (symtab->symbols) free(symtab->symbols);
+  if (symtab->hash_table) {
+    symtab->hash_table->close(symtab->hash_table);
+  }
+  free(symtab);
+}
+
+uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
+                      const char *sym_name, int *sym_size) {
+  DBT key, value;
+  int ret;
+
+  // library does not have symbol table
+  if (!symtab || !symtab->hash_table)
+     return 0;
+
+  key.data = (char*)(uintptr_t)sym_name;
+  key.size = strlen(sym_name) + 1;
+  ret = (*symtab->hash_table->get)(symtab->hash_table, &key, &value, 0);
+  if (ret == 0) {
+    struct elf_symbol *sym = value.data;
+    uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset);
+    if (sym_size) *sym_size = sym->size;
+    return rslt;
+  }
+
+quit:
+  return 0;
+}
+
+const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
+                           uintptr_t* poffset) {
+  int n = 0;
+  if (!symtab) return NULL;
+  for (; n < symtab->num_symbols; n++) {
+     struct elf_symbol* sym = &(symtab->symbols[n]);
+     if (sym->name != NULL &&
+         offset >= sym->offset && offset < sym->offset + sym->size) {
+        if (poffset) *poffset = (offset - sym->offset);
+        return sym->name;
+     }
+  }
+  return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/symtab.h	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef _SYMTAB_H_
+#define _SYMTAB_H_
+
+#include <stdint.h>
+
+// interface to manage ELF symbol tables
+
+struct symtab;
+
+// build symbol table for a given ELF file descriptor
+struct symtab* build_symtab(int fd);
+
+// destroy the symbol table
+void destroy_symtab(struct symtab* symtab);
+
+// search for symbol in the given symbol table. Adds offset
+// to the base uintptr_t supplied. Returns NULL if not found.
+uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
+                      const char *sym_name, int *sym_size);
+
+// look for nearest symbol for a given offset (not address - base
+// subtraction done by caller
+const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
+                      uintptr_t* poffset);
+
+#endif /*_SYMTAB_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/os/bsd/test.c	Wed Jul 05 17:52:13 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "libproc.h"
+
+int main(int argc, char** argv) {
+   struct ps_prochandle* ph;
+
+   init_libproc(true);
+   switch (argc) {
+      case 2: {
+         // process
+         ph = Pgrab(atoi(argv[1]));
+         break;
+      }
+
+      case 3: {
+        // core
+        ph = Pgrab_core(argv[1], argv[2]);
+        break;
+      }
+
+      default: {
+        fprintf(stderr, "usage %s <pid> or %s <exec file> <core file>\n", argv[0], argv[0]);
+        return 1;
+      }
+   }
+
+   if (ph) {
+      Prelease(ph);
+      return 0;
+   } else {
+      printf("can't connect to debuggee\n");
+      return 1;
+   }
+}
--- a/hotspot/agent/src/os/solaris/Makefile	Thu Sep 29 18:53:49 2011 -0700
+++ b/hotspot/agent/src/os/solaris/Makefile	Wed Jul 05 17:52:13 2017 +0200
@@ -24,9 +24,7 @@
 
 
 all:
-	cd dbx; $(MAKE) all
 	cd proc; $(MAKE) all
 
 clean:
-	cd dbx; $(MAKE) clean
 	cd proc; $(MAKE) clean
--- a/hotspot/agent/src/os/solaris/dbx/Makefile	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#
-# Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#  
-#
-
-
-# Targets are:
-#   32bit:  Build the 32 bit version in ./32bit
-#   64bit:  Build the 64 bit version in ./64bit
-#   helloWorld:  Build the helloWorld test program
-#   all:    Build all of the above.  This is the default.
-#
-# NOTE: This makefile uses IOBuf.cpp, IOBuf.hpp, Buffer.cpp, and
-#           Buffer.hpp from the src/os/win32/agent directory.
-
-.PHONY: 32bit 64bit
-
-ARCH_ORIG = $(shell uname -p)
-
-# C++    := /java/devtools/$(ARCH_ORIG)/SUNWspro/SC6.1/bin/CC
-
-C++    := CC
-RM     := /usr/bin/rm
-MKDIRS := /usr/bin/mkdir -p
-
-
-WIN32_DIR := ../../win32
-ARCH     := $(subst i386,i486,$(ARCH_ORIG))
-# INCLUDES := -I/net/sparcworks.eng/export/set/sparcworks5/dbx_62_intg/dev/src/dbx -I$(WIN32_DIR)
-INCLUDES := -I. -I$(WIN32_DIR)
-CFLAGS_32bit := -xarch=v8
-CFLAGS_64bit := -xarch=v9
-CFLAGS   := -PIC -xO3 $(INCLUDES)
-LIBS     := -lsocket -lnsl -lrtld_db
-LDFLAGS  := -G
-
-ifneq "$(ARCH)" "i486"
-    CFLAGS += $(CFLAGS_$(VERSION))
-    LDFLAGS += $(CFLAGS_$(VERSION))
-endif
-
-# We use IOBuf.hpp, IOBuf.cpp, Buffer.hpp, and Buffer.cpp from the win32 dir.
-vpath %.cpp .:$(WIN32_DIR)
-vpath %.hpp .:$(WIN32_DIR)
-
-OBJS = $(VERSION)/svc_agent_dbx.o $(VERSION)/IOBuf.o $(VERSION)/Buffer.o
-
-
-
-# The default is to make both 32 bit and 64 bit versions.
-all:: 32bit 64bit
-
-32bit 64bit:: 
-	$(MKDIRS) $@
-	$(MAKE) $@/libsvc_agent_dbx.so  helloWorld VERSION=$@
-
-$(VERSION)/IOBuf.o: IOBuf.hpp
-$(VERSION)/Buffer.o: Buffer.hpp
-$(VERSION)/svc_agent_dbx.o: svc_agent_dbx.hpp
-
-$(VERSION)/%.o: %.cpp
-	$(C++) $(CFLAGS) -c $< -o $@
-
-$(VERSION)/libsvc_agent_dbx.so:: $(OBJS)
-	$(C++) $(LDFLAGS) -o $(VERSION)/libsvc_agent_dbx.so $(OBJS) $(LIBS)
-
-# Would be nice to move this into a shared directory
-helloWorld:: helloWorld.cpp
-	$(C++) -g $< -o $@
-
-clean::
-	$(RM) -rf 32bit 64bit *.o helloWorld
--- a/hotspot/agent/src/os/solaris/dbx/README	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-shell_impl.h
-proc_service_2.h
-
-The above files are captured from the dbx build environment.
-Rather then use a -I that points to stuff in .eng domain that
-may not be accessible in other domains these files are just
-copied here so local builds in other domains will work.
-These files rarely change so the fact that we might have to
-strobe in new ones on rare occasions is no big deal.
--- a/hotspot/agent/src/os/solaris/dbx/README-commands.txt	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-This import module uses a largely text-based protocol, except for
-certain bulk data transfer operations. All text is in single-byte
-US-ASCII.
-
-Commands understood:
-
-address_size                  ::= <int result>
-
-    Returns 32 if attached to 32-bit process, 64 if 64-bit.
-
-peek_fail_fast <bool arg>     ::=
-
-    Indicates whether "peek" requests should "fail fast"; that is, if
-    any of the addresses in the requested range are unmapped, report
-    the entire range as unmapped. This is substantially faster than
-    the alternative, which is to read the entire range byte-by-byte.
-    However, it should only be used when it is guaranteed by the
-    client application that peeks come from at most one page. The
-    default is that peek_fast_fail is not enabled.
-
-peek <address addr> <unsigned int numBytes> ::=
-    B<binary char success>
-       [<binary unsigned int len> <binary char isMapped> [<binary char data>]...]...
-
-    NOTE that the binary portion of this message is prefixed by the
-    uppercase US-ASCII letter 'B', allowing easier synchronization by
-    clients. There is no data between the 'B' and the rest of the
-    message.
-
-    May only be called once attached. Reads the address space of the
-    target process starting at the given address (see below for format
-    specifications) and extending the given number of bytes. Whether
-    the read succeeded is indicated by a single byte containing a 1 or
-    0 (success or failure). If successful, the return result is given
-    in a sequence of ranges. _len_, the length of each range, is
-    indicated by a 32-bit unsigned integer transmitted with big-endian
-    byte ordering (i.e., most significant byte first).  _isMapped_
-    indicates whether the range is mapped or unmapped in the target
-    process's address space, and will contain the value 1 or 0 for
-    mapped or unmapped, respectively. If the range is mapped,
-    _isMapped_ is followed by _data_, containing the raw binary data
-    for the range. The sum of all ranges' lengths is guaranteed to be
-    equivalent to the number of bytes requested.
-
-poke <address addr> <int numBytes> B[<binary char data>]... ::= <bool result>
-
-    NOTE that the binary portion of this message is prefixed by the
-    uppercase US-ASCII letter 'B', allowing easier synchronization by
-    clients. There is no data between the 'B' and the rest of the
-    message.
-
-    Writes the given data to the target process starting at the given
-    address. Returns 1 on success, 0 on failure (i.e., one or more of
-    target addresses were unmapped).
-
-mapped <address addr> <int numBytes> ::= <bool result>
-
-    Returns 1 if entire address range [address...address + int arg) is
-    mapped in target process's address space, 0 if not
-
-lookup <symbol objName> <symbol sym> ::= <address addr>
-
-    First symbol is object name; second is symbol to be looked up.
-    Looks up symbol in target process's symbol table and returns
-    address. Returns NULL (0x0) if symbol is not found.
-
-thr_gregs <int tid>                  ::= <int numAddresses> <address...>
-
-    Fetch the "general" (integer) register set for the given thread.
-    Returned as a series of hexidecimal values. NOTE: the meaning of
-    the return value is architecture-dependent. In general it is the
-    contents of the prgregset_t.
-
-exit                                 ::=
-
-    Exits the serviceability agent dbx module, returning control to
-    the dbx prompt.
-
-// Data formats and example values:
-<address>      ::=   0x12345678[9ABCDEF0] /* up to 64-bit hex value */
-<unsigned int> ::=   5                    /* up to 32-bit integer number; no leading sign */
-<bool>         ::=   1                    /* ASCII '0' or '1' */
--- a/hotspot/agent/src/os/solaris/dbx/helloWorld.cpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <stdio.h>
-#include <inttypes.h>
-
-extern "C" {
-  const char* helloWorldString = "Hello, world!";
-  // Do not change these values without changing TestDebugger.java as well
-  // FIXME: should make these jbyte, jshort, etc...
-  volatile int8_t  testByte     = 132;
-  volatile int16_t testShort    = 27890;
-  volatile int32_t testInt      = 1020304050;
-  volatile int64_t testLong     = 102030405060708090LL;
-  volatile float   testFloat    = 35.4F;
-  volatile double  testDouble   = 1.23456789;
-
-  volatile int helloWorldTrigger = 0;
-}
-
-int
-main(int, char**) {
-  while (1) {
-    while (helloWorldTrigger == 0) {
-    }
-
-    fprintf(stderr, "%s\n", helloWorldString);
-    fprintf(stderr, "testByte=%d\n", testByte);
-    fprintf(stderr, "testShort=%d\n", testShort);
-    fprintf(stderr, "testInt=%d\n", testInt);
-    fprintf(stderr, "testLong=%d\n", testLong);
-    fprintf(stderr, "testFloat=%d\n", testFloat);
-    fprintf(stderr, "testDouble=%d\n", testDouble);
-
-    while (helloWorldTrigger != 0) {
-    }
-  }
-}
--- a/hotspot/agent/src/os/solaris/dbx/proc_service_2.h	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _PROC_SERVICE_2_H
-#define _PROC_SERVICE_2_H
-
-/*
- * Types, function definitions for the provider of services beyond
- * proc_service.  This interface will be used by import modules like
- * BAT/prex, NEO debugger etc.
- */
-
-/*
- CCR info
-
- Version history:
-
-        1.0       - Initial CCR release
-
-        1.1       - Changes for GLUE/neo.
-                    New entry points ps_svnt_generic() and ps_svc_generic()
-                  - New entry point ps_getpid()
-
- Release information for automatic CCR updates:
- BEGIN RELEASE NOTES: (signifies what gets put into CCR release notes)
-        1.2       - Changes to support Solaris 2.7
-
- END RELEASE NOTES: (signifies what gets put into CCR release notes)
-
- Following is used for CCR version number:
-
-#define CCR_PROC_SERVICE_2_VERSION 1.2
-
-*/
-
-
-#include <proc_service.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ps_loadobj {
-        int     objfd;          /* fd of the load object or executable
-                                 * -1 implies its not available.
-                                 * This file decriptor is live only during the
-                                 * particular call to ps_iter_f().  If you
-                                 * need it beyond that you need to dup() it.
-                                 */
-        psaddr_t
-                text_base;      /* address where text of loadobj was mapped */
-        psaddr_t
-                data_base;      /* address where data of loadobj was mapped */
-        const char *objname;    /* loadobj name */
-};
-
-typedef int ps_iter_f(const struct ps_prochandle *, const struct ps_loadobj *,
-                        void *cd);
-
-/*
- * Returns the ps_prochandle for the current process under focus.  Returns
- * NULL if there is none.
- */
-
-const struct ps_prochandle *
-ps_get_prochandle(void);
-
-/*
- * Returns the ps_prochandle for the current process(allows core files to
- * be specified) under focus.  Returns NULL if there is none.
- */
-const struct ps_prochandle *
-ps_get_prochandle2(int cores_too);
-
-/*
- * Returns the pid of the process referred to by the ps_prochandle.
- *
- * 0 is returned in case the ps_prochandle is not valid or refers to dead
- * process.
- *
- */
-pid_t
-ps_getpid(const struct ps_prochandle *);
-
-/*
- * Iteration function that iterates over all load objects *and the
- *      executable*
- *
- *      If the callback routine returns:
- *      0 - continue processing link objects
- *      non zero - stop calling the callback function
- *
- */
-
-ps_err_e
-ps_loadobj_iter(const struct ps_prochandle *, ps_iter_f *, void *clnt_data);
-
-/*
- * Address => function name mapping
- *
- * Given an address, returns a pointer to the function's
- * linker name (null terminated).
- */
-
-ps_err_e
-ps_find_fun_name(const struct ps_prochandle *, psaddr_t addr,
-                        const char **name);
-
-/*
- * Interface to LD_PRELOAD.  LD_PRELOAD given library across the
- * program 'exec'.
- *
- */
-
-/*
- * Append/Prepend the 'lib' (has to be library name as understood by LD_PRELOAD)
- * to the LD_PRELOAD variable setting to be used by the debugee
- * Returns a cookie (in id).
- */
-ps_err_e
-ps_ld_preload_append(const char *lib, int *id);
-ps_err_e
-ps_ld_preload_prepend(const char *lib, int *id);
-
-/*
- * Remove the library associated with 'id' from the LD_PRELOAD setting.
- *
- */
-ps_err_e
-ps_ld_preload_remove(int id);
-
-#ifdef __cplusplus
-}
-#endif
-
-/*
- * The following are C++ only interfaces
- */
-#ifdef __cplusplus
-
-/*
- * classes ServiceDbx and ServantDbx and defined in "gp_dbx_svc.h" which is
- * accessed via CCR
- */
-extern class ServantDbx *ps_svnt_generic();
-extern class ServiceDbx *ps_svc_generic();
-
-#endif
-
-#endif /* _PROC_SERVICE_2_H */
--- a/hotspot/agent/src/os/solaris/dbx/shell_imp.h	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHELL_IMP_H
-#define SHELL_IMP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-
-/*
- CCR info
-
- Vesrion history:
-
-        1.0       - Initial CCR release
-
- Release information for automatic CCR updates:
-
- BEGIN RELEASE NOTES: (signifies what gets put into CCR release notes)
-        1.1
-                  - Entry points for va_list style msgs; new shell_imp_vmsg()
-                    and shell_imp_verrmsg()
-                  - shell_imp_env_checker() is now shell_imp_var_checker().
-                    Also the var_checker callback gets passed interp.
-        1.2       - interposition framework (used by jdbx)
-                  - access to input FILE pointer.
-
- END RELEASE NOTES: (signifies what gets put into CCR release notes)
-
-Following is used as a CCR version number:
-#define CCR_SHELL_IMP_VERSION 1.1
-*/
-
-#include <stdarg.h>
-
-#define SHELL_IMP_MAJOR 1
-#define SHELL_IMP_MINOR 2
-#define SHELL_IMP_FLAG_GLOB 0x1
-#define SHELL_IMP_FLAG_ARGQ 0x2
-
-typedef void *shell_imp_interp_t;
-typedef void *shell_imp_command_t;
-typedef int shell_imp_fun_t(shell_imp_interp_t, int, char **, void *);
-
-int
-shell_imp_init(
-    int,                /* major version number */
-    int,                /* minor version number */
-    shell_imp_interp_t, /* interpreter */
-    int,                /* argc */
-    char *[]            /* argv */
-);
-
-int
-shell_imp_fini(shell_imp_interp_t);
-
-shell_imp_command_t
-shell_imp_define_command(char *,        /* command name e.g. "tnf" */
-                    shell_imp_fun_t *,  /* callback function */
-                    int,                /* SHELL_IMP_FLAG_* bit vector */
-                    void *,             /* client_data Passed as last arg to
-                                        /* callback function */
-                    char *              /* help message, e.g. */
-                                        /* "enable the specified tnf probes" */
-            );
-
-int
-shell_imp_undefine_command(shell_imp_command_t);
-
-int
-shell_imp_var_checker(shell_imp_interp_t,
-                      const char *,         /* var name */
-                      int (*)(shell_imp_interp_t, const char*) /* env checker */
-                     );
-
-int
-shell_imp_execute(shell_imp_interp_t, const char *);
-
-const char *
-shell_imp_get_var(shell_imp_interp_t, const char *);
-
-void
-shell_imp_msg(shell_imp_interp_t, const char *, ...);
-
-void
-shell_imp_errmsg(shell_imp_interp_t, const char *, ...);
-
-void
-shell_imp_vmsg(shell_imp_interp_t, const char *, va_list);
-
-void
-shell_imp_verrmsg(shell_imp_interp_t, const char *, va_list);
-
-
-
-/*
- * Stuff added for 1.2
- */
-
-struct shell_imp_interposition_info_t {
-    shell_imp_fun_t *
-                new_func;
-    void *      new_client_data;
-    shell_imp_fun_t *
-                original_func;
-    void *      original_client_data;
-    int         original_flags;
-};
-
-typedef int shell_imp_dispatcher_t(shell_imp_interp_t, int, char **,
-                                   shell_imp_interposition_info_t *);
-
-shell_imp_command_t
-shell_imp_interpose(char *name,
-                    shell_imp_fun_t *new_func,
-                    int    flags,
-                    void *client_data,
-                    char * description,
-                    shell_imp_dispatcher_t *);
-
-int shell_imp_uninterpose(shell_imp_command_t);
-
-int
-shell_imp_dispatch_interposition(shell_imp_interp_t,
-                                 shell_imp_interposition_info_t *,
-                                 int argc, char *argv[]);
-
-int
-shell_imp_dispatch_original(shell_imp_interp_t,
-                                 shell_imp_interposition_info_t *,
-                                 int argc, char *argv[]);
-
-FILE *
-shell_imp_cur_input(shell_imp_interp_t);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--- a/hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.cpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1068 +0,0 @@
-/*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-// This is the implementation of a very simple dbx import module which
-// handles requests from the VM which come in over a socket. The
-// higher-level Java wrapper for dbx starts the debugger, attaches to
-// the process, imports this command, and runs it. After that, the SA
-// writes commands to this agent via its own private communications
-// channel. The intent is to move away from the text-based front-end
-// completely in the near future (no more calling "debug" by printing
-// text to dbx's stdin).
-
-#include <stdio.h>
-#include <errno.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <string.h>
-#include <stropts.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <proc_service.h>
-#include <sys/procfs_isa.h>
-#include <rtld_db.h>
-#include "proc_service_2.h"
-#include "svc_agent_dbx.hpp"
-
-static ServiceabilityAgentDbxModule* module = NULL;
-#define NEEDS_CLEANUP
-
-// Useful for debugging
-#define VERBOSE_DEBUGGING
-
-#ifdef VERBOSE_DEBUGGING
-# define debug_only(x) x
-#else
-# define debug_only(x)
-#endif
-
-// For profiling
-//#define PROFILING
-
-#ifdef PROFILING
-#define PROFILE_COUNT 200
-static Timer scanTimer;
-static Timer workTimer;
-static Timer writeTimer;
-static int numRequests = 0;
-#endif /* PROFILING */
-
-const char* ServiceabilityAgentDbxModule::CMD_ADDRESS_SIZE   = "address_size";
-const char* ServiceabilityAgentDbxModule::CMD_PEEK_FAIL_FAST = "peek_fail_fast";
-const char* ServiceabilityAgentDbxModule::CMD_PEEK           = "peek";
-const char* ServiceabilityAgentDbxModule::CMD_POKE           = "poke";
-const char* ServiceabilityAgentDbxModule::CMD_MAPPED         = "mapped";
-const char* ServiceabilityAgentDbxModule::CMD_LOOKUP         = "lookup";
-const char* ServiceabilityAgentDbxModule::CMD_THR_GREGS      = "thr_gregs";
-const char* ServiceabilityAgentDbxModule::CMD_EXIT           = "exit";
-
-// The initialization routines must not have C++ name mangling
-extern "C" {
-
-/** This is the initialization routine called by dbx upon importing of
-    this module. Returns 0 upon successful initialization, -1 upon
-    failure. */
-int shell_imp_init(int major, int minor,
-                   shell_imp_interp_t interp, int argc, char *argv[])
-{
-  // Ensure shell interpreter data structure is laid out the way we
-  // expect
-  if (major != SHELL_IMP_MAJOR) {
-    debug_only(fprintf(stderr, "Serviceability agent: unexpected value for SHELL_IMP_MAJOR (got %d, expected %d)\n", major, SHELL_IMP_MAJOR);)
-    return -1;
-  }
-  if (minor < SHELL_IMP_MINOR) {
-    debug_only(fprintf(stderr, "Serviceability agent: unexpected value for SHELL_IMP_MINOR (got %d, expected >= %d)\n", minor, SHELL_IMP_MINOR);)
-    return -1;
-  }
-
-  if (module != NULL) {
-    debug_only(fprintf(stderr, "Serviceability agent: module appears to already be initialized (should not happen)\n");)
-    // Already initialized. Should not happen.
-    return -1;
-  }
-
-  module = new ServiceabilityAgentDbxModule(major, minor, interp, argc, argv);
-  if (!module->install()) {
-    debug_only(fprintf(stderr, "Serviceability agent: error installing import module\n");)
-    delete module;
-    module = NULL;
-    return -1;
-  }
-
-  // Installation was successful. Next step will be for the user to
-  // enter the appropriate command on the command line, which will
-  // make the SA's dbx module wait for commands to come in over the
-  // socket.
-  return 0;
-}
-
-/** This is the routine called by dbx upon unloading of this module.
-    Returns 0 upon success, -1 upon failure. */
-int
-shell_imp_fini(shell_imp_interp_t)
-{
-  if (module == NULL) {
-    return -1;
-  }
-
-  bool res = module->uninstall();
-  delete module;
-  module = NULL;
-  if (!res) {
-    return -1;
-  }
-  return 0;
-}
-
-} // extern "C"
-
-/** This is the routine which is called by the dbx shell when the user
-    requests the serviceability agent module to run. This delegates to
-    ServiceabilityAgentDbxModule::run. This routine's signature must
-    match that of shell_imp_fun_t. */
-extern "C" {
-static int
-svc_agent_run(shell_imp_interp_t, int, char **, void *) {
-  if (module == NULL) {
-    return -1;
-  }
-
-  module->run();
-  return 0;
-}
-}
-
-/*
- * Implementation of ServiceabilityAgentDbxModule class
- */
-
-// NOTE: we need to forward declare the special "ps_get_prochandle2"
-// function which allows examination of core files as well. It isn't
-// currently in proc_service_2.h. Note also that it has name mangling
-// because it isn't declared extern "C".
-//const struct ps_prochandle *ps_get_prochandle2(int cores_too);
-
-ServiceabilityAgentDbxModule::ServiceabilityAgentDbxModule(int, int, shell_imp_interp_t interp,
-                                                           int argc, char *argv[])
-  :myComm(32768, 131072)
-{
-  _interp = interp;
-  _argc = argc;
-  _argv = argv;
-  _tdb_agent = NULL;
-  peek_fail_fast = false;
-  libThreadName = NULL;
-}
-
-ServiceabilityAgentDbxModule::~ServiceabilityAgentDbxModule() {
-  if (_command != NULL) {
-    uninstall();
-  }
-}
-
-char*
-readCStringFromProcess(psaddr_t addr) {
-  char c;
-  int num = 0;
-  ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
-
-  // Search for null terminator
-  do {
-    if (ps_pread(cur_proc, addr + num, &c, 1) != PS_OK) {
-      return NULL;
-    }
-    ++num;
-  } while (c != 0);
-
-  // Allocate string
-  char* res = new char[num];
-  if (ps_pread(cur_proc, addr, res, num) != PS_OK) {
-    delete[] res;
-    return NULL;
-  }
-  return res;
-}
-
-int
-findLibThreadCB(const rd_loadobj_t* lo, void* data) {
-  ServiceabilityAgentDbxModule* module = (ServiceabilityAgentDbxModule*) data;
-  char* name = readCStringFromProcess(lo->rl_nameaddr);
-  if (strstr(name, "libthread.so") != NULL) {
-    module->libThreadName = name;
-    return 0;
-  } else {
-    delete[] name;
-    return 1;
-  }
-}
-
-bool
-ServiceabilityAgentDbxModule::install() {
-  // NOTE interdependency between here and Java side wrapper
-  // FIXME: casts of string literal to char * to match prototype
-  _command = shell_imp_define_command((char *) "svc_agent_run",
-                                      &svc_agent_run,
-                                      0,
-                                      NULL,
-                                      (char *) "Run the serviceability agent's dbx module.\n"
-                                      "This routine causes the module to listen on a socket for requests.\n"
-                                      "It does not return until the Java-side code tells it to exit, at\n"
-                                      "which point control is returned to the dbx shell.");
-  if (_command == NULL) {
-    debug_only(fprintf(stderr, "Serviceability agent: Failed to install svc_agent_run command\n"));
-    return false;
-  }
-
-  // This is fairly painful. Since dbx doesn't currently load
-  // libthread_db with RTLD_GLOBAL, we can't just use RTLD_DEFAULT for
-  // the argument to dlsym. Instead, we have to use rtld_db to search
-  // through the loaded objects in the target process for libthread.so and
-
-  // Try rtld_db
-  if (rd_init(RD_VERSION) != RD_OK) {
-    debug_only(fprintf(stderr, "Serviceability agent: Unable to init rtld_db\n"));
-    return false;
-  }
-
-  rd_agent_t* rda = rd_new((struct ps_prochandle*) ps_get_prochandle2(1));
-  if (rda == NULL) {
-    debug_only(fprintf(stderr, "Serviceability agent: Unable to allocate rtld_db agent\n"));
-    return false;
-  }
-
-  if (rd_loadobj_iter(rda, (rl_iter_f*) findLibThreadCB, this) != RD_OK) {
-    debug_only(fprintf(stderr, "Serviceability agent: Loadobject iteration failed\n"));
-    return false;
-  }
-
-  if (libThreadName == NULL) {
-    debug_only(fprintf(stderr, "Serviceability agent: Failed to find pathname to libthread.so in target process\n"));
-    return false;
-  }
-
-  // Find and open libthread_db.so
-  char* slash = strrchr(libThreadName, '/');
-  if (slash == NULL) {
-    debug_only(fprintf(stderr, "Serviceability agent: can't parse path to libthread.so \"%s\"\n"));
-    return false;
-  }
-
-  int slashPos = slash - libThreadName;
-  char* buf = new char[slashPos + strlen("libthread_db.so") + 20]; // slop
-  if (buf == NULL) {
-    debug_only(fprintf(stderr, "Serviceability agent: error allocating libthread_db.so pathname\n"));
-    return false;
-  }
-  strncpy(buf, libThreadName, slashPos + 1);
-
-  // Check dbx's data model; use sparcv9/ subdirectory if 64-bit and
-  // if target process is 32-bit
-  if ((sizeof(void*) == 8) &&
-      (strstr(libThreadName, "sparcv9") == NULL)) {
-    strcpy(buf + slashPos + 1, "sparcv9/");
-    slashPos += strlen("sparcv9/");
-  }
-
-  strcpy(buf + slashPos + 1, "libthread_db.so");
-
-  libThreadDB = dlopen(buf, RTLD_LAZY);
-  void* tmpDB = libThreadDB;
-  if (libThreadDB == NULL) {
-    debug_only(fprintf(stderr, "Serviceability agent: Warning: unable to find libthread_db.so at \"%s\"\n", buf));
-    // Would like to handle this case as well. Maybe dbx has a better
-    // idea of where libthread_db.so lies. If the problem with dbx
-    // loading libthread_db without RTLD_GLOBAL specified ever gets
-    // fixed, we could run this code all the time.
-    tmpDB = RTLD_DEFAULT;
-  }
-
-  delete[] buf;
-
-  // Initialize access to libthread_db
-  td_init_fn          = (td_init_fn_t*)          dlsym(tmpDB, "td_init");
-  td_ta_new_fn        = (td_ta_new_fn_t*)        dlsym(tmpDB, "td_ta_new");
-  td_ta_delete_fn     = (td_ta_delete_fn_t*)     dlsym(tmpDB, "td_ta_delete");
-  td_ta_map_id2thr_fn = (td_ta_map_id2thr_fn_t*) dlsym(tmpDB, "td_ta_map_id2thr");
-  td_thr_getgregs_fn  = (td_thr_getgregs_fn_t*)  dlsym(tmpDB, "td_thr_getgregs");
-
-  if (td_init_fn == NULL ||
-      td_ta_new_fn == NULL ||
-      td_ta_delete_fn == NULL ||
-      td_ta_map_id2thr_fn == NULL ||
-      td_thr_getgregs_fn == NULL) {
-    debug_only(fprintf(stderr, "Serviceability agent: Failed to find one or more libthread_db symbols:\n"));
-    debug_only(if (td_init_fn == NULL)          fprintf(stderr, "  td_init\n"));
-    debug_only(if (td_ta_new_fn == NULL)        fprintf(stderr, "  td_ta_new\n"));
-    debug_only(if (td_ta_delete_fn == NULL)     fprintf(stderr, "  td_ta_delete\n"));
-    debug_only(if (td_ta_map_id2thr_fn == NULL) fprintf(stderr, "  td_ta_map_id2thr\n"));
-    debug_only(if (td_thr_getgregs_fn == NULL)  fprintf(stderr, "  td_thr_getgregs\n"));
-    return false;
-  }
-
-  if ((*td_init_fn)() != TD_OK) {
-    debug_only(fprintf(stderr, "Serviceability agent: Failed to initialize libthread_db\n"));
-    return false;
-  }
-
-  return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::uninstall() {
-  if (_command == NULL) {
-    return false;
-  }
-
-  if (libThreadDB != NULL) {
-    dlclose(libThreadDB);
-    libThreadDB = NULL;
-  }
-
-  int res = shell_imp_undefine_command(_command);
-
-  if (res != 0) {
-    return false;
-  }
-
-  return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::run() {
-  // This is where most of the work gets done.
-  // The command processor loop looks like the following:
-  //  - create listening socket
-  //  - accept a connection (only one for now)
-  //  - while that connection is open and the "exit" command has not
-  //    been received:
-  //    - read command
-  //    - if it's the exit command, cleanup and return
-  //    - otherwise, process command and write result
-
-  int listening_socket = socket(AF_INET, SOCK_STREAM, 0);
-  if (listening_socket < 0) {
-    return false;
-  }
-
-  // Set the SO_REUSEADDR property on the listening socket. This
-  // prevents problems with calls to bind() to the same port failing
-  // after this process exits. This seems to work on all platforms.
-  int reuse_address = 1;
-  if (setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR,
-                 (char *)&reuse_address, sizeof(reuse_address)) < 0) {
-    close(listening_socket);
-    return false;
-  }
-
-  sockaddr_in server_address;
-  // Build the server address. We can bind the listening socket to the
-  // INADDR_ANY internet address.
-  memset((char*)&server_address, 0, sizeof(server_address));
-  server_address.sin_family = AF_INET;
-  server_address.sin_addr.s_addr = (unsigned long)htonl(INADDR_ANY);
-  server_address.sin_port = htons((short)PORT);
-
-  // Bind socket to port
-  if (bind(listening_socket, (sockaddr*) &server_address,
-           sizeof(server_address)) < 0) {
-    close(listening_socket);
-    return false;
-  }
-
-  // Arbitrarily chosen backlog of 5 (shouldn't matter since we expect
-  // at most one connection)
-  if (listen(listening_socket, 5) < 0) {
-    close(listening_socket);
-    return false;
-  }
-
-  // OK, now ready to wait for a data connection. This call to
-  // accept() will block.
-  struct sockaddr_in client_address;
-  int address_len   = sizeof(client_address);
-  int client_socket = accept(listening_socket, (sockaddr*) &client_address,
-                         &address_len);
-  // Close listening socket regardless of whether accept() succeeded.
-  // (FIXME: this may be annoying, especially during debugging, but I
-  // really feel that robustness and multiple connections should be
-  // handled higher up, e.g., at the Java level -- multiple clients
-  // could conceivably connect to the SA via RMI, and that would be a
-  // more robust solution than implementing multiple connections at
-  // this level)
-  NEEDS_CLEANUP;
-
-  // NOTE: the call to shutdown() usually fails, so don't panic if this happens
-  shutdown(listening_socket, 2);
-
-  if (close(listening_socket) < 0) {
-    debug_only(fprintf(stderr, "Serviceability agent: Error closing listening socket\n"));
-    return false;
-  }
-
-  if (client_socket < 0) {
-    debug_only(fprintf(stderr, "Serviceability agent: Failed to open client socket\n"));
-    // No more cleanup necessary
-    return false;
-  }
-
-  // Attempt to disable TCP buffering on this socket. We send small
-  // amounts of data back and forth and don't want buffering.
-  int buffer_val = 1;
-  if (setsockopt(client_socket, IPPROTO_IP, TCP_NODELAY, (char *) &buffer_val, sizeof(buffer_val)) < 0) {
-    debug_only(fprintf(stderr, "Serviceability agent: Failed to set TCP_NODELAY option on client socket\n"));
-    cleanup(client_socket);
-    return false;
-  }
-
-  // OK, we have the data socket through which we will communicate
-  // with the Java side. Wait for commands or until reading or writing
-  // caused an error.
-
-  bool should_continue = true;
-
-  myComm.setSocket(client_socket);
-
-#ifdef PROFILING
-  scanTimer.reset();
-  workTimer.reset();
-  writeTimer.reset();
-#endif
-
-  // Allocate a new thread agent for libthread_db
-  if ((*td_ta_new_fn)((ps_prochandle*) ps_get_prochandle2(1), &_tdb_agent) !=
-      TD_OK) {
-    debug_only(fprintf(stderr, "Serviceability agent: Failed to allocate thread agent\n"));
-    cleanup(client_socket);
-    return false;
-  }
-
-  do {
-    // Decided to use text to communicate between these processes.
-    // Probably will make debugging easier -- could telnet in if
-    // necessary. Will make scanning harder, but probably doesn't
-    // matter.
-
-    // Why not just do what workshop does and parse dbx's console?
-    // Probably could do that, but at least this way we are in control
-    // of the text format on both ends.
-
-    // FIXME: should have some way of synchronizing these commands
-    // between the C and Java sources.
-
-    NEEDS_CLEANUP;
-
-    // Do a blocking read of a line from the socket.
-    char *input_buffer = myComm.readLine();
-    if (input_buffer == NULL) {
-      debug_only(fprintf(stderr, "Serviceability agent: error during read: errno = %d\n", errno));
-      debug_only(perror("Serviceability agent"));
-      // Error occurred during read.
-      // FIXME: should guard against SIGPIPE
-      cleanup(client_socket);
-      return false;
-    }
-
-    // OK, now ready to scan. See README-commands.txt for syntax
-    // descriptions.
-
-    bool res = false;
-    if (!strncmp(input_buffer, CMD_ADDRESS_SIZE, strlen(CMD_ADDRESS_SIZE))) {
-      res = handleAddressSize(input_buffer + strlen(CMD_ADDRESS_SIZE));
-    } else if (!strncmp(input_buffer, CMD_PEEK_FAIL_FAST, strlen(CMD_PEEK_FAIL_FAST))) {
-      res = handlePeekFailFast(input_buffer + strlen(CMD_PEEK_FAIL_FAST));
-    } else if (!strncmp(input_buffer, CMD_PEEK, strlen(CMD_PEEK))) {
-      res = handlePeek(input_buffer + strlen(CMD_PEEK));
-    } else if (!strncmp(input_buffer, CMD_POKE, strlen(CMD_POKE))) {
-      res = handlePoke(input_buffer + strlen(CMD_POKE));
-    } else if (!strncmp(input_buffer, CMD_MAPPED, strlen(CMD_MAPPED))) {
-      res = handleMapped(input_buffer + strlen(CMD_MAPPED));
-    } else if (!strncmp(input_buffer, CMD_LOOKUP, strlen(CMD_LOOKUP))) {
-      res = handleLookup(input_buffer + strlen(CMD_LOOKUP));
-    } else if (!strncmp(input_buffer, CMD_THR_GREGS, strlen(CMD_THR_GREGS))) {
-      res = handleThrGRegs(input_buffer + strlen(CMD_THR_GREGS));
-    } else if (!strncmp(input_buffer, CMD_EXIT, strlen(CMD_EXIT))) {
-      should_continue = false;
-    }
-
-    if (should_continue) {
-      if (!res) {
-        cleanup(client_socket);
-        return false;
-      }
-    }
-
-#ifdef PROFILING
-    if (++numRequests == PROFILE_COUNT) {
-      fprintf(stderr, "%d requests: %d ms scanning, %d ms work, %d ms writing\n",
-              PROFILE_COUNT, scanTimer.total(), workTimer.total(), writeTimer.total());
-      fflush(stderr);
-      scanTimer.reset();
-      workTimer.reset();
-      writeTimer.reset();
-      numRequests = 0;
-    }
-#endif
-
-  } while (should_continue);
-
-  // Successful exit
-  cleanup(client_socket);
-  return true;
-}
-
-void
-ServiceabilityAgentDbxModule::cleanup(int client_socket) {
-  shutdown(client_socket, 2);
-  close(client_socket);
-  if (_tdb_agent != NULL) {
-    (*td_ta_delete_fn)(_tdb_agent);
-  }
-}
-
-bool
-ServiceabilityAgentDbxModule::handleAddressSize(char* data) {
-  int data_model;
-  ps_err_e result = ps_pdmodel((ps_prochandle*) ps_get_prochandle2(1),
-                               &data_model);
-  if (result != PS_OK) {
-    myComm.writeString("0");
-    myComm.flush();
-    return false;
-  }
-
-  int val;
-  switch (data_model) {
-  case PR_MODEL_ILP32:
-    val = 32;
-    break;
-  case PR_MODEL_LP64:
-    val = 64;
-    break;
-  default:
-    val = 0;
-    break;
-  }
-
-  if (!myComm.writeInt(val)) {
-    return false;
-  }
-  if (!myComm.writeEOL()) {
-    return false;
-  }
-  return myComm.flush();
-}
-
-bool
-ServiceabilityAgentDbxModule::handlePeekFailFast(char* data) {
-  unsigned int val;
-  if (!scanUnsignedInt(&data, &val)) {
-    return false;
-  }
-  peek_fail_fast = (val ? true : false);
-  return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::handlePeek(char* data) {
-  // Scan hex address, return false if failed
-  psaddr_t addr;
-#ifdef PROFILING
-  scanTimer.start();
-#endif /* PROFILING */
-  if (!scanAddress(&data, &addr)) {
-    return false;
-  }
-  unsigned int num;
-  if (!scanUnsignedInt(&data, &num)) {
-    return false;
-  }
-  if (num == 0) {
-#ifdef PROFILING
-    writeTimer.start();
-#endif /* PROFILING */
-    myComm.writeBinChar('B');
-    myComm.writeBinChar(1);
-    myComm.writeBinUnsignedInt(0);
-    myComm.writeBinChar(0);
-#ifdef PROFILING
-    writeTimer.stop();
-#endif /* PROFILING */
-    return true;
-  }
-#ifdef PROFILING
-  scanTimer.stop();
-  workTimer.start();
-#endif /* PROFILING */
-  char* buf = new char[num];
-  ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
-  ps_err_e result = ps_pread(cur_proc, addr, buf, num);
-  if (result == PS_OK) {
-    // Fast case; entire read succeeded.
-#ifdef PROFILING
-    workTimer.stop();
-    writeTimer.start();
-#endif /* PROFILING */
-    myComm.writeBinChar('B');
-    myComm.writeBinChar(1);
-    myComm.writeBinUnsignedInt(num);
-    myComm.writeBinChar(1);
-    myComm.writeBinBuf(buf, num);
-#ifdef PROFILING
-    writeTimer.stop();
-#endif /* PROFILING */
-  } else {
-#ifdef PROFILING
-    workTimer.stop();
-#endif /* PROFILING */
-
-    if (peek_fail_fast) {
-#ifdef PROFILING
-    writeTimer.start();
-#endif /* PROFILING */
-      // Fail fast
-      myComm.writeBinChar('B');
-      myComm.writeBinChar(1);
-      myComm.writeBinUnsignedInt(num);
-      myComm.writeBinChar(0);
-#ifdef PROFILING
-    writeTimer.stop();
-#endif /* PROFILING */
-    } else {
-      // Slow case: try to read one byte at a time
-      // FIXME: need better way of handling this, a la VirtualQuery
-
-      unsigned int  strideLen      = 0;
-      int           bufIdx         = 0;
-      bool          lastByteMapped = (ps_pread(cur_proc, addr, buf, 1) == PS_OK ? true : false);
-
-#ifdef PROFILING
-      writeTimer.start();
-#endif /* PROFILING */
-      myComm.writeBinChar('B');
-      myComm.writeBinChar(1);
-#ifdef PROFILING
-      writeTimer.stop();
-#endif /* PROFILING */
-
-      for (int i = 0; i < num; ++i, ++addr) {
-#ifdef PROFILING
-        workTimer.start();
-#endif /* PROFILING */
-        result = ps_pread(cur_proc, addr, &buf[bufIdx], 1);
-#ifdef PROFILING
-        workTimer.stop();
-#endif /* PROFILING */
-        bool tmpMapped = (result == PS_OK ? true : false);
-#ifdef PROFILING
-        writeTimer.start();
-#endif /* PROFILING */
-        if (tmpMapped != lastByteMapped) {
-          // State change. Write the length of the last stride.
-          myComm.writeBinUnsignedInt(strideLen);
-          if (lastByteMapped) {
-            // Stop gathering data. Write the data of the last stride.
-            myComm.writeBinChar(1);
-            myComm.writeBinBuf(buf, strideLen);
-            bufIdx = 0;
-          } else {
-            // Start gathering data to write.
-            myComm.writeBinChar(0);
-          }
-          strideLen = 0;
-          lastByteMapped = tmpMapped;
-        }
-#ifdef PROFILING
-        writeTimer.stop();
-#endif /* PROFILING */
-        if (lastByteMapped) {
-          ++bufIdx;
-        }
-        ++strideLen;
-      }
-
-      // Write last stride (must be at least one byte long by definition)
-#ifdef PROFILING
-      writeTimer.start();
-#endif /* PROFILING */
-      myComm.writeBinUnsignedInt(strideLen);
-      if (lastByteMapped) {
-        myComm.writeBinChar(1);
-        myComm.writeBinBuf(buf, strideLen);
-      } else {
-        myComm.writeBinChar(0);
-      }
-#ifdef PROFILING
-      writeTimer.stop();
-#endif /* PROFILING */
-    }
-  }
-  delete[] buf;
-  myComm.flush();
-  return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::handlePoke(char* data) {
-  // FIXME: not yet implemented
-  NEEDS_CLEANUP;
-  bool res = myComm.writeBoolAsInt(false);
-  myComm.flush();
-  return res;
-}
-
-bool
-ServiceabilityAgentDbxModule::handleMapped(char* data) {
-  // Scan address
-  psaddr_t addr;
-  if (!scanAddress(&data, &addr)) {
-    return false;
-  }
-  unsigned int num;
-  if (!scanUnsignedInt(&data, &num)) {
-    return false;
-  }
-  unsigned char val;
-  ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
-  char* buf = new char[num];
-  if (ps_pread(cur_proc, addr, buf, num) == PS_OK) {
-    myComm.writeBoolAsInt(true);
-  } else {
-    myComm.writeBoolAsInt(false);
-  }
-  delete[] buf;
-  myComm.writeEOL();
-  myComm.flush();
-  return true;
-}
-
-extern "C"
-int loadobj_iterator(const rd_loadobj_t* loadobj, void *) {
-  if (loadobj != NULL) {
-    fprintf(stderr, "loadobj_iterator: visited loadobj \"%p\"\n", (void*) loadobj->rl_nameaddr);
-    return 1;
-  }
-
-  fprintf(stderr, "loadobj_iterator: NULL loadobj\n");
-  return 0;
-}
-
-bool
-ServiceabilityAgentDbxModule::handleLookup(char* data) {
-  // Debugging: iterate over loadobjs
-  /*
-  rd_agent_t* rld_agent = rd_new((ps_prochandle*) ps_get_prochandle2(1));
-  rd_loadobj_iter(rld_agent, &loadobj_iterator, NULL);
-  rd_delete(rld_agent);
-  */
-
-#ifdef PROFILING
-  scanTimer.start();
-#endif /* PROFILING */
-
-  char* object_name = scanSymbol(&data);
-  if (object_name == NULL) {
-    return false;
-  }
-  char* symbol_name = scanSymbol(&data);
-  if (symbol_name == NULL) {
-    delete[] object_name;
-    return false;
-  }
-
-#ifdef PROFILING
-  scanTimer.stop();
-  workTimer.start();
-#endif /* PROFILING */
-
-  ps_sym_t sym;
-  // FIXME: check return values from write routines
-  ps_prochandle* process = (ps_prochandle*) ps_get_prochandle2(1);
-  ps_err_e lookup_res = ps_pglobal_sym(process,
-                                       object_name, symbol_name, &sym);
-#ifdef PROFILING
-  workTimer.stop();
-  writeTimer.start();
-#endif /* PROFILING */
-
-  delete[] object_name;
-  delete[] symbol_name;
-  if (lookup_res != PS_OK) {
-    // This is too noisy
-    //    debug_only(fprintf(stderr, "ServiceabilityAgentDbxModule::handleLookup: error %d\n", lookup_res));
-    myComm.writeString("0x0");
-  } else {
-    myComm.writeAddress((void *)sym.st_value);
-  }
-  myComm.writeEOL();
-  myComm.flush();
-
-#ifdef PROFILING
-  writeTimer.stop();
-#endif /* PROFILING */
-
-  return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::handleThrGRegs(char* data) {
-#ifdef PROFILING
-  scanTimer.start();
-#endif /* PROFILING */
-
-  unsigned int num;
-  // Get the thread ID
-  if (!scanUnsignedInt(&data, &num)) {
-    return false;
-  }
-
-#ifdef PROFILING
-  scanTimer.stop();
-  workTimer.start();
-#endif /* PROFILING */
-
-  // Map tid to thread handle
-  td_thrhandle_t thread_handle;
-  if ((*td_ta_map_id2thr_fn)(_tdb_agent, num, &thread_handle) != TD_OK) {
-    //    fprintf(stderr, "Error mapping thread ID %d to thread handle\n", num);
-    return false;
-  }
-
-  // Fetch register set
-  prgregset_t reg_set;
-  memset(reg_set, 0, sizeof(reg_set));
-  td_err_e result = (*td_thr_getgregs_fn)(&thread_handle, reg_set);
-  if ((result != TD_OK) && (result != TD_PARTIALREG)) {
-    //    fprintf(stderr, "Error fetching registers for thread handle %d: error = %d\n", num, result);
-    return false;
-  }
-
-#ifdef PROFILING
-  workTimer.stop();
-  writeTimer.start();
-#endif /* PROFILING */
-
-#if (defined(__sparc) || defined(__i386))
-  myComm.writeInt(NPRGREG);
-  myComm.writeSpace();
-  for (int i = 0; i < NPRGREG; i++) {
-    myComm.writeAddress((void *)reg_set[i]);
-    if (i == NPRGREG - 1) {
-      myComm.writeEOL();
-    } else {
-      myComm.writeSpace();
-    }
-  }
-#else
-#error  Please port ServiceabilityAgentDbxModule::handleThrGRegs to your current platform
-#endif
-
-  myComm.flush();
-
-#ifdef PROFILING
-  writeTimer.stop();
-#endif /* PROFILING */
-
-  return true;
-}
-
-//
-// Input routines
-//
-
-bool
-ServiceabilityAgentDbxModule::scanAddress(char** data, psaddr_t* addr) {
-  *addr = 0;
-
-  // Skip whitespace
-  while ((**data != 0) && (isspace(**data))) {
-    ++*data;
-  }
-
-  if (**data == 0) {
-    return false;
-  }
-
-  if (strncmp(*data, "0x", 2) != 0) {
-    return false;
-  }
-
-  *data += 2;
-
-  while ((**data != 0) && (!isspace(**data))) {
-    int val;
-    bool res = charToNibble(**data, &val);
-    if (!res) {
-      return false;
-    }
-    *addr <<= 4;
-    *addr |= val;
-    ++*data;
-  }
-
-  return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::scanUnsignedInt(char** data, unsigned int* num) {
-  *num = 0;
-
-  // Skip whitespace
-  while ((**data != 0) && (isspace(**data))) {
-    ++*data;
-  }
-
-  if (**data == 0) {
-    return false;
-  }
-
-  while ((**data != 0) && (!isspace(**data))) {
-    char cur = **data;
-    if ((cur < '0') || (cur > '9')) {
-      return false;
-    }
-    *num *= 10;
-    *num += cur - '0';
-    ++*data;
-  }
-
-  return true;
-}
-
-char*
-ServiceabilityAgentDbxModule::scanSymbol(char** data) {
-  // Skip whitespace
-  while ((**data != 0) && (isspace(**data))) {
-    ++*data;
-  }
-
-  if (**data == 0) {
-    return NULL;
-  }
-
-  // First count length
-  int len = 1; // Null terminator
-  char* tmpData = *data;
-  while ((*tmpData != 0) && (!isspace(*tmpData))) {
-    ++tmpData;
-    ++len;
-  }
-  char* buf = new char[len];
-  strncpy(buf, *data, len - 1);
-  buf[len - 1] = 0;
-  *data += len - 1;
-  return buf;
-}
-
-bool
-ServiceabilityAgentDbxModule::charToNibble(char ascii, int* value) {
-  if (ascii >= '0' && ascii <= '9') {
-    *value = ascii - '0';
-    return true;
-  } else if (ascii >= 'A' && ascii <= 'F') {
-    *value = 10 + ascii - 'A';
-    return true;
-  } else if (ascii >= 'a' && ascii <= 'f') {
-    *value = 10 + ascii - 'a';
-    return true;
-  }
-
-  return false;
-}
-
-
-char*
-ServiceabilityAgentDbxModule::readCStringFromProcess(psaddr_t addr) {
-  char c;
-  int num = 0;
-  ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
-
-  // Search for null terminator
-  do {
-    if (ps_pread(cur_proc, addr + num, &c, 1) != PS_OK) {
-      return NULL;
-    }
-    ++num;
-  } while (c != 0);
-
-  // Allocate string
-  char* res = new char[num];
-  if (ps_pread(cur_proc, addr, res, num) != PS_OK) {
-    delete[] res;
-    return NULL;
-  }
-  return res;
-}
-
-
-//--------------------------------------------------------------------------------
-// Class Timer
-//
-
-Timer::Timer() {
-  reset();
-}
-
-Timer::~Timer() {
-}
-
-void
-Timer::start() {
-  gettimeofday(&startTime, NULL);
-}
-
-void
-Timer::stop() {
-  struct timeval endTime;
-  gettimeofday(&endTime, NULL);
-  totalMicroseconds += timevalDiff(&startTime, &endTime);
-  ++counter;
-}
-
-long
-Timer::total() {
-  return (totalMicroseconds / 1000);
-}
-
-long
-Timer::average() {
-  return (long) ((double) total() / (double) counter);
-}
-
-void
-Timer::reset() {
-  totalMicroseconds = 0;
-  counter = 0;
-}
-
-long long
-Timer::timevalDiff(struct timeval* start, struct timeval* end) {
-  long long secs = end->tv_sec - start->tv_sec;
-  secs *= 1000000;
-  long long usecs = end->tv_usec - start->tv_usec;
-  return (secs + usecs);
-}
--- a/hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.hpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "shell_imp.h"
-#include "IOBuf.hpp"
-#include <sys/time.h>
-#include <thread_db.h>
-
-typedef td_err_e td_init_fn_t();
-typedef td_err_e td_ta_new_fn_t(struct ps_prochandle *, td_thragent_t **);
-typedef td_err_e td_ta_delete_fn_t(td_thragent_t *);
-typedef td_err_e td_ta_map_id2thr_fn_t(const td_thragent_t *, thread_t,  td_thrhandle_t *);
-typedef td_err_e td_thr_getgregs_fn_t(const td_thrhandle_t *, prgregset_t);
-
-class ServiceabilityAgentDbxModule {
-public:
-  ServiceabilityAgentDbxModule(int major, int minor,
-                               shell_imp_interp_t interp, int argc, char *argv[]);
-  ~ServiceabilityAgentDbxModule();
-
-  bool install();
-  bool uninstall();
-
-  /* This is invoked through the dbx command interpreter. It listens
-     on a socket for commands and does not return until it receives an
-     "exit" command. At that point control is returned to dbx's main
-     loop, at which point if the user sends an exit command to dbx's
-     shell the dbx process will exit. Returns true if completed
-     successfully, false if an error occurred while running (for
-     example, unable to bind listening socket). */
-  bool run();
-
-private:
-
-  // This must be shared between the Java and C layers
-  static const int PORT = 21928;
-
-  // Command handlers
-  bool handleAddressSize(char* data);
-  bool handlePeekFailFast(char* data);
-  bool handlePeek(char* data);
-  bool handlePoke(char* data);
-  bool handleMapped(char* data);
-  bool handleLookup(char* data);
-  bool handleThrGRegs(char* data);
-
-  // Input routines
-
-  // May mutate addr argument even if result is false
-  bool scanAddress(char** data, psaddr_t* addr);
-  // May mutate num argument even if result is false
-  bool scanUnsignedInt(char** data, unsigned int* num);
-  // Returns NULL if error occurred while scanning. Otherwise, returns
-  // newly-allocated character array which must be freed with delete[].
-  char* scanSymbol(char** data);
-  // Helper routine: converts ASCII to 4-bit integer. Returns true if
-  // character is in range, false otherwise.
-  bool charToNibble(char ascii, int* value);
-
-  // Output routines
-
-  // Writes an int with no leading or trailing spaces
-  bool writeInt(int val, int fd);
-  // Writes an address in hex format with no leading or trailing
-  // spaces
-  bool writeAddress(psaddr_t addr, int fd);
-  // Writes a register in hex format with no leading or trailing
-  // spaces (addresses and registers might be of different size)
-  bool writeRegister(prgreg_t reg, int fd);
-  // Writes a space to given file descriptor
-  bool writeSpace(int fd);
-  // Writes carriage return to given file descriptor
-  bool writeCR(int fd);
-  // Writes a bool as [0|1]
-  bool writeBoolAsInt(bool val, int fd);
-  // Helper routine: converts low 4 bits to ASCII [0..9][A..F]
-  char nibbleToChar(unsigned char nibble);
-
-  // Base routine called by most of the above
-  bool writeString(const char* str, int fd);
-
-  // Writes a binary character
-  bool writeBinChar(char val, int fd);
-  // Writes a binary unsigned int in network (big-endian) byte order
-  bool writeBinUnsignedInt(unsigned int val, int fd);
-  // Writes a binary buffer
-  bool writeBinBuf(char* buf, int size, int fd);
-
-  // Routine to flush the socket
-  bool flush(int client_socket);
-
-  void cleanup(int client_socket);
-
-  // The shell interpreter on which we can invoke commands (?)
-  shell_imp_interp_t _interp;
-
-  // The "command line" arguments passed to us by dbx (?)
-  int _argc;
-  char **_argv;
-
-  // The installed command in the dbx shell
-  shell_imp_command_t _command;
-
-  // Access to libthread_db (dlsym'ed to be able to pick up the
-  // version loaded by dbx)
-  td_init_fn_t*          td_init_fn;
-  td_ta_new_fn_t*        td_ta_new_fn;
-  td_ta_delete_fn_t*     td_ta_delete_fn;
-  td_ta_map_id2thr_fn_t* td_ta_map_id2thr_fn;
-  td_thr_getgregs_fn_t*  td_thr_getgregs_fn;
-
-  // Our "thread agent" -- access to libthread_db
-  td_thragent_t* _tdb_agent;
-
-  // Path to libthread.so in target process; free with delete[]
-  char* libThreadName;
-
-  // Handle to dlopen'ed libthread_db.so
-  void* libThreadDB;
-
-  // Helper callback for finding libthread_db.so
-  friend int findLibThreadCB(const rd_loadobj_t* lo, void* data);
-
-  // Support for reading C strings out of the target process (so we
-  // can find the correct libthread_db). Returns newly-allocated char*
-  // which must be freed with delete[], or null if the read failed.
-  char* readCStringFromProcess(psaddr_t addr);
-
-  IOBuf myComm;
-
-  // Output buffer support (used by writeString, writeChar, flush)
-  char* output_buffer;
-  int output_buffer_size;
-  int output_buffer_pos;
-
-  // "Fail fast" flag
-  bool peek_fail_fast;
-
-  // Commands
-  static const char* CMD_ADDRESS_SIZE;
-  static const char* CMD_PEEK_FAIL_FAST;
-  static const char* CMD_PEEK;
-  static const char* CMD_POKE;
-  static const char* CMD_MAPPED;
-  static const char* CMD_LOOKUP;
-  static const char* CMD_THR_GREGS;
-  static const char* CMD_EXIT;
-};
-
-// For profiling. Times reported are in milliseconds.
-class Timer {
-public:
-  Timer();
-  ~Timer();
-
-  void start();
-  void stop();
-  long total();
-  long average();
-  void reset();
-
-private:
-  struct timeval startTime;
-  long long totalMicroseconds; // stored internally in microseconds
-  int counter;
-  long long timevalDiff(struct timeval* startTime, struct timeval* endTime);
-};
--- a/hotspot/agent/src/os/win32/BasicList.hpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _BASIC_LIST_
-#define _BASIC_LIST_
-
-#include <vector>
-
-template<class T>
-class BasicList {
-protected:
-  typedef std::vector<T> InternalListType;
-  InternalListType internalList;
-
-public:
-  BasicList() {
-  }
-  virtual ~BasicList() {
-  }
-
-  void add(T arg) {
-    internalList.push_back(arg);
-  }
-
-  bool remove(T arg) {
-    for (InternalListType::iterator iter = internalList.begin();
-         iter != internalList.end(); iter++) {
-      if (*iter == arg) {
-        internalList.erase(iter);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  int size() {
-    return internalList.size();
-  }
-
-  T get(int index) {
-    return internalList[index];
-  }
-};
-
-#endif  // #defined _BASIC_LIST_
--- a/hotspot/agent/src/os/win32/Buffer.cpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "Buffer.hpp"
-
-#include <string.h>
-
-Buffer::Buffer(int bufSize) {
-  buf = new char[bufSize];
-  sz = bufSize;
-  fill = 0;
-  drain = 0;
-}
-
-Buffer::~Buffer() {
-  delete[] buf;
-}
-
-char*
-Buffer::fillPos() {
-  return buf + fill;
-}
-
-int
-Buffer::remaining() {
-  return sz - fill;
-}
-
-int
-Buffer::size() {
-  return sz;
-}
-
-bool
-Buffer::incrFillPos(int amt) {
-  if (fill + amt >= sz) {
-    return false;
-  }
-  fill += amt;
-  return true;
-}
-
-int
-Buffer::readByte() {
-  if (drain < fill) {
-    return buf[drain++] & 0xFF;
-  } else {
-    return -1;
-  }
-}
-
-int
-Buffer::readBytes(char* data, int len) {
-  int numRead = 0;
-  while (numRead < len) {
-    int c = readByte();
-    if (c < 0) break;
-    data[numRead++] = (char) c;
-  }
-  return numRead;
-}
-
-char*
-Buffer::drainPos() {
-  return buf + drain;
-}
-
-int
-Buffer::drainRemaining() {
-  return fill - drain;
-}
-
-bool
-Buffer::incrDrainPos(int amt) {
-  if (drainRemaining() < amt) {
-    return false;
-  }
-  drain += amt;
-  return true;
-}
-
-void
-Buffer::compact() {
-  // Copy down data
-  memmove(buf, buf + drain, fill - drain);
-  // Adjust positions
-  fill -= drain;
-  drain = 0;
-}
--- a/hotspot/agent/src/os/win32/Buffer.hpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _BUFFER_
-#define _BUFFER_
-
-// A Buffer is the backing store for the IOBuf abstraction and
-// supports producer-consumer filling and draining.
-
-class Buffer {
-public:
-  Buffer(int bufSize);
-  ~Buffer();
-
-  char* fillPos();   // Position of the place where buffer should be filled
-  int   remaining(); // Number of bytes that can be placed starting at fillPos
-  int   size();      // Size of the buffer
-  // Move up fill position by amount (decreases remaining()); returns
-  // false if not enough space
-  bool  incrFillPos(int amt);
-
-  // Read single byte (0..255); returns -1 if no data available.
-  int   readByte();
-  // Read multiple bytes, non-blocking (this buffer does not define a
-  // fill mechanism), into provided buffer. Returns number of bytes read.
-  int   readBytes(char* buf, int len);
-
-  // Access to drain position. Be very careful using this.
-  char* drainPos();
-  int   drainRemaining();
-  bool  incrDrainPos(int amt);
-
-  // Compact buffer, removing already-consumed input. This must be
-  // called periodically to yield the illusion of an infinite buffer.
-  void  compact();
-
-private:
-  Buffer(const Buffer&);
-  Buffer& operator=(const Buffer&);
-
-  char* buf;
-  int   sz;
-  int   fill;
-  int   drain;
-};
-
-#endif // #defined _BUFFER_
--- a/hotspot/agent/src/os/win32/Dispatcher.cpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "dispatcher.hpp"
-
-const char* CMD_ASCII         = "ascii";
-const char* CMD_UNICODE       = "unicode";
-const char* CMD_PROCLIST      = "proclist";
-const char* CMD_ATTACH        = "attach";
-const char* CMD_DETACH        = "detach";
-const char* CMD_LIBINFO       = "libinfo";
-const char* CMD_PEEK          = "peek";
-const char* CMD_POKE          = "poke";
-const char* CMD_THREADLIST    = "threadlist";
-const char* CMD_DUPHANDLE     = "duphandle";
-const char* CMD_CLOSEHANDLE   = "closehandle";
-const char* CMD_GETCONTEXT    = "getcontext";
-const char* CMD_SETCONTEXT    = "setcontext";
-const char* CMD_SELECTORENTRY = "selectorentry";
-const char* CMD_SUSPEND       = "suspend";
-const char* CMD_RESUME        = "resume";
-const char* CMD_POLLEVENT     = "pollevent";
-const char* CMD_CONTINUEEVENT = "continueevent";
-const char* CMD_EXIT          = "exit";
-
-// Uncomment the #define below to get messages on stderr
-// #define DEBUGGING
-
-void
-Dispatcher::dispatch(char* cmd, Handler* handler) {
-  if (!strncmp(cmd, CMD_ASCII, strlen(CMD_ASCII))) {
-    handler->ascii(cmd + strlen(CMD_ASCII));
-
-  } else if (!strncmp(cmd, CMD_UNICODE, strlen(CMD_UNICODE))) {
-    handler->unicode(cmd + strlen(CMD_UNICODE));
-
-  } else if (!strncmp(cmd, CMD_PROCLIST, strlen(CMD_PROCLIST))) {
-    handler->procList(cmd + strlen(CMD_PROCLIST));
-
-  } else if (!strncmp(cmd, CMD_ATTACH, strlen(CMD_ATTACH))) {
-    handler->attach(cmd + strlen(CMD_ATTACH));
-
-  } else if (!strncmp(cmd, CMD_DETACH, strlen(CMD_DETACH))) {
-    handler->detach(cmd + strlen(CMD_DETACH));
-
-  } else if (!strncmp(cmd, CMD_LIBINFO, strlen(CMD_LIBINFO))) {
-    handler->libInfo(cmd + strlen(CMD_LIBINFO));
-
-  } else if (!strncmp(cmd, CMD_PEEK, strlen(CMD_PEEK))) {
-    handler->peek(cmd + strlen(CMD_PEEK));
-
-  } else if (!strncmp(cmd, CMD_POKE, strlen(CMD_POKE))) {
-    handler->poke(cmd + strlen(CMD_POKE));
-
-  } else if (!strncmp(cmd, CMD_THREADLIST, strlen(CMD_THREADLIST))) {
-    handler->threadList(cmd + strlen(CMD_THREADLIST));
-
-  } else if (!strncmp(cmd, CMD_DUPHANDLE, strlen(CMD_DUPHANDLE))) {
-    handler->dupHandle(cmd + strlen(CMD_DUPHANDLE));
-
-  } else if (!strncmp(cmd, CMD_CLOSEHANDLE, strlen(CMD_CLOSEHANDLE))) {
-    handler->closeHandle(cmd + strlen(CMD_CLOSEHANDLE));
-
-  } else if (!strncmp(cmd, CMD_GETCONTEXT, strlen(CMD_GETCONTEXT))) {
-    handler->getContext(cmd + strlen(CMD_GETCONTEXT));
-
-  } else if (!strncmp(cmd, CMD_SETCONTEXT, strlen(CMD_SETCONTEXT))) {
-    handler->setContext(cmd + strlen(CMD_SETCONTEXT));
-
-  } else if (!strncmp(cmd, CMD_SELECTORENTRY, strlen(CMD_SELECTORENTRY))) {
-    handler->selectorEntry(cmd + strlen(CMD_SELECTORENTRY));
-
-  } else if (!strncmp(cmd, CMD_SUSPEND, strlen(CMD_SUSPEND))) {
-    handler->suspend(cmd + strlen(CMD_SUSPEND));
-
-  } else if (!strncmp(cmd, CMD_RESUME, strlen(CMD_RESUME))) {
-    handler->resume(cmd + strlen(CMD_RESUME));
-
-  } else if (!strncmp(cmd, CMD_POLLEVENT, strlen(CMD_POLLEVENT))) {
-    handler->pollEvent(cmd + strlen(CMD_POLLEVENT));
-
-  } else if (!strncmp(cmd, CMD_CONTINUEEVENT, strlen(CMD_CONTINUEEVENT))) {
-    handler->continueEvent(cmd + strlen(CMD_CONTINUEEVENT));
-
-  } else if (!strcmp(cmd, CMD_EXIT)) {
-    handler->exit(cmd + strlen(CMD_EXIT));
-  }
-
-#ifdef DEBUGGING
-  else fprintf(stderr, "Ignoring illegal command \"%s\"\n", cmd);
-#endif
-}
--- a/hotspot/agent/src/os/win32/Dispatcher.hpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _DISPATCHER_
-#define _DISPATCHER_
-
-#include "Handler.hpp"
-
-/** This class understands the commands supported by the system and
-    calls the appropriate handler routines. */
-
-class Dispatcher {
-public:
-  static void dispatch(char* cmd, Handler* handler);
-};
-
-#endif  // #defined _DISPATCHER_
--- a/hotspot/agent/src/os/win32/Handler.hpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _HANDLER_
-#define _HANDLER_
-
-/** An abstract base class encapsulating the handlers for all commands
-    understood by the system. */
-class Handler {
-public:
-  virtual void ascii(char* arg)         = 0;
-  virtual void unicode(char* arg)       = 0;
-  virtual void procList(char* arg)      = 0;
-  virtual void attach(char* arg)        = 0;
-  virtual void detach(char* arg)        = 0;
-  virtual void libInfo(char* arg)       = 0;
-  virtual void peek(char* arg)          = 0;
-  virtual void poke(char* arg)          = 0;
-  virtual void threadList(char* arg)    = 0;
-  virtual void dupHandle(char* arg)     = 0;
-  virtual void closeHandle(char* arg)   = 0;
-  virtual void getContext(char* arg)    = 0;
-  virtual void setContext(char* arg)    = 0;
-  virtual void selectorEntry(char* arg) = 0;
-  virtual void suspend(char* arg)       = 0;
-  virtual void resume(char* arg)        = 0;
-  virtual void pollEvent(char* arg)     = 0;
-  virtual void continueEvent(char* arg) = 0;
-  virtual void exit(char* arg)          = 0;
-};
-
-#endif  // #defined _HANDLER_
--- a/hotspot/agent/src/os/win32/IOBuf.cpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,490 +0,0 @@
-/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <stdio.h>
-
-// This file is currently used for os/solaris/agent too.  At some point in time
-// the source will be reorganized to avoid these ifdefs.
-
-#ifdef __sun
-  #include <string.h>
-  #include <inttypes.h>
-  #include <sys/byteorder.h>
-#endif
-
-#include "IOBuf.hpp"
-
-// Formats for printing pointers
-#ifdef _LP64
-#  define INTPTR_FORMAT "0x%016lx"
-#else /* ! _LP64 */
-#  define INTPTR_FORMAT "0x%08lx"
-#endif /* _LP64 */
-
-// Uncomment the #define below to get messages on stderr
-// #define DEBUGGING
-
-IOBuf::IOBuf(int inLen, int outLen) {
-  inBuf = new Buffer(inLen);
-  outBuf = new Buffer(outLen);
-  fd = INVALID_SOCKET;
-  outHandle = NULL;
-  usingSocket = true;
-  reset();
-}
-
-IOBuf::~IOBuf() {
-  delete inBuf;
-  delete outBuf;
-}
-
-void
-IOBuf::setSocket(SOCKET sock) {
-  fd = sock;
-  usingSocket = true;
-}
-
-// Reading/writing files is only needed and used on windows.
-#ifdef WIN32
-void
-IOBuf::setOutputFileHandle(HANDLE handle) {
-  outHandle = handle;
-  usingSocket = false;
-}
-#endif
-
-void
-IOBuf::reset() {
-  gotDataLastTime = false;
-  state          = TEXT_STATE;
-  binPos         = 0;
-  binLength      = 0;
-}
-
-IOBuf::ReadLineResult
-IOBuf::tryReadLine() {
-  return doReadLine(false);
-}
-
-char*
-IOBuf::readLine() {
-  ReadLineResult rr = doReadLine(true);
-  if (rr != RL_GOT_DATA) {
-    return NULL;
-  }
-  return getLine();
-}
-
-IOBuf::ReadLineResult
-IOBuf::doReadLine(bool shouldWait) {
-
-  if (!usingSocket) {
-    return IOBuf::RL_ERROR;
-  }
-
-  if (gotDataLastTime) {
-    curLine.clear();
-  }
-
-  int c;
-  do {
-    c = readChar(shouldWait);
-    if (c >= 0) {
-      Action act = processChar((char) c);
-      if (act == GOT_LINE) {
-        curLine.push_back('\0');
-        gotDataLastTime = true;
-        return IOBuf::RL_GOT_DATA;
-      } else if (act == SKIP_EOL_CHAR) {
-        // Do nothing
-      } else {
-        curLine.push_back((char) c);
-      }
-    }
-  } while (shouldWait || c >= 0);
-
-  gotDataLastTime = false;
-  return IOBuf::RL_NO_DATA;
-}
-
-bool
-IOBuf::flushImpl(bool moreDataToCome) {
-  int numWritten = 0;
-
-#ifdef WIN32
-  // When running on Windows and using IOBufs for inter-process
-  // communication, we need to write metadata into the stream
-  // indicating how many bytes are coming down. Five bytes are written
-  // per flush() call, four containing the integer number of bytes
-  // coming (not including the five-byte header) and one (a 0 or 1)
-  // indicating whether there is more data coming.
-  if (!usingSocket) {
-    int numToWrite = outBuf->drainRemaining();
-    char moreToCome = (moreDataToCome ? 1 : 0);
-    DWORD numBytesWritten;
-    if (!WriteFile(outHandle, &numToWrite, sizeof(int), &numBytesWritten, NULL)) {
-      return false;
-    }
-    if (numBytesWritten != sizeof(int)) {
-      return false;
-    }
-    if (!WriteFile(outHandle, &moreToCome, 1, &numBytesWritten, NULL)) {
-      return false;
-    }
-    if (numBytesWritten != 1) {
-      return false;
-    }
-  }
-#endif
-
-  while (outBuf->drainRemaining() != 0) {
-#ifdef DEBUGGING
-      fprintf(stderr, "Flushing %d bytes\n", outBuf->drainRemaining());
-#endif
-    if (usingSocket) {
-      numWritten = send(fd, outBuf->drainPos(), outBuf->drainRemaining(), 0);
-    } else {
-#ifdef WIN32
-      DWORD numBytesWritten;
-      if (!WriteFile(outHandle, outBuf->drainPos(), outBuf->drainRemaining(), &numBytesWritten, NULL)) {
-        numWritten = -1;
-      } else {
-        numWritten = numBytesWritten;
-      }
-#endif
-    }
-    if (numWritten != -1) {
-#ifdef DEBUGGING
-      fprintf(stderr, "Flushed %d bytes\n", numWritten);
-#endif
-      outBuf->incrDrainPos(numWritten);
-    } else {
-      return false;
-    }
-  }
-
-  outBuf->compact();
-
-  return true;
-}
-
-int
-IOBuf::readChar(bool block) {
-  do {
-    int c = inBuf->readByte();
-    if (c >= 0) {
-      return c;
-    }
-    // See whether we need to compact the input buffer
-    if (inBuf->remaining() < inBuf->size() / 2) {
-      inBuf->compact();
-    }
-    // See whether socket is ready
-    fd_set fds;
-    FD_ZERO(&fds);
-    FD_SET(fd, &fds);
-    struct timeval timeout;
-    timeout.tv_sec = 0;
-    timeout.tv_usec = 0;
-    if (block || select(1 + fd, &fds, NULL, NULL, &timeout) > 0) {
-      if (block || FD_ISSET(fd, &fds)) {
-#ifdef DEBUGGING
-        int b = (block ? 1 : 0);
-        fprintf(stderr, "calling recv: block = %d\n", b);
-#endif
-        // Read data from socket
-        int numRead = recv(fd, inBuf->fillPos(), inBuf->remaining(), 0);
-        if (numRead < 0) {
-#ifdef DEBUGGING
-          fprintf(stderr, "recv failed\n");
-#endif
-          return -1;
-        }
-        inBuf->incrFillPos(numRead);
-      }
-    }
-  } while (block);
-
-  return inBuf->readByte();
-}
-
-char*
-IOBuf::getLine() {
-#ifdef DEBUGGING
-  fprintf(stderr, "Returning (first 10 chars) \"%.10s\"\n", curLine.begin());
-#endif
-  return curLine.begin();
-}
-
-bool
-IOBuf::flush() {
-  return flushImpl(false);
-}
-
-bool
-IOBuf::writeString(const char* str) {
-  int len = strlen(str);
-
-  if (len > outBuf->size()) {
-    return false;
-  }
-
-  if (len > outBuf->remaining()) {
-    if (!flushImpl(true)) {
-      return false;
-    }
-  }
-
-  // NOTE we do not copy the null terminator of the string.
-
-  strncpy(outBuf->fillPos(), str, len);
-  outBuf->incrFillPos(len);
-  return true;
-}
-
-bool
-IOBuf::writeInt(int val) {
-  char buf[128];
-  sprintf(buf, "%d", val);
-  return writeString(buf);
-}
-
-bool
-IOBuf::writeUnsignedInt(unsigned int val) {
-  char buf[128];
-  sprintf(buf, "%u", val);
-  return writeString(buf);
-}
-
-bool
-IOBuf::writeBoolAsInt(bool val) {
-  if (val) {
-    return writeString("1");
-  } else {
-    return writeString("0");
-  }
-}
-
-bool
-IOBuf::writeAddress(void* val) {
-  char buf[128];
-  sprintf(buf, INTPTR_FORMAT, val);
-  return writeString(buf);
-}
-
-bool
-IOBuf::writeSpace() {
-  return writeString(" ");
-}
-
-bool
-IOBuf::writeEOL() {
-  return writeString("\n\r");
-}
-
-bool
-IOBuf::writeBinChar(char c) {
-  return writeBinBuf((char*) &c, sizeof(c));
-}
-
-bool
-IOBuf::writeBinUnsignedShort(unsigned short i) {
-  i = htons(i);
-  return writeBinBuf((char*) &i, sizeof(i));
-}
-
-bool
-IOBuf::writeBinUnsignedInt(unsigned int i) {
-  i = htonl(i);
-  return writeBinBuf((char*) &i, sizeof(i));
-}
-
-bool
-IOBuf::writeBinBuf(char* buf, int size) {
-  while (size > 0) {
-    int spaceRemaining = outBuf->remaining();
-    if (spaceRemaining == 0) {
-      if (!flushImpl(true)) {
-        return false;
-      }
-      spaceRemaining = outBuf->remaining();
-    }
-    int toCopy = (size > spaceRemaining) ? spaceRemaining : size;
-    memcpy(outBuf->fillPos(), buf, toCopy);
-    outBuf->incrFillPos(toCopy);
-    buf += toCopy;
-    size -= toCopy;
-    if (size > 0) {
-      if (!flushImpl(true)) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-#ifdef WIN32
-IOBuf::FillState
-IOBuf::fillFromFileHandle(HANDLE fh, DWORD* numBytesRead) {
-  int totalToRead;
-  char moreToCome;
-
-  outBuf->compact();
-
-  DWORD numRead;
-  if (!ReadFile(fh, &totalToRead, sizeof(int), &numRead, NULL)) {
-    return FAILED;
-  }
-  if (numRead != sizeof(int)) {
-    return FAILED;
-  }
-  if (!ReadFile(fh, &moreToCome, 1, &numRead, NULL)) {
-    return FAILED;
-  }
-  if (numRead != 1) {
-    return FAILED;
-  }
-  if (outBuf->remaining() < totalToRead) {
-    return FAILED;
-  }
-
-  int tmp = totalToRead;
-
-  while (totalToRead > 0) {
-    if (!ReadFile(fh, outBuf->fillPos(), totalToRead, &numRead, NULL)) {
-      return FAILED;
-    }
-    outBuf->incrFillPos((int) numRead);
-    totalToRead -= numRead;
-  }
-
-  *numBytesRead = tmp;
-  return ((moreToCome == 0) ? DONE : MORE_DATA_PENDING);
-}
-#endif
-
-bool
-IOBuf::isBinEscapeChar(char c) {
-  return (c == '|');
-}
-
-IOBuf::Action
-IOBuf::processChar(char c) {
-  Action action = NO_ACTION;
-  switch (state) {
-  case TEXT_STATE: {
-    // Looking for text char, bin escape char, or EOL
-    if (isBinEscapeChar(c)) {
-#ifdef DEBUGGING
-      fprintf(stderr, "[a: '%c'] ", inBuf[0]);
-#endif
-      binPos = 0;
-#ifdef DEBUGGING
-      fprintf(stderr, "[b: '%c'] ", inBuf[0]);
-#endif
-      binLength = 0;
-#ifdef DEBUGGING
-      fprintf(stderr, "[c: '%c'] ", inBuf[0]);
-#endif
-      state = BIN_STATE;
-#ifdef DEBUGGING
-      fprintf(stderr, "[d: '%c'] ", inBuf[0]);
-#endif
-#ifdef DEBUGGING
-      fprintf(stderr, "\nSwitching to BIN_STATE\n");
-#endif
-    } else if (isEOL(c)) {
-      state = EOL_STATE;
-      action = GOT_LINE;
-#ifdef DEBUGGING
-      fprintf(stderr, "\nSwitching to EOL_STATE (GOT_LINE)\n");
-#endif
-    }
-#ifdef DEBUGGING
-    else {
-      fprintf(stderr, "'%c' ", c);
-      fflush(stderr);
-    }
-#endif
-    break;
-  }
-
-  case BIN_STATE: {
-    // Seeking to finish read of input
-    if (binPos < 4) {
-      int cur = c & 0xFF;
-      binLength <<= 8;
-      binLength |= cur;
-      ++binPos;
-    } else {
-#ifdef DEBUGGING
-      fprintf(stderr, "Reading binary byte %d of %d\n",
-              binPos - 4, binLength);
-#endif
-      ++binPos;
-      if (binPos == 4 + binLength) {
-        state = TEXT_STATE;
-#ifdef DEBUGGING
-        fprintf(stderr, "Switching to TEXT_STATE\n");
-#endif
-      }
-    }
-    break;
-  }
-
-  case EOL_STATE: {
-    // More EOL characters just cause us to re-enter this state
-    if (isEOL(c)) {
-      action = SKIP_EOL_CHAR;
-    } else if (isBinEscapeChar(c)) {
-      binPos = 0;
-      binLength = 0;
-      state = BIN_STATE;
-    } else {
-      state = TEXT_STATE;
-#ifdef DEBUGGING
-      fprintf(stderr, "'%c' ", c);
-      fflush(stderr);
-#endif
-    }
-    break;
-  }
-
-  } // switch
-
-  return action;
-}
-
-
-bool
-IOBuf::isEOL(char c) {
-#ifdef WIN32
-  return ((c == '\n') || (c == '\r'));
-#elif defined(__sun)
-  return c == '\n';
-#else
-  #error Please port isEOL() to your platform
-  return false;
-#endif
-}
--- a/hotspot/agent/src/os/win32/IOBuf.hpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _IO_BUF_
-#define _IO_BUF_
-
-// This file is currently used for os/solaris/agent/ too.  At some point in time
-// the source will be reorganized to avoid these ifdefs.
-// Note that this class can read/write from a file as well as a socket.  This
-// file capability is only implemented on win32.
-
-#ifdef WIN32
-  #include <winsock2.h>
-#else
-  #include <sys/types.h>
-  #include <sys/socket.h>
-  // These are from win32 winsock2.h
-  typedef unsigned int SOCKET;
-  typedef void * HANDLE;
-  typedef unsigned long DWORD;
-  #define INVALID_SOCKET (SOCKET)(~0)
-#endif
-
-#include <vector>
-#include "Buffer.hpp"
-
-/** Manages an input/output buffer pair for a socket or file handle. */
-class IOBuf {
-public:
-  IOBuf(int inBufLen, int outBufLen);
-  ~IOBuf();
-
-  enum ReadLineResult {
-    RL_GOT_DATA,
-    RL_NO_DATA,
-    RL_ERROR
-  };
-
-  /** Change the socket with which this buffer is associated */
-  void setSocket(SOCKET sock);
-
-  // Reading/writing files is only supported on windows.
-#ifdef WIN32
-  /** Change the output file handle with which this buffer is
-      associated. Currently IOBufs can not be used to read from a file
-      handle. */
-  void setOutputFileHandle(HANDLE handle);
-#endif
-
-  /** Reset the input and output buffers, without flushing the output
-      data to the socket */
-  void reset();
-
-  /** Try to read a line of data from the given socket without
-      blocking. If was able to read a complete line of data, returns a
-      character pointer to the beginning of the (null-terminated)
-      string. If not, returns NULL, but maintains enough state that
-      subsequent calls to tryReadLine() will not ignore the data
-      already read. NOTE: this skips end-of-line characters (typically
-      CR/LF) as defined by "isEOL()". When switching back and forth
-      between binary and text modes, to be sure no data is lost, pad
-      the beginning and end of the binary transmission with bytes
-      which can not be confused with these characters. */
-  ReadLineResult tryReadLine();
-
-  /** Read a line of data from the given socket, blocking until a
-      line, including EOL, appears.  Return the line, or NULL if
-      something goes wrong. */
-  char *readLine();
-
-  /** Get the pointer to the beginning of the (null-terminated) line.
-      This should only be called if tryReadLine() has returned
-      RL_GOT_DATA. This sets the "parsing cursor" to the beginning of
-      the line. */
-  char* getLine();
-
-  // NOTE: any further data-acquisition routines must ALWAYS call
-  // fixupData() at the beginning!
-
-  //----------------------------------------------------------------------
-  // Output routines
-  //
-
-  /** Flush the output buffer to the socket. Returns true if
-      succeeded, false if write error occurred. */
-  bool flush();
-
-  /** Write the given string to the output buffer. May flush if output
-      buffer becomes too full to store the data. Not guaranteed to
-      work if string is longer than the size of the output buffer.
-      Does not include the null terminator of the string. Returns true
-      if succeeded, false if write error occurred. */
-  bool writeString(const char* str);
-
-  /** Write the given int to the output buffer. May flush if output
-      buffer becomes too full to store the data. Returns true if
-      succeeded, false if write error occurred. */
-  bool writeInt(int val);
-
-  /** Write the given unsigned int to the output buffer. May flush if
-      output buffer becomes too full to store the data. Returns true
-      if succeeded, false if write error occurred. */
-  bool writeUnsignedInt(unsigned int val);
-
-  /** Write the given boolean to the output buffer. May flush if
-      output buffer becomes too full to store the data. Returns true
-      if succeeded, false if write error occurred. */
-  bool writeBoolAsInt(bool val);
-
-  /** Write the given address to the output buffer. May flush if
-      output buffer becomes too full to store the data. Returns true
-      if succeeded, false if write error occurred. */
-  bool writeAddress(void* val);
-
-  /** Writes a space to the output buffer. May flush if output buffer
-      becomes too full to store the data. Returns true if succeeded,
-      false if write error occurred. */
-  bool writeSpace();
-
-  /** Writes an end-of-line sequence to the output buffer. May flush
-      if output buffer becomes too full to store the data. Returns
-      true if succeeded, false if write error occurred. */
-  bool writeEOL();
-
-  /** Writes a binary character to the output buffer. */
-  bool writeBinChar(char c);
-
-  /** Writes a binary unsigned short in network (big-endian) byte
-      order to the output buffer. */
-  bool writeBinUnsignedShort(unsigned short i);
-
-  /** Writes a binary unsigned int in network (big-endian) byte order
-      to the output buffer. */
-  bool writeBinUnsignedInt(unsigned int i);
-
-  /** Writes a binary buffer to the output buffer. */
-  bool writeBinBuf(char* buf, int size);
-
-#ifdef WIN32
-  enum FillState {
-    DONE = 1,
-    MORE_DATA_PENDING = 2,
-    FAILED = 3
-  };
-
-  /** Very specialized routine; fill the output buffer from the given
-      file handle. Caller is responsible for ensuring that there is
-      data to be read on the file handle. */
-  FillState fillFromFileHandle(HANDLE fh, DWORD* numRead);
-#endif
-
-  /** Binary utility routine (for poke) */
-  static bool isBinEscapeChar(char c);
-
-private:
-  IOBuf(const IOBuf&);
-  IOBuf& operator=(const IOBuf&);
-
-  // Returns -1 if non-blocking and no data available
-  int readChar(bool block);
-  // Line-oriented reading
-  std::vector<char> curLine;
-  bool gotDataLastTime;
-
-  ReadLineResult doReadLine(bool);
-
-  bool flushImpl(bool moreDataToCome);
-
-  SOCKET fd;
-  HANDLE outHandle;
-  bool usingSocket;
-
-  // Buffers
-  Buffer* inBuf;
-  Buffer* outBuf;
-
-  // Simple finite-state machine to handle binary data
-  enum State {
-    TEXT_STATE,
-    BIN_STATE,
-    EOL_STATE
-  };
-  enum Action {
-    NO_ACTION,
-    GOT_LINE,     // TEXT_STATE -> EOL_STATE transition
-    SKIP_EOL_CHAR // EOL_STATE -> EOL_STATE transition
-  };
-
-  State state;
-  Action processChar(char c);
-
-  // Handling incoming binary buffers (poke command)
-  int   binPos;    // Number of binary characters read so far;
-                   // total number to read is binLength + 4
-  int   binLength; // Number of binary characters in message;
-                   // not valid until binPos >= 4
-
-  bool isEOL(char c);
-};
-
-#endif  // #defined _IO_BUF_
--- a/hotspot/agent/src/os/win32/LockableList.hpp	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _LOCKABLE_LIST_
-#define _LOCKABLE_LIST_
-
-#include <windows.h>
-#include "BasicList.hpp"
-
-template<class T>
-class LockableList : public BasicList<T> {
-private:
-  CRITICAL_SECTION crit;
-
-public:
-  LockableList() {
-    InitializeCriticalSection(&crit);
-  }
-
-  ~LockableList() {
-    DeleteCriticalSection(&crit);
-  }
-
-  void lock() {
-    EnterCriticalSection(&crit);
-  }
-
-  void unlock() {
-    LeaveCriticalSection(&crit);
-  }
-};
-
-#endif  // #defined _LOCKABLE_LIST_
--- a/hotspot/agent/src/os/win32/Makefile	Thu Sep 29 18:53:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-#
-# Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#  
-#
-
-SERVER=SwDbgSrv.exe
-SUBPROCESS=SwDbgSub.exe
-
-SERVER_SOURCES =   \
-  Buffer.cpp       \
-  Dispatcher.cpp   \
-  initWinsock.cpp  \
-  IOBuf.cpp        \
-  ioUtils.cpp      \
-  isNT4.cpp        \
-  nt4internals.cpp \
-  procList.cpp     \
-  Reaper.cpp       \
-  SwDbgSrv.cpp     \
-  serverLists.cpp  \
-  toolHelp.cpp
-
-SUBPROCESS_SOURCES = \
-  SwDbgSub.cpp       \
-  Buffer.cpp         \
-  IOBuf.cpp          \
-  isNT4.cpp          \
-  libInfo.cpp        \
-  Monitor.cpp        \
-  nt4internals.cpp   \
-  toolHelp.cpp
-
-SERVER_OBJS     = $(SERVER_SOURCES:.cpp=.obj)
-SUBPROCESS_OBJS = $(SUBPROCESS_SOURCES:.cpp=.obj)
-
-CPP=cl.exe
-LINK32=link.exe
-
-# These do not need to be optimized (don't run a lot of code) and it
-# will be useful to have the assertion checks in place
-
-CFLAGS=/nologo /MD /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-
-LIBS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib          \
-     ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib     \
-     winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib \
-     odbccp32.lib ws2_32.lib  /nologo /subsystem:console /debug /machine:I386
-
-default: $(SERVER) $(SUBPROCESS)
-
-$(SERVER): $(SERVER_OBJS)
-	$(LINK32) /out:$@ $(SERVER_OBJS) $(LIBS)
-
-$(SUBPROCESS): $(SUBPROCESS_OBJS)
-	$(LINK32) /out:$@ $(SUBPROCESS_OBJS) $(LIBS)
-
-clean:
-	rm -f *.obj *.idb *.pch *.pdb *.ncb *.opt *.plg *.exe *.ilk
-
-.cpp.obj:
-	@ $(CPP) $(CFLAGS) /o $@ $<
--- a/hotspot/agent/src/os/win32/Message.hpp	Thu Sep 29 18:53:49 2011 -0700