1 /*
   2  * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <ctype.h>
  27 
  28 #include "util.h"
  29 #include "transport.h"
  30 #include "eventHandler.h"
  31 #include "threadControl.h"
  32 #include "outStream.h"
  33 #include "inStream.h"
  34 #include "invoker.h"
  35 
  36 /* Global data area */
  37 BackendGlobalData *gdata = NULL;
  38 
  39 /* Forward declarations */
  40 static jboolean isInterface(jclass clazz);
  41 static jboolean isArrayClass(jclass clazz);
  42 static char * getPropertyUTF8(JNIEnv *env, char *propertyName);
  43 
  44 /* Save an object reference for use later (create a NewGlobalRef) */
  45 void
  46 saveGlobalRef(JNIEnv *env, jobject obj, jobject *pobj)
  47 {
  48     jobject newobj;
  49 
  50     if ( pobj == NULL ) {
  51         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef pobj");
  52     }
  53     if ( *pobj != NULL ) {
  54         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef *pobj");
  55     }
  56     if ( env == NULL ) {
  57         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef env");
  58     }
  59     if ( obj == NULL ) {
  60         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef obj");
  61     }
  62     newobj = JNI_FUNC_PTR(env,NewGlobalRef)(env, obj);
  63     if ( newobj == NULL ) {
  64         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"NewGlobalRef");
  65     }
  66     *pobj = newobj;
  67 }
  68 
  69 /* Toss a previously saved object reference */
  70 void
  71 tossGlobalRef(JNIEnv *env, jobject *pobj)
  72 {
  73     jobject obj;
  74 
  75     if ( pobj == NULL ) {
  76         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"tossGlobalRef pobj");
  77     }
  78     obj = *pobj;
  79     if ( env == NULL ) {
  80         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"tossGlobalRef env");
  81     }
  82     if ( obj == NULL ) {
  83         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"tossGlobalRef obj");
  84     }
  85     JNI_FUNC_PTR(env,DeleteGlobalRef)(env, obj);
  86     *pobj = NULL;
  87 }
  88 
  89 static jclass
  90 findClass(JNIEnv *env, const char * name)
  91 {
  92     jclass x;
  93 
  94     if ( env == NULL ) {
  95         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"findClass env");
  96     }
  97     if ( name == NULL || name[0] == 0 ) {
  98         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"findClass name");
  99     }
 100     x = JNI_FUNC_PTR(env,FindClass)(env, name);
 101     if (x == NULL) {
 102         ERROR_MESSAGE(("JDWP Can't find class %s", name));
 103         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
 104     }
 105     if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) {
 106         ERROR_MESSAGE(("JDWP Exception occurred finding class %s", name));
 107         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
 108     }
 109     return x;
 110 }
 111 
 112 static jmethodID
 113 getMethod(JNIEnv *env, jclass clazz, const char * name, const char *signature)
 114 {
 115     jmethodID method;
 116 
 117     if ( env == NULL ) {
 118         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod env");
 119     }
 120     if ( clazz == NULL ) {
 121         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod clazz");
 122     }
 123     if ( name == NULL || name[0] == 0 ) {
 124         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod name");
 125     }
 126     if ( signature == NULL || signature[0] == 0 ) {
 127         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod signature");
 128     }
 129     method = JNI_FUNC_PTR(env,GetMethodID)(env, clazz, name, signature);
 130     if (method == NULL) {
 131         ERROR_MESSAGE(("JDWP Can't find method %s with signature %s",
 132                                 name, signature));
 133         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
 134     }
 135     if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) {
 136         ERROR_MESSAGE(("JDWP Exception occurred finding method %s with signature %s",
 137                                 name, signature));
 138         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
 139     }
 140     return method;
 141 }
 142 
 143 static jmethodID
 144 getStaticMethod(JNIEnv *env, jclass clazz, const char * name, const char *signature)
 145 {
 146     jmethodID method;
 147 
 148     if ( env == NULL ) {
 149         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod env");
 150     }
 151     if ( clazz == NULL ) {
 152         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod clazz");
 153     }
 154     if ( name == NULL || name[0] == 0 ) {
 155         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod name");
 156     }
 157     if ( signature == NULL || signature[0] == 0 ) {
 158         EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod signature");
 159     }
 160     method = JNI_FUNC_PTR(env,GetStaticMethodID)(env, clazz, name, signature);
 161     if (method == NULL) {
 162         ERROR_MESSAGE(("JDWP Can't find method %s with signature %s",
 163                                 name, signature));
 164         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
 165     }
 166     if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) {
 167         ERROR_MESSAGE(("JDWP Exception occurred finding method %s with signature %s",
 168                                 name, signature));
 169         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
 170     }
 171     return method;
 172 }
 173 
 174 void
 175 util_initialize(JNIEnv *env)
 176 {
 177     WITH_LOCAL_REFS(env, 6) {
 178 
 179         jvmtiError error;
 180         jclass localClassClass;
 181         jclass localThreadClass;
 182         jclass localThreadGroupClass;
 183         jclass localClassLoaderClass;
 184         jclass localStringClass;
 185         jclass localSystemClass;
 186         jclass localPropertiesClass;
 187         jclass localVMSupportClass;
 188         jobject localAgentProperties;
 189         jmethodID getAgentProperties;
 190         jint groupCount;
 191         jthreadGroup *groups;
 192         jthreadGroup localSystemThreadGroup;
 193 
 194         /* Find some standard classes */
 195 
 196         localClassClass         = findClass(env,"java/lang/Class");
 197         localThreadClass        = findClass(env,"java/lang/Thread");
 198         localThreadGroupClass   = findClass(env,"java/lang/ThreadGroup");
 199         localClassLoaderClass   = findClass(env,"java/lang/ClassLoader");
 200         localStringClass        = findClass(env,"java/lang/String");
 201         localSystemClass        = findClass(env,"java/lang/System");
 202         localPropertiesClass    = findClass(env,"java/util/Properties");
 203 
 204         /* Save references */
 205 
 206         saveGlobalRef(env, localClassClass,       &(gdata->classClass));
 207         saveGlobalRef(env, localThreadClass,      &(gdata->threadClass));
 208         saveGlobalRef(env, localThreadGroupClass, &(gdata->threadGroupClass));
 209         saveGlobalRef(env, localClassLoaderClass, &(gdata->classLoaderClass));
 210         saveGlobalRef(env, localStringClass,      &(gdata->stringClass));
 211         saveGlobalRef(env, localSystemClass,      &(gdata->systemClass));
 212 
 213         /* Find some standard methods */
 214 
 215         gdata->threadConstructor =
 216                 getMethod(env, gdata->threadClass,
 217                     "<init>", "(Ljava/lang/ThreadGroup;Ljava/lang/String;)V");
 218         gdata->threadSetDaemon =
 219                 getMethod(env, gdata->threadClass, "setDaemon", "(Z)V");
 220         gdata->threadResume =
 221                 getMethod(env, gdata->threadClass, "resume", "()V");
 222         gdata->systemGetProperty =
 223                 getStaticMethod(env, gdata->systemClass,
 224                     "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
 225         gdata->setProperty =
 226                 getMethod(env, localPropertiesClass,
 227                     "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
 228 
 229         /* Find the system thread group */
 230 
 231         groups = NULL;
 232         groupCount = 0;
 233         error = JVMTI_FUNC_PTR(gdata->jvmti,GetTopThreadGroups)
 234                     (gdata->jvmti, &groupCount, &groups);
 235         if (error != JVMTI_ERROR_NONE ) {
 236             EXIT_ERROR(error, "Can't get system thread group");
 237         }
 238         if ( groupCount == 0 ) {
 239             EXIT_ERROR(AGENT_ERROR_NULL_POINTER, "Can't get system thread group");
 240         }
 241         localSystemThreadGroup = groups[0];
 242         saveGlobalRef(env, localSystemThreadGroup, &(gdata->systemThreadGroup));
 243 
 244         /* Get some basic Java property values we will need at some point */
 245         gdata->property_java_version
 246                         = getPropertyUTF8(env, "java.version");
 247         gdata->property_java_vm_name
 248                         = getPropertyUTF8(env, "java.vm.name");
 249         gdata->property_java_vm_info
 250                         = getPropertyUTF8(env, "java.vm.info");
 251         gdata->property_java_class_path
 252                         = getPropertyUTF8(env, "java.class.path");
 253         gdata->property_sun_boot_class_path
 254                         = getPropertyUTF8(env, "sun.boot.class.path");
 255         gdata->property_sun_boot_library_path
 256                         = getPropertyUTF8(env, "sun.boot.library.path");
 257         gdata->property_path_separator
 258                         = getPropertyUTF8(env, "path.separator");
 259         gdata->property_user_dir
 260                         = getPropertyUTF8(env, "user.dir");
 261 
 262         /* Get agent properties: invoke sun.misc.VMSupport.getAgentProperties */
 263         localVMSupportClass = JNI_FUNC_PTR(env,FindClass)
 264                                           (env, "sun/misc/VMSupport");
 265         if (localVMSupportClass == NULL) {
 266             gdata->agent_properties = NULL;
 267             if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
 268                 JNI_FUNC_PTR(env,ExceptionClear)(env);
 269             }
 270         } else {
 271             getAgentProperties  =
 272                 getStaticMethod(env, localVMSupportClass,
 273                                 "getAgentProperties", "()Ljava/util/Properties;");
 274             localAgentProperties =
 275                 JNI_FUNC_PTR(env,CallStaticObjectMethod)
 276                             (env, localVMSupportClass, getAgentProperties);
 277             saveGlobalRef(env, localAgentProperties, &(gdata->agent_properties));
 278             if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
 279                 JNI_FUNC_PTR(env,ExceptionClear)(env);
 280                 EXIT_ERROR(AGENT_ERROR_INTERNAL,
 281                     "Exception occurred calling sun.misc.VMSupport.getAgentProperties");
 282             }
 283         }
 284 
 285     } END_WITH_LOCAL_REFS(env);
 286 
 287 }
 288 
 289 void
 290 util_reset(void)
 291 {
 292 }
 293 
 294 jboolean
 295 isObjectTag(jbyte tag) {
 296     return (tag == JDWP_TAG(OBJECT)) ||
 297            (tag == JDWP_TAG(STRING)) ||
 298            (tag == JDWP_TAG(THREAD)) ||
 299            (tag == JDWP_TAG(THREAD_GROUP)) ||
 300            (tag == JDWP_TAG(CLASS_LOADER)) ||
 301            (tag == JDWP_TAG(CLASS_OBJECT)) ||
 302            (tag == JDWP_TAG(ARRAY));
 303 }
 304 
 305 jbyte
 306 specificTypeKey(JNIEnv *env, jobject object)
 307 {
 308     if (object == NULL) {
 309         return JDWP_TAG(OBJECT);
 310     } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->stringClass)) {
 311         return JDWP_TAG(STRING);
 312     } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadClass)) {
 313         return JDWP_TAG(THREAD);
 314     } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadGroupClass)) {
 315         return JDWP_TAG(THREAD_GROUP);
 316     } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classLoaderClass)) {
 317         return JDWP_TAG(CLASS_LOADER);
 318     } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classClass)) {
 319         return JDWP_TAG(CLASS_OBJECT);
 320     } else {
 321         jboolean classIsArray;
 322 
 323         WITH_LOCAL_REFS(env, 1) {
 324             jclass clazz;
 325             clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
 326             classIsArray = isArrayClass(clazz);
 327         } END_WITH_LOCAL_REFS(env);
 328 
 329         return (classIsArray ? JDWP_TAG(ARRAY) : JDWP_TAG(OBJECT));
 330     }
 331 }
 332 
 333 static void
 334 writeFieldValue(JNIEnv *env, PacketOutputStream *out, jobject object,
 335                 jfieldID field)
 336 {
 337     jclass clazz;
 338     char *signature = NULL;
 339     jvmtiError error;
 340     jbyte typeKey;
 341 
 342     clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
 343     error = fieldSignature(clazz, field, NULL, &signature, NULL);
 344     if (error != JVMTI_ERROR_NONE) {
 345         outStream_setError(out, map2jdwpError(error));
 346         return;
 347     }
 348     typeKey = signature[0];
 349     jvmtiDeallocate(signature);
 350 
 351     /*
 352      * For primitive types, the type key is bounced back as is. Objects
 353      * are handled in the switch statement below.
 354      */
 355     if ((typeKey != JDWP_TAG(OBJECT)) && (typeKey != JDWP_TAG(ARRAY))) {
 356         (void)outStream_writeByte(out, typeKey);
 357     }
 358 
 359     switch (typeKey) {
 360         case JDWP_TAG(OBJECT):
 361         case JDWP_TAG(ARRAY):   {
 362             jobject value = JNI_FUNC_PTR(env,GetObjectField)(env, object, field);
 363             (void)outStream_writeByte(out, specificTypeKey(env, value));
 364             (void)outStream_writeObjectRef(env, out, value);
 365             break;
 366         }
 367 
 368         case JDWP_TAG(BYTE):
 369             (void)outStream_writeByte(out,
 370                       JNI_FUNC_PTR(env,GetByteField)(env, object, field));
 371             break;
 372 
 373         case JDWP_TAG(CHAR):
 374             (void)outStream_writeChar(out,
 375                       JNI_FUNC_PTR(env,GetCharField)(env, object, field));
 376             break;
 377 
 378         case JDWP_TAG(FLOAT):
 379             (void)outStream_writeFloat(out,
 380                       JNI_FUNC_PTR(env,GetFloatField)(env, object, field));
 381             break;
 382 
 383         case JDWP_TAG(DOUBLE):
 384             (void)outStream_writeDouble(out,
 385                       JNI_FUNC_PTR(env,GetDoubleField)(env, object, field));
 386             break;
 387 
 388         case JDWP_TAG(INT):
 389             (void)outStream_writeInt(out,
 390                       JNI_FUNC_PTR(env,GetIntField)(env, object, field));
 391             break;
 392 
 393         case JDWP_TAG(LONG):
 394             (void)outStream_writeLong(out,
 395                       JNI_FUNC_PTR(env,GetLongField)(env, object, field));
 396             break;
 397 
 398         case JDWP_TAG(SHORT):
 399             (void)outStream_writeShort(out,
 400                       JNI_FUNC_PTR(env,GetShortField)(env, object, field));
 401             break;
 402 
 403         case JDWP_TAG(BOOLEAN):
 404             (void)outStream_writeBoolean(out,
 405                       JNI_FUNC_PTR(env,GetBooleanField)(env, object, field));
 406             break;
 407     }
 408 }
 409 
 410 static void
 411 writeStaticFieldValue(JNIEnv *env, PacketOutputStream *out, jclass clazz,
 412                       jfieldID field)
 413 {
 414     jvmtiError error;
 415     char *signature = NULL;
 416     jbyte typeKey;
 417 
 418     error = fieldSignature(clazz, field, NULL, &signature, NULL);
 419     if (error != JVMTI_ERROR_NONE) {
 420         outStream_setError(out, map2jdwpError(error));
 421         return;
 422     }
 423     typeKey = signature[0];
 424     jvmtiDeallocate(signature);
 425 
 426     /*
 427      * For primitive types, the type key is bounced back as is. Objects
 428      * are handled in the switch statement below.
 429      */
 430     if ((typeKey != JDWP_TAG(OBJECT)) && (typeKey != JDWP_TAG(ARRAY))) {
 431         (void)outStream_writeByte(out, typeKey);
 432     }
 433 
 434     switch (typeKey) {
 435         case JDWP_TAG(OBJECT):
 436         case JDWP_TAG(ARRAY):   {
 437             jobject value = JNI_FUNC_PTR(env,GetStaticObjectField)(env, clazz, field);
 438             (void)outStream_writeByte(out, specificTypeKey(env, value));
 439             (void)outStream_writeObjectRef(env, out, value);
 440             break;
 441         }
 442 
 443         case JDWP_TAG(BYTE):
 444             (void)outStream_writeByte(out,
 445                       JNI_FUNC_PTR(env,GetStaticByteField)(env, clazz, field));
 446             break;
 447 
 448         case JDWP_TAG(CHAR):
 449             (void)outStream_writeChar(out,
 450                       JNI_FUNC_PTR(env,GetStaticCharField)(env, clazz, field));
 451             break;
 452 
 453         case JDWP_TAG(FLOAT):
 454             (void)outStream_writeFloat(out,
 455                       JNI_FUNC_PTR(env,GetStaticFloatField)(env, clazz, field));
 456             break;
 457 
 458         case JDWP_TAG(DOUBLE):
 459             (void)outStream_writeDouble(out,
 460                       JNI_FUNC_PTR(env,GetStaticDoubleField)(env, clazz, field));
 461             break;
 462 
 463         case JDWP_TAG(INT):
 464             (void)outStream_writeInt(out,
 465                       JNI_FUNC_PTR(env,GetStaticIntField)(env, clazz, field));
 466             break;
 467 
 468         case JDWP_TAG(LONG):
 469             (void)outStream_writeLong(out,
 470                       JNI_FUNC_PTR(env,GetStaticLongField)(env, clazz, field));
 471             break;
 472 
 473         case JDWP_TAG(SHORT):
 474             (void)outStream_writeShort(out,
 475                       JNI_FUNC_PTR(env,GetStaticShortField)(env, clazz, field));
 476             break;
 477 
 478         case JDWP_TAG(BOOLEAN):
 479             (void)outStream_writeBoolean(out,
 480                       JNI_FUNC_PTR(env,GetStaticBooleanField)(env, clazz, field));
 481             break;
 482     }
 483 }
 484 
 485 void
 486 sharedGetFieldValues(PacketInputStream *in, PacketOutputStream *out,
 487                      jboolean isStatic)
 488 {
 489     JNIEnv *env = getEnv();
 490     jint length;
 491     jobject object;
 492     jclass clazz;
 493 
 494     object = NULL;
 495     clazz  = NULL;
 496 
 497     if (isStatic) {
 498         clazz = inStream_readClassRef(env, in);
 499     } else {
 500         object = inStream_readObjectRef(env, in);
 501     }
 502 
 503     length = inStream_readInt(in);
 504     if (inStream_error(in)) {
 505         return;
 506     }
 507 
 508     WITH_LOCAL_REFS(env, length + 1) { /* +1 for class with instance fields */
 509 
 510         int i;
 511 
 512         (void)outStream_writeInt(out, length);
 513         for (i = 0; (i < length) && !outStream_error(out); i++) {
 514             jfieldID field = inStream_readFieldID(in);
 515 
 516             if (isStatic) {
 517                 writeStaticFieldValue(env, out, clazz, field);
 518             } else {
 519                 writeFieldValue(env, out, object, field);
 520             }
 521         }
 522 
 523     } END_WITH_LOCAL_REFS(env);
 524 }
 525 
 526 jboolean
 527 sharedInvoke(PacketInputStream *in, PacketOutputStream *out)
 528 {
 529     jvalue *arguments = NULL;
 530     jint options;
 531     jvmtiError error;
 532     jbyte invokeType;
 533     jclass clazz;
 534     jmethodID method;
 535     jint argumentCount;
 536     jobject instance;
 537     jthread thread;
 538     JNIEnv *env;
 539 
 540     /*
 541      * Instance methods start with the instance, thread and class,
 542      * and statics and constructors start with the class and then the
 543      * thread.
 544      */
 545     env = getEnv();
 546     if (inStream_command(in) == JDWP_COMMAND(ObjectReference, InvokeMethod)) {
 547         instance = inStream_readObjectRef(env, in);
 548         thread = inStream_readThreadRef(env, in);
 549         clazz = inStream_readClassRef(env, in);
 550     } else { /* static method or constructor */
 551         instance = NULL;
 552         clazz = inStream_readClassRef(env, in);
 553         thread = inStream_readThreadRef(env, in);
 554     }
 555 
 556     /*
 557      * ... and the rest of the packet is identical for all commands
 558      */
 559     method = inStream_readMethodID(in);
 560     argumentCount = inStream_readInt(in);
 561     if (inStream_error(in)) {
 562         return JNI_TRUE;
 563     }
 564 
 565     /* If count == 0, don't try and allocate 0 bytes, you'll get NULL */
 566     if ( argumentCount > 0 ) {
 567         int i;
 568         /*LINTED*/
 569         arguments = jvmtiAllocate(argumentCount * (jint)sizeof(*arguments));
 570         if (arguments == NULL) {
 571             outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
 572             return JNI_TRUE;
 573         }
 574         for (i = 0; (i < argumentCount) && !inStream_error(in); i++) {
 575             arguments[i] = inStream_readValue(in, NULL);
 576         }
 577         if (inStream_error(in)) {
 578             return JNI_TRUE;
 579         }
 580     }
 581 
 582     options = inStream_readInt(in);
 583     if (inStream_error(in)) {
 584         if ( arguments != NULL ) {
 585             jvmtiDeallocate(arguments);
 586         }
 587         return JNI_TRUE;
 588     }
 589 
 590     if (inStream_command(in) == JDWP_COMMAND(ClassType, NewInstance)) {
 591         invokeType = INVOKE_CONSTRUCTOR;
 592     } else if (inStream_command(in) == JDWP_COMMAND(ClassType, InvokeMethod)) {
 593         invokeType = INVOKE_STATIC;
 594     } else if (inStream_command(in) == JDWP_COMMAND(InterfaceType, InvokeMethod)) {
 595         invokeType = INVOKE_STATIC;
 596     } else if (inStream_command(in) == JDWP_COMMAND(ObjectReference, InvokeMethod)) {
 597         invokeType = INVOKE_INSTANCE;
 598     } else {
 599         outStream_setError(out, JDWP_ERROR(INTERNAL));
 600         if ( arguments != NULL ) {
 601             jvmtiDeallocate(arguments);
 602         }
 603         return JNI_TRUE;
 604     }
 605 
 606     /*
 607      * Request the invoke. If there are no errors in the request,
 608      * the interrupting thread will actually do the invoke and a
 609      * reply will be generated subsequently, so we don't reply here.
 610      */
 611     error = invoker_requestInvoke(invokeType, (jbyte)options, inStream_id(in),
 612                                   thread, clazz, method,
 613                                   instance, arguments, argumentCount);
 614     if (error != JVMTI_ERROR_NONE) {
 615         outStream_setError(out, map2jdwpError(error));
 616         if ( arguments != NULL ) {
 617             jvmtiDeallocate(arguments);
 618         }
 619         return JNI_TRUE;
 620     }
 621 
 622     return JNI_FALSE;   /* Don't reply */
 623 }
 624 
 625 jint
 626 uniqueID(void)
 627 {
 628     static jint currentID = 0;
 629     return currentID++;
 630 }
 631 
 632 int
 633 filterDebugThreads(jthread *threads, int count)
 634 {
 635     int i;
 636     int current;
 637 
 638     /* Squish out all of the debugger-spawned threads */
 639     for (i = 0, current = 0; i < count; i++) {
 640         jthread thread = threads[i];
 641         if (!threadControl_isDebugThread(thread)) {
 642             if (i > current) {
 643                 threads[current] = thread;
 644             }
 645             current++;
 646         }
 647     }
 648     return current;
 649 }
 650 
 651 jbyte
 652 referenceTypeTag(jclass clazz)
 653 {
 654     jbyte tag;
 655 
 656     if (isInterface(clazz)) {
 657         tag = JDWP_TYPE_TAG(INTERFACE);
 658     } else if (isArrayClass(clazz)) {
 659         tag = JDWP_TYPE_TAG(ARRAY);
 660     } else {
 661         tag = JDWP_TYPE_TAG(CLASS);
 662     }
 663 
 664     return tag;
 665 }
 666 
 667 /**
 668  * Get field modifiers
 669  */
 670 jvmtiError
 671 fieldModifiers(jclass clazz, jfieldID field, jint *pmodifiers)
 672 {
 673     jvmtiError error;
 674 
 675     *pmodifiers = 0;
 676     error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldModifiers)
 677             (gdata->jvmti, clazz, field, pmodifiers);
 678     return error;
 679 }
 680 
 681 /**
 682  * Get method modifiers
 683  */
 684 jvmtiError
 685 methodModifiers(jmethodID method, jint *pmodifiers)
 686 {
 687     jvmtiError error;
 688 
 689     *pmodifiers = 0;
 690     error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodModifiers)
 691             (gdata->jvmti, method, pmodifiers);
 692     return error;
 693 }
 694 
 695 /* Returns a local ref to the declaring class for a method, or NULL. */
 696 jvmtiError
 697 methodClass(jmethodID method, jclass *pclazz)
 698 {
 699     jvmtiError error;
 700 
 701     *pclazz = NULL;
 702     error = FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass)
 703                                 (gdata->jvmti, method, pclazz);
 704     return error;
 705 }
 706 
 707 /* Returns a local ref to the declaring class for a method, or NULL. */
 708 jvmtiError
 709 methodLocation(jmethodID method, jlocation *ploc1, jlocation *ploc2)
 710 {
 711     jvmtiError error;
 712 
 713     error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodLocation)
 714                                 (gdata->jvmti, method, ploc1, ploc2);
 715     return error;
 716 }
 717 
 718 /**
 719  * Get method signature
 720  */
 721 jvmtiError
 722 methodSignature(jmethodID method,
 723         char **pname, char **psignature, char **pgeneric_signature)
 724 {
 725     jvmtiError error;
 726     char *name = NULL;
 727     char *signature = NULL;
 728     char *generic_signature = NULL;
 729 
 730     error = FUNC_PTR(gdata->jvmti,GetMethodName)
 731             (gdata->jvmti, method, &name, &signature, &generic_signature);
 732 
 733     if ( pname != NULL ) {
 734         *pname = name;
 735     } else if ( name != NULL )  {
 736         jvmtiDeallocate(name);
 737     }
 738     if ( psignature != NULL ) {
 739         *psignature = signature;
 740     } else if ( signature != NULL ) {
 741         jvmtiDeallocate(signature);
 742     }
 743     if ( pgeneric_signature != NULL ) {
 744         *pgeneric_signature = generic_signature;
 745     } else if ( generic_signature != NULL )  {
 746         jvmtiDeallocate(generic_signature);
 747     }
 748     return error;
 749 }
 750 
 751 /*
 752  * Get the return type key of the method
 753  *     V or B C D F I J S Z L  [
 754  */
 755 jvmtiError
 756 methodReturnType(jmethodID method, char *typeKey)
 757 {
 758     char       *signature;
 759     jvmtiError  error;
 760 
 761     signature = NULL;
 762     error     = methodSignature(method, NULL, &signature, NULL);
 763     if (error == JVMTI_ERROR_NONE) {
 764         if (signature == NULL ) {
 765             error = AGENT_ERROR_INVALID_TAG;
 766         } else {
 767             char * xx;
 768 
 769             xx = strchr(signature, ')');
 770             if (xx == NULL || *(xx + 1) == 0) {
 771                 error = AGENT_ERROR_INVALID_TAG;
 772             } else {
 773                *typeKey = *(xx + 1);
 774             }
 775             jvmtiDeallocate(signature);
 776         }
 777     }
 778     return error;
 779 }
 780 
 781 
 782 /**
 783  * Return class loader for a class (must be inside a WITH_LOCAL_REFS)
 784  */
 785 jvmtiError
 786 classLoader(jclass clazz, jobject *pclazz)
 787 {
 788     jvmtiError error;
 789 
 790     *pclazz = NULL;
 791     error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassLoader)
 792             (gdata->jvmti, clazz, pclazz);
 793     return error;
 794 }
 795 
 796 /**
 797  * Get field signature
 798  */
 799 jvmtiError
 800 fieldSignature(jclass clazz, jfieldID field,
 801         char **pname, char **psignature, char **pgeneric_signature)
 802 {
 803     jvmtiError error;
 804     char *name = NULL;
 805     char *signature = NULL;
 806     char *generic_signature = NULL;
 807 
 808     error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldName)
 809             (gdata->jvmti, clazz, field, &name, &signature, &generic_signature);
 810 
 811     if ( pname != NULL ) {
 812         *pname = name;
 813     } else if ( name != NULL )  {
 814         jvmtiDeallocate(name);
 815     }
 816     if ( psignature != NULL ) {
 817         *psignature = signature;
 818     } else if ( signature != NULL )  {
 819         jvmtiDeallocate(signature);
 820     }
 821     if ( pgeneric_signature != NULL ) {
 822         *pgeneric_signature = generic_signature;
 823     } else if ( generic_signature != NULL )  {
 824         jvmtiDeallocate(generic_signature);
 825     }
 826     return error;
 827 }
 828 
 829 JNIEnv *
 830 getEnv(void)
 831 {
 832     JNIEnv *env = NULL;
 833     jint rc;
 834 
 835     rc = FUNC_PTR(gdata->jvm,GetEnv)
 836                 (gdata->jvm, (void **)&env, JNI_VERSION_1_2);
 837     if (rc != JNI_OK) {
 838         ERROR_MESSAGE(("JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = %d",
 839                 rc));
 840         EXIT_ERROR(AGENT_ERROR_NO_JNI_ENV,NULL);
 841     }
 842     return env;
 843 }
 844 
 845 jvmtiError
 846 spawnNewThread(jvmtiStartFunction func, void *arg, char *name)
 847 {
 848     JNIEnv *env = getEnv();
 849     jvmtiError error;
 850 
 851     LOG_MISC(("Spawning new thread: %s", name));
 852 
 853     WITH_LOCAL_REFS(env, 3) {
 854 
 855         jthread thread;
 856         jstring nameString;
 857 
 858         nameString = JNI_FUNC_PTR(env,NewStringUTF)(env, name);
 859         if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
 860             JNI_FUNC_PTR(env,ExceptionClear)(env);
 861             error = AGENT_ERROR_OUT_OF_MEMORY;
 862             goto err;
 863         }
 864 
 865         thread = JNI_FUNC_PTR(env,NewObject)
 866                         (env, gdata->threadClass, gdata->threadConstructor,
 867                                    gdata->systemThreadGroup, nameString);
 868         if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
 869             JNI_FUNC_PTR(env,ExceptionClear)(env);
 870             error = AGENT_ERROR_OUT_OF_MEMORY;
 871             goto err;
 872         }
 873 
 874         /*
 875          * Make the debugger thread a daemon
 876          */
 877         JNI_FUNC_PTR(env,CallVoidMethod)
 878                         (env, thread, gdata->threadSetDaemon, JNI_TRUE);
 879         if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
 880             JNI_FUNC_PTR(env,ExceptionClear)(env);
 881             error = AGENT_ERROR_JNI_EXCEPTION;
 882             goto err;
 883         }
 884 
 885         error = threadControl_addDebugThread(thread);
 886         if (error == JVMTI_ERROR_NONE) {
 887             /*
 888              * Debugger threads need cycles in all sorts of strange
 889              * situations (e.g. infinite cpu-bound loops), so give the
 890              * thread a high priority. Note that if the VM has an application
 891              * thread running at the max priority, there is still a chance
 892              * that debugger threads will be starved. (There needs to be
 893              * a way to give debugger threads a priority higher than any
 894              * application thread).
 895              */
 896             error = JVMTI_FUNC_PTR(gdata->jvmti,RunAgentThread)
 897                         (gdata->jvmti, thread, func, arg,
 898                                         JVMTI_THREAD_MAX_PRIORITY);
 899         }
 900 
 901         err: ;
 902 
 903     } END_WITH_LOCAL_REFS(env);
 904 
 905     return error;
 906 }
 907 
 908 jvmtiError
 909 jvmtiGetCapabilities(jvmtiCapabilities *caps)
 910 {
 911     if ( gdata->vmDead ) {
 912         return AGENT_ERROR_VM_DEAD;
 913     }
 914     if (!gdata->haveCachedJvmtiCapabilities) {
 915         jvmtiError error;
 916 
 917         error = JVMTI_FUNC_PTR(gdata->jvmti,GetCapabilities)
 918                         (gdata->jvmti, &(gdata->cachedJvmtiCapabilities));
 919         if (error != JVMTI_ERROR_NONE) {
 920             return error;
 921         }
 922         gdata->haveCachedJvmtiCapabilities = JNI_TRUE;
 923     }
 924 
 925     *caps = gdata->cachedJvmtiCapabilities;
 926 
 927     return JVMTI_ERROR_NONE;
 928 }
 929 
 930 static jint
 931 jvmtiVersion(void)
 932 {
 933     if (gdata->cachedJvmtiVersion == 0) {
 934         jvmtiError error;
 935         error = JVMTI_FUNC_PTR(gdata->jvmti,GetVersionNumber)
 936                         (gdata->jvmti, &(gdata->cachedJvmtiVersion));
 937         if (error != JVMTI_ERROR_NONE) {
 938             EXIT_ERROR(error, "on getting the JVMTI version number");
 939         }
 940     }
 941     return gdata->cachedJvmtiVersion;
 942 }
 943 
 944 jint
 945 jvmtiMajorVersion(void)
 946 {
 947     return (jvmtiVersion() & JVMTI_VERSION_MASK_MAJOR)
 948                     >> JVMTI_VERSION_SHIFT_MAJOR;
 949 }
 950 
 951 jint
 952 jvmtiMinorVersion(void)
 953 {
 954     return (jvmtiVersion() & JVMTI_VERSION_MASK_MINOR)
 955                     >> JVMTI_VERSION_SHIFT_MINOR;
 956 }
 957 
 958 jint
 959 jvmtiMicroVersion(void)
 960 {
 961     return (jvmtiVersion() & JVMTI_VERSION_MASK_MICRO)
 962                     >> JVMTI_VERSION_SHIFT_MICRO;
 963 }
 964 
 965 jboolean
 966 canSuspendResumeThreadLists(void)
 967 {
 968     jvmtiError error;
 969     jvmtiCapabilities cap;
 970 
 971     error = jvmtiGetCapabilities(&cap);
 972     return (error == JVMTI_ERROR_NONE && cap.can_suspend);
 973 }
 974 
 975 jvmtiError
 976 getSourceDebugExtension(jclass clazz, char **extensionPtr)
 977 {
 978     return JVMTI_FUNC_PTR(gdata->jvmti,GetSourceDebugExtension)
 979                 (gdata->jvmti, clazz, extensionPtr);
 980 }
 981 
 982 /*
 983  * Convert the signature "Ljava/lang/Foo;" to a
 984  * classname "java.lang.Foo" compatible with the pattern.
 985  * Signature is overwritten in-place.
 986  */
 987 void
 988 convertSignatureToClassname(char *convert)
 989 {
 990     char *p;
 991 
 992     p = convert + 1;
 993     while ((*p != ';') && (*p != '\0')) {
 994         char c = *p;
 995         if (c == '/') {
 996             *(p-1) = '.';
 997         } else {
 998             *(p-1) = c;
 999         }
1000         p++;
1001     }
1002     *(p-1) = '\0';
1003 }
1004 
1005 static void
1006 handleInterrupt(void)
1007 {
1008     /*
1009      * An interrupt is handled:
1010      *
1011      * 1) for running application threads by deferring the interrupt
1012      * until the current event handler has concluded.
1013      *
1014      * 2) for debugger threads by ignoring the interrupt; this is the
1015      * most robust solution since debugger threads don't use interrupts
1016      * to signal any condition.
1017      *
1018      * 3) for application threads that have not started or already
1019      * ended by ignoring the interrupt. In the former case, the application
1020      * is relying on timing to determine whether or not the thread sees
1021      * the interrupt; in the latter case, the interrupt is meaningless.
1022      */
1023     jthread thread = threadControl_currentThread();
1024     if ((thread != NULL) && (!threadControl_isDebugThread(thread))) {
1025         threadControl_setPendingInterrupt(thread);
1026     }
1027 }
1028 
1029 static jvmtiError
1030 ignore_vm_death(jvmtiError error)
1031 {
1032     if (error == JVMTI_ERROR_WRONG_PHASE) {
1033         LOG_MISC(("VM_DEAD, in debugMonitor*()?"));
1034         return JVMTI_ERROR_NONE; /* JVMTI does this, not JVMDI? */
1035     }
1036     return error;
1037 }
1038 
1039 void
1040 debugMonitorEnter(jrawMonitorID monitor)
1041 {
1042     jvmtiError error;
1043     while (JNI_TRUE) {
1044         error = FUNC_PTR(gdata->jvmti,RawMonitorEnter)
1045                         (gdata->jvmti, monitor);
1046         error = ignore_vm_death(error);
1047         if (error == JVMTI_ERROR_INTERRUPT) {
1048             handleInterrupt();
1049         } else {
1050             break;
1051         }
1052     }
1053     if (error != JVMTI_ERROR_NONE) {
1054         EXIT_ERROR(error, "on raw monitor enter");
1055     }
1056 }
1057 
1058 void
1059 debugMonitorExit(jrawMonitorID monitor)
1060 {
1061     jvmtiError error;
1062 
1063     error = FUNC_PTR(gdata->jvmti,RawMonitorExit)
1064                 (gdata->jvmti, monitor);
1065     error = ignore_vm_death(error);
1066     if (error != JVMTI_ERROR_NONE) {
1067         EXIT_ERROR(error, "on raw monitor exit");
1068     }
1069 }
1070 
1071 void
1072 debugMonitorWait(jrawMonitorID monitor)
1073 {
1074     jvmtiError error;
1075     error = FUNC_PTR(gdata->jvmti,RawMonitorWait)
1076         (gdata->jvmti, monitor, ((jlong)(-1)));
1077 
1078     /*
1079      * According to the JLS (17.8), here we have
1080      * either :
1081      * a- been notified
1082      * b- gotten a suprious wakeup
1083      * c- been interrupted
1084      * If both a and c have happened, the VM must choose
1085      * which way to return - a or c.  If it chooses c
1086      * then the notify is gone - either to some other
1087      * thread that is also waiting, or it is dropped
1088      * on the floor.
1089      *
1090      * a is what we expect.  b won't hurt us any -
1091      * callers should be programmed to handle
1092      * spurious wakeups.  In case of c,
1093      * then the interrupt has been cleared, but
1094      * we don't want to consume it.  It came from
1095      * user code and is intended for user code, not us.
1096      * So, we will remember that the interrupt has
1097      * occurred and re-activate it when this thread
1098      * goes back into user code.
1099      * That being said, what do we do here?  Since
1100      * we could have been notified too, here we will
1101      * just pretend that we have been.  It won't hurt
1102      * anything to return in the same way as if
1103      * we were notified since callers have to be able to
1104      * handle spurious wakeups anyway.
1105      */
1106     if (error == JVMTI_ERROR_INTERRUPT) {
1107         handleInterrupt();
1108         error = JVMTI_ERROR_NONE;
1109     }
1110     error = ignore_vm_death(error);
1111     if (error != JVMTI_ERROR_NONE) {
1112         EXIT_ERROR(error, "on raw monitor wait");
1113     }
1114 }
1115 
1116 void
1117 debugMonitorTimedWait(jrawMonitorID monitor, jlong millis)
1118 {
1119     jvmtiError error;
1120     error = FUNC_PTR(gdata->jvmti,RawMonitorWait)
1121         (gdata->jvmti, monitor, millis);
1122     if (error == JVMTI_ERROR_INTERRUPT) {
1123         /* See comment above */
1124         handleInterrupt();
1125         error = JVMTI_ERROR_NONE;
1126     }
1127     error = ignore_vm_death(error);
1128     if (error != JVMTI_ERROR_NONE) {
1129         EXIT_ERROR(error, "on raw monitor timed wait");
1130     }
1131 }
1132 
1133 void
1134 debugMonitorNotify(jrawMonitorID monitor)
1135 {
1136     jvmtiError error;
1137 
1138     error = FUNC_PTR(gdata->jvmti,RawMonitorNotify)
1139                 (gdata->jvmti, monitor);
1140     error = ignore_vm_death(error);
1141     if (error != JVMTI_ERROR_NONE) {
1142         EXIT_ERROR(error, "on raw monitor notify");
1143     }
1144 }
1145 
1146 void
1147 debugMonitorNotifyAll(jrawMonitorID monitor)
1148 {
1149     jvmtiError error;
1150 
1151     error = FUNC_PTR(gdata->jvmti,RawMonitorNotifyAll)
1152                 (gdata->jvmti, monitor);
1153     error = ignore_vm_death(error);
1154     if (error != JVMTI_ERROR_NONE) {
1155         EXIT_ERROR(error, "on raw monitor notify all");
1156     }
1157 }
1158 
1159 jrawMonitorID
1160 debugMonitorCreate(char *name)
1161 {
1162     jrawMonitorID monitor;
1163     jvmtiError error;
1164 
1165     error = FUNC_PTR(gdata->jvmti,CreateRawMonitor)
1166                 (gdata->jvmti, name, &monitor);
1167     if (error != JVMTI_ERROR_NONE) {
1168         EXIT_ERROR(error, "on creation of a raw monitor");
1169     }
1170     return monitor;
1171 }
1172 
1173 void
1174 debugMonitorDestroy(jrawMonitorID monitor)
1175 {
1176     jvmtiError error;
1177 
1178     error = FUNC_PTR(gdata->jvmti,DestroyRawMonitor)
1179                 (gdata->jvmti, monitor);
1180     error = ignore_vm_death(error);
1181     if (error != JVMTI_ERROR_NONE) {
1182         EXIT_ERROR(error, "on destruction of raw monitor");
1183     }
1184 }
1185 
1186 /**
1187  * Return array of all threads (must be inside a WITH_LOCAL_REFS)
1188  */
1189 jthread *
1190 allThreads(jint *count)
1191 {
1192     jthread *threads;
1193     jvmtiError error;
1194 
1195     *count = 0;
1196     threads = NULL;
1197     error = JVMTI_FUNC_PTR(gdata->jvmti,GetAllThreads)
1198                 (gdata->jvmti, count, &threads);
1199     if (error == AGENT_ERROR_OUT_OF_MEMORY) {
1200         return NULL; /* Let caller deal with no memory? */
1201     }
1202     if (error != JVMTI_ERROR_NONE) {
1203         EXIT_ERROR(error, "getting all threads");
1204     }
1205     return threads;
1206 }
1207 
1208 /**
1209  * Fill the passed in structure with thread group info.
1210  * name field is JVMTI allocated.  parent is global ref.
1211  */
1212 void
1213 threadGroupInfo(jthreadGroup group, jvmtiThreadGroupInfo *info)
1214 {
1215     jvmtiError error;
1216 
1217     error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadGroupInfo)
1218                 (gdata->jvmti, group, info);
1219     if (error != JVMTI_ERROR_NONE) {
1220         EXIT_ERROR(error, "on getting thread group info");
1221     }
1222 }
1223 
1224 /**
1225  * Return class signature string
1226  */
1227 jvmtiError
1228 classSignature(jclass clazz, char **psignature, char **pgeneric_signature)
1229 {
1230     jvmtiError error;
1231     char *signature = NULL;
1232 
1233     /*
1234      * pgeneric_signature can be NULL, and GetClassSignature
1235      * accepts NULL.
1236      */
1237     error = FUNC_PTR(gdata->jvmti,GetClassSignature)
1238                 (gdata->jvmti, clazz, &signature, pgeneric_signature);
1239 
1240     if ( psignature != NULL ) {
1241         *psignature = signature;
1242     } else if ( signature != NULL )  {
1243         jvmtiDeallocate(signature);
1244     }
1245     return error;
1246 }
1247 
1248 /* Get class name (not signature) */
1249 char *
1250 getClassname(jclass clazz)
1251 {
1252     char *classname;
1253 
1254     classname = NULL;
1255     if ( clazz != NULL ) {
1256         if (classSignature(clazz, &classname, NULL) != JVMTI_ERROR_NONE) {
1257             classname = NULL;
1258         } else {
1259             /* Convert in place */
1260             convertSignatureToClassname(classname);
1261         }
1262     }
1263     return classname; /* Caller must free this memory */
1264 }
1265 
1266 void
1267 writeGenericSignature(PacketOutputStream *out, char *genericSignature)
1268 {
1269     if (genericSignature == NULL) {
1270         (void)outStream_writeString(out, "");
1271     } else {
1272         (void)outStream_writeString(out, genericSignature);
1273     }
1274 }
1275 
1276 jint
1277 classStatus(jclass clazz)
1278 {
1279     jint status;
1280     jvmtiError error;
1281 
1282     error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassStatus)
1283                 (gdata->jvmti, clazz, &status);
1284     if (error != JVMTI_ERROR_NONE) {
1285         EXIT_ERROR(error, "on getting class status");
1286     }
1287     return status;
1288 }
1289 
1290 static jboolean
1291 isArrayClass(jclass clazz)
1292 {
1293     jboolean isArray = JNI_FALSE;
1294     jvmtiError error;
1295 
1296     error = JVMTI_FUNC_PTR(gdata->jvmti,IsArrayClass)
1297                 (gdata->jvmti, clazz, &isArray);
1298     if (error != JVMTI_ERROR_NONE) {
1299         EXIT_ERROR(error, "on checking for an array class");
1300     }
1301     return isArray;
1302 }
1303 
1304 static jboolean
1305 isInterface(jclass clazz)
1306 {
1307     jboolean isInterface = JNI_FALSE;
1308     jvmtiError error;
1309 
1310     error = JVMTI_FUNC_PTR(gdata->jvmti,IsInterface)
1311                 (gdata->jvmti, clazz, &isInterface);
1312     if (error != JVMTI_ERROR_NONE) {
1313         EXIT_ERROR(error, "on checking for an interface");
1314     }
1315     return isInterface;
1316 }
1317 
1318 jvmtiError
1319 isFieldSynthetic(jclass clazz, jfieldID field, jboolean *psynthetic)
1320 {
1321     jvmtiError error;
1322 
1323     error = JVMTI_FUNC_PTR(gdata->jvmti,IsFieldSynthetic)
1324                 (gdata->jvmti, clazz, field, psynthetic);
1325     if ( error == JVMTI_ERROR_MUST_POSSESS_CAPABILITY ) {
1326         /* If the query is not supported, we assume it is not synthetic. */
1327         *psynthetic = JNI_FALSE;
1328         return JVMTI_ERROR_NONE;
1329     }
1330     return error;
1331 }
1332 
1333 jvmtiError
1334 isMethodSynthetic(jmethodID method, jboolean *psynthetic)
1335 {
1336     jvmtiError error;
1337 
1338     error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodSynthetic)
1339                 (gdata->jvmti, method, psynthetic);
1340     if ( error == JVMTI_ERROR_MUST_POSSESS_CAPABILITY ) {
1341         /* If the query is not supported, we assume it is not synthetic. */
1342         *psynthetic = JNI_FALSE;
1343         return JVMTI_ERROR_NONE;
1344     }
1345     return error;
1346 }
1347 
1348 jboolean
1349 isMethodNative(jmethodID method)
1350 {
1351     jboolean isNative = JNI_FALSE;
1352     jvmtiError error;
1353 
1354     error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodNative)
1355                 (gdata->jvmti, method, &isNative);
1356     if (error != JVMTI_ERROR_NONE) {
1357         EXIT_ERROR(error, "on checking for a native interface");
1358     }
1359     return isNative;
1360 }
1361 
1362 jboolean
1363 isSameObject(JNIEnv *env, jobject o1, jobject o2)
1364 {
1365     if ( o1==o2 ) {
1366         return JNI_TRUE;
1367     }
1368     return FUNC_PTR(env,IsSameObject)(env, o1, o2);
1369 }
1370 
1371 jint
1372 objectHashCode(jobject object)
1373 {
1374     jint hashCode = 0;
1375     jvmtiError error;
1376 
1377     if ( object!=NULL ) {
1378         error = JVMTI_FUNC_PTR(gdata->jvmti,GetObjectHashCode)
1379                     (gdata->jvmti, object, &hashCode);
1380         if (error != JVMTI_ERROR_NONE) {
1381             EXIT_ERROR(error, "on getting an object hash code");
1382         }
1383     }
1384     return hashCode;
1385 }
1386 
1387 /* Get all implemented interfaces (must be inside a WITH_LOCAL_REFS) */
1388 jvmtiError
1389 allInterfaces(jclass clazz, jclass **ppinterfaces, jint *pcount)
1390 {
1391     jvmtiError error;
1392 
1393     *pcount = 0;
1394     *ppinterfaces = NULL;
1395     error = JVMTI_FUNC_PTR(gdata->jvmti,GetImplementedInterfaces)
1396                 (gdata->jvmti, clazz, pcount, ppinterfaces);
1397     return error;
1398 }
1399 
1400 /* Get all loaded classes (must be inside a WITH_LOCAL_REFS) */
1401 jvmtiError
1402 allLoadedClasses(jclass **ppclasses, jint *pcount)
1403 {
1404     jvmtiError error;
1405 
1406     *pcount = 0;
1407     *ppclasses = NULL;
1408     error = JVMTI_FUNC_PTR(gdata->jvmti,GetLoadedClasses)
1409                 (gdata->jvmti, pcount, ppclasses);
1410     return error;
1411 }
1412 
1413 /* Get all loaded classes for a loader (must be inside a WITH_LOCAL_REFS) */
1414 jvmtiError
1415 allClassLoaderClasses(jobject loader, jclass **ppclasses, jint *pcount)
1416 {
1417     jvmtiError error;
1418 
1419     *pcount = 0;
1420     *ppclasses = NULL;
1421     error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassLoaderClasses)
1422                 (gdata->jvmti, loader, pcount, ppclasses);
1423     return error;
1424 }
1425 
1426 static jboolean
1427 is_a_nested_class(char *outer_sig, int outer_sig_len, char *sig, int sep)
1428 {
1429     char *inner;
1430 
1431     /* Assumed outer class signature is  "LOUTERCLASSNAME;"
1432      *         inner class signature is  "LOUTERCLASSNAME$INNERNAME;"
1433      *
1434      * INNERNAME can take the form:
1435      *    [0-9][1-9]*        anonymous class somewhere in the file
1436      *    [0-9][1-9]*NAME    local class somewhere in the OUTER class
1437      *    NAME               nested class in OUTER
1438      *
1439      * If NAME itself contains a $ (sep) then classname is further nested
1440      *    inside another class.
1441      *
1442      */
1443 
1444     /* Check prefix first */
1445     if ( strncmp(sig, outer_sig, outer_sig_len-1) != 0 ) {
1446         return JNI_FALSE;
1447     }
1448 
1449     /* Prefix must be followed by a $ (sep) */
1450     if ( sig[outer_sig_len-1] != sep ) {
1451         return JNI_FALSE;  /* No sep follows the match, must not be nested. */
1452     }
1453 
1454     /* Walk past any digits, if we reach the end, must be pure anonymous */
1455     inner = sig + outer_sig_len;
1456 #if 1 /* We want to return local classes */
1457     while ( *inner && isdigit(*inner) ) {
1458         inner++;
1459     }
1460     /* But anonymous class names can't be trusted. */
1461     if ( *inner == ';' ) {
1462         return JNI_FALSE;  /* A pure anonymous class */
1463     }
1464 #else
1465     if ( *inner && isdigit(*inner) ) {
1466         return JNI_FALSE;  /* A pure anonymous or local class */
1467     }
1468 #endif
1469 
1470     /* Nested deeper? */
1471     if ( strchr(inner, sep) != NULL ) {
1472         return JNI_FALSE;  /* Nested deeper than we want? */
1473     }
1474     return JNI_TRUE;
1475 }
1476 
1477 /* Get all nested classes for a class (must be inside a WITH_LOCAL_REFS) */
1478 jvmtiError
1479 allNestedClasses(jclass parent_clazz, jclass **ppnested, jint *pcount)
1480 {
1481     jvmtiError error;
1482     jobject parent_loader;
1483     jclass *classes;
1484     char *signature;
1485     size_t len;
1486     jint count;
1487     jint ncount;
1488     int i;
1489 
1490     *ppnested   = NULL;
1491     *pcount     = 0;
1492 
1493     parent_loader = NULL;
1494     classes       = NULL;
1495     signature     = NULL;
1496     count         = 0;
1497     ncount        = 0;
1498 
1499     error = classLoader(parent_clazz, &parent_loader);
1500     if (error != JVMTI_ERROR_NONE) {
1501         return error;
1502     }
1503     error = classSignature(parent_clazz, &signature, NULL);
1504     if (error != JVMTI_ERROR_NONE) {
1505         return error;
1506     }
1507     len = strlen(signature);
1508 
1509     error = allClassLoaderClasses(parent_loader, &classes, &count);
1510     if ( error != JVMTI_ERROR_NONE ) {
1511         jvmtiDeallocate(signature);
1512         return error;
1513     }
1514 
1515     for (i=0; i<count; i++) {
1516         jclass clazz;
1517         char *candidate_signature;
1518 
1519         clazz = classes[i];
1520         candidate_signature = NULL;
1521         error = classSignature(clazz, &candidate_signature, NULL);
1522         if (error != JVMTI_ERROR_NONE) {
1523             break;
1524         }
1525 
1526         if ( is_a_nested_class(signature, (int)len, candidate_signature, '$') ||
1527              is_a_nested_class(signature, (int)len, candidate_signature, '#') ) {
1528             /* Float nested classes to top */
1529             classes[i] = classes[ncount];
1530             classes[ncount++] = clazz;
1531         }
1532         jvmtiDeallocate(candidate_signature);
1533     }
1534 
1535     jvmtiDeallocate(signature);
1536 
1537     if ( count != 0 &&  ncount == 0 ) {
1538         jvmtiDeallocate(classes);
1539         classes = NULL;
1540     }
1541 
1542     *ppnested = classes;
1543     *pcount = ncount;
1544     return error;
1545 }
1546 
1547 void
1548 createLocalRefSpace(JNIEnv *env, jint capacity)
1549 {
1550     /*
1551      * Save current exception since it might get overwritten by
1552      * the calls below. Note we must depend on space in the existing
1553      * frame because asking for a new frame may generate an exception.
1554      */
1555     jobject throwable = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
1556 
1557     /*
1558      * Use the current frame if necessary; otherwise create a new one
1559      */
1560     if (JNI_FUNC_PTR(env,PushLocalFrame)(env, capacity) < 0) {
1561         EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"PushLocalFrame: Unable to push JNI frame");
1562     }
1563 
1564     /*
1565      * TO DO: This could be more efficient if it used EnsureLocalCapacity,
1566      * but that would not work if two functions on the call stack
1567      * use this function. We would need to either track reserved
1568      * references on a per-thread basis or come up with a convention
1569      * that would prevent two functions from depending on this function
1570      * at the same time.
1571      */
1572 
1573     /*
1574      * Restore exception state from before call
1575      */
1576     if (throwable != NULL) {
1577         JNI_FUNC_PTR(env,Throw)(env, throwable);
1578     } else {
1579         JNI_FUNC_PTR(env,ExceptionClear)(env);
1580     }
1581 }
1582 
1583 jboolean
1584 isClass(jobject object)
1585 {
1586     JNIEnv *env = getEnv();
1587     return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classClass);
1588 }
1589 
1590 jboolean
1591 isThread(jobject object)
1592 {
1593     JNIEnv *env = getEnv();
1594     return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadClass);
1595 }
1596 
1597 jboolean
1598 isThreadGroup(jobject object)
1599 {
1600     JNIEnv *env = getEnv();
1601     return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadGroupClass);
1602 }
1603 
1604 jboolean
1605 isString(jobject object)
1606 {
1607     JNIEnv *env = getEnv();
1608     return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->stringClass);
1609 }
1610 
1611 jboolean
1612 isClassLoader(jobject object)
1613 {
1614     JNIEnv *env = getEnv();
1615     return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classLoaderClass);
1616 }
1617 
1618 jboolean
1619 isArray(jobject object)
1620 {
1621     JNIEnv *env = getEnv();
1622     jboolean is;
1623 
1624     WITH_LOCAL_REFS(env, 1) {
1625         jclass clazz;
1626         clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
1627         is = isArrayClass(clazz);
1628     } END_WITH_LOCAL_REFS(env);
1629 
1630     return is;
1631 }
1632 
1633 /**
1634  * Return property value as jstring
1635  */
1636 static jstring
1637 getPropertyValue(JNIEnv *env, char *propertyName)
1638 {
1639     jstring valueString;
1640     jstring nameString;
1641 
1642     valueString = NULL;
1643 
1644     /* Create new String object to hold the property name */
1645     nameString = JNI_FUNC_PTR(env,NewStringUTF)(env, propertyName);
1646     if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
1647         JNI_FUNC_PTR(env,ExceptionClear)(env);
1648         /* NULL will be returned below */
1649     } else {
1650         /* Call valueString = System.getProperty(nameString) */
1651         valueString = JNI_FUNC_PTR(env,CallStaticObjectMethod)
1652             (env, gdata->systemClass, gdata->systemGetProperty, nameString);
1653         if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
1654             JNI_FUNC_PTR(env,ExceptionClear)(env);
1655             valueString = NULL;
1656         }
1657     }
1658     return valueString;
1659 }
1660 
1661 /**
1662  * Set an agent property
1663  */
1664 void
1665 setAgentPropertyValue(JNIEnv *env, char *propertyName, char* propertyValue)
1666 {
1667     jstring nameString;
1668     jstring valueString;
1669 
1670     if (gdata->agent_properties == NULL) {
1671         /* VMSupport doesn't exist; so ignore */
1672         return;
1673     }
1674 
1675     /* Create jstrings for property name and value */
1676     nameString = JNI_FUNC_PTR(env,NewStringUTF)(env, propertyName);
1677     if (nameString != NULL) {
1678         valueString = JNI_FUNC_PTR(env,NewStringUTF)(env, propertyValue);
1679         if (valueString != NULL) {
1680             /* invoke Properties.setProperty */
1681             JNI_FUNC_PTR(env,CallObjectMethod)
1682                 (env, gdata->agent_properties,
1683                  gdata->setProperty,
1684                  nameString, valueString);
1685         }
1686     }
1687     if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
1688         JNI_FUNC_PTR(env,ExceptionClear)(env);
1689     }
1690 }
1691 
1692 /**
1693  * Return property value as JDWP allocated string in UTF8 encoding
1694  */
1695 static char *
1696 getPropertyUTF8(JNIEnv *env, char *propertyName)
1697 {
1698     jvmtiError  error;
1699     char       *value;
1700 
1701     value = NULL;
1702     error = JVMTI_FUNC_PTR(gdata->jvmti,GetSystemProperty)
1703                 (gdata->jvmti, (const char *)propertyName, &value);
1704     if (error != JVMTI_ERROR_NONE) {
1705         jstring valueString;
1706 
1707         value = NULL;
1708         valueString = getPropertyValue(env, propertyName);
1709 
1710         if (valueString != NULL) {
1711             const char *utf;
1712 
1713             /* Get the UTF8 encoding for this property value string */
1714             utf = JNI_FUNC_PTR(env,GetStringUTFChars)(env, valueString, NULL);
1715             /* Make a copy for returning, release the JNI copy */
1716             value = jvmtiAllocate((int)strlen(utf) + 1);
1717             if (value != NULL) {
1718                 (void)strcpy(value, utf);
1719             }
1720             JNI_FUNC_PTR(env,ReleaseStringUTFChars)(env, valueString, utf);
1721         }
1722     }
1723     if ( value == NULL ) {
1724         ERROR_MESSAGE(("JDWP Can't get property value for %s", propertyName));
1725         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
1726     }
1727     return value;
1728 }
1729 
1730 jboolean
1731 isMethodObsolete(jmethodID method)
1732 {
1733     jvmtiError error;
1734     jboolean obsolete = JNI_TRUE;
1735 
1736     if ( method != NULL ) {
1737         error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodObsolete)
1738                     (gdata->jvmti, method, &obsolete);
1739         if (error != JVMTI_ERROR_NONE) {
1740             obsolete = JNI_TRUE;
1741         }
1742     }
1743     return obsolete;
1744 }
1745 
1746 /* Get the jvmti environment to be used with tags */
1747 jvmtiEnv *
1748 getSpecialJvmti(void)
1749 {
1750     jvmtiEnv  *jvmti;
1751     jvmtiError error;
1752     int        rc;
1753 
1754     /* Get one time use JVMTI Env */
1755     jvmtiCapabilities caps;
1756 
1757     rc = JVM_FUNC_PTR(gdata->jvm,GetEnv)
1758                      (gdata->jvm, (void **)&jvmti, JVMTI_VERSION_1);
1759     if (rc != JNI_OK) {
1760         return NULL;
1761     }
1762     (void)memset(&caps, 0, (int)sizeof(caps));
1763     caps.can_tag_objects = 1;
1764     error = JVMTI_FUNC_PTR(jvmti,AddCapabilities)(jvmti, &caps);
1765     if ( error != JVMTI_ERROR_NONE ) {
1766         return NULL;
1767     }
1768     return jvmti;
1769 }
1770 
1771 void
1772 writeCodeLocation(PacketOutputStream *out, jclass clazz,
1773                        jmethodID method, jlocation location)
1774 {
1775     jbyte tag;
1776 
1777     if (clazz != NULL) {
1778         tag = referenceTypeTag(clazz);
1779     } else {
1780         tag = JDWP_TYPE_TAG(CLASS);
1781     }
1782     (void)outStream_writeByte(out, tag);
1783     (void)outStream_writeObjectRef(getEnv(), out, clazz);
1784     (void)outStream_writeMethodID(out, isMethodObsolete(method)?NULL:method);
1785     (void)outStream_writeLocation(out, location);
1786 }
1787 
1788 void *
1789 jvmtiAllocate(jint numBytes)
1790 {
1791     void *ptr;
1792     jvmtiError error;
1793     if ( numBytes == 0 ) {
1794         return NULL;
1795     }
1796     error = FUNC_PTR(gdata->jvmti,Allocate)
1797                 (gdata->jvmti, numBytes, (unsigned char**)&ptr);
1798     if (error != JVMTI_ERROR_NONE ) {
1799         EXIT_ERROR(error, "Can't allocate jvmti memory");
1800     }
1801     return ptr;
1802 }
1803 
1804 void
1805 jvmtiDeallocate(void *ptr)
1806 {
1807     jvmtiError error;
1808     if ( ptr == NULL ) {
1809         return;
1810     }
1811     error = FUNC_PTR(gdata->jvmti,Deallocate)
1812                 (gdata->jvmti, ptr);
1813     if (error != JVMTI_ERROR_NONE ) {
1814         EXIT_ERROR(error, "Can't deallocate jvmti memory");
1815     }
1816 }
1817 
1818 /* Rarely needed, transport library uses JDWP errors, only use? */
1819 jvmtiError
1820 map2jvmtiError(jdwpError error)
1821 {
1822     switch ( error ) {
1823         case JDWP_ERROR(NONE):
1824             return JVMTI_ERROR_NONE;
1825         case JDWP_ERROR(INVALID_THREAD):
1826             return JVMTI_ERROR_INVALID_THREAD;
1827         case JDWP_ERROR(INVALID_THREAD_GROUP):
1828             return JVMTI_ERROR_INVALID_THREAD_GROUP;
1829         case JDWP_ERROR(INVALID_PRIORITY):
1830             return JVMTI_ERROR_INVALID_PRIORITY;
1831         case JDWP_ERROR(THREAD_NOT_SUSPENDED):
1832             return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1833         case JDWP_ERROR(THREAD_SUSPENDED):
1834             return JVMTI_ERROR_THREAD_SUSPENDED;
1835         case JDWP_ERROR(INVALID_OBJECT):
1836             return JVMTI_ERROR_INVALID_OBJECT;
1837         case JDWP_ERROR(INVALID_CLASS):
1838             return JVMTI_ERROR_INVALID_CLASS;
1839         case JDWP_ERROR(CLASS_NOT_PREPARED):
1840             return JVMTI_ERROR_CLASS_NOT_PREPARED;
1841         case JDWP_ERROR(INVALID_METHODID):
1842             return JVMTI_ERROR_INVALID_METHODID;
1843         case JDWP_ERROR(INVALID_LOCATION):
1844             return JVMTI_ERROR_INVALID_LOCATION;
1845         case JDWP_ERROR(INVALID_FIELDID):
1846             return JVMTI_ERROR_INVALID_FIELDID;
1847         case JDWP_ERROR(INVALID_FRAMEID):
1848             return AGENT_ERROR_INVALID_FRAMEID;
1849         case JDWP_ERROR(NO_MORE_FRAMES):
1850             return JVMTI_ERROR_NO_MORE_FRAMES;
1851         case JDWP_ERROR(OPAQUE_FRAME):
1852             return JVMTI_ERROR_OPAQUE_FRAME;
1853         case JDWP_ERROR(NOT_CURRENT_FRAME):
1854             return AGENT_ERROR_NOT_CURRENT_FRAME;
1855         case JDWP_ERROR(TYPE_MISMATCH):
1856             return JVMTI_ERROR_TYPE_MISMATCH;
1857         case JDWP_ERROR(INVALID_SLOT):
1858             return JVMTI_ERROR_INVALID_SLOT;
1859         case JDWP_ERROR(DUPLICATE):
1860             return JVMTI_ERROR_DUPLICATE;
1861         case JDWP_ERROR(NOT_FOUND):
1862             return JVMTI_ERROR_NOT_FOUND;
1863         case JDWP_ERROR(INVALID_MONITOR):
1864             return JVMTI_ERROR_INVALID_MONITOR;
1865         case JDWP_ERROR(NOT_MONITOR_OWNER):
1866             return JVMTI_ERROR_NOT_MONITOR_OWNER;
1867         case JDWP_ERROR(INTERRUPT):
1868             return JVMTI_ERROR_INTERRUPT;
1869         case JDWP_ERROR(INVALID_CLASS_FORMAT):
1870             return JVMTI_ERROR_INVALID_CLASS_FORMAT;
1871         case JDWP_ERROR(CIRCULAR_CLASS_DEFINITION):
1872             return JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION;
1873         case JDWP_ERROR(FAILS_VERIFICATION):
1874             return JVMTI_ERROR_FAILS_VERIFICATION;
1875         case JDWP_ERROR(ADD_METHOD_NOT_IMPLEMENTED):
1876             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED;
1877         case JDWP_ERROR(SCHEMA_CHANGE_NOT_IMPLEMENTED):
1878             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
1879         case JDWP_ERROR(INVALID_TYPESTATE):
1880             return JVMTI_ERROR_INVALID_TYPESTATE;
1881         case JDWP_ERROR(HIERARCHY_CHANGE_NOT_IMPLEMENTED):
1882             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
1883         case JDWP_ERROR(DELETE_METHOD_NOT_IMPLEMENTED):
1884             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED;
1885         case JDWP_ERROR(UNSUPPORTED_VERSION):
1886             return JVMTI_ERROR_UNSUPPORTED_VERSION;
1887         case JDWP_ERROR(NAMES_DONT_MATCH):
1888             return JVMTI_ERROR_NAMES_DONT_MATCH;
1889         case JDWP_ERROR(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED):
1890             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
1891         case JDWP_ERROR(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED):
1892             return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED;
1893         case JDWP_ERROR(NOT_IMPLEMENTED):
1894             return JVMTI_ERROR_NOT_AVAILABLE;
1895         case JDWP_ERROR(NULL_POINTER):
1896             return JVMTI_ERROR_NULL_POINTER;
1897         case JDWP_ERROR(ABSENT_INFORMATION):
1898             return JVMTI_ERROR_ABSENT_INFORMATION;
1899         case JDWP_ERROR(INVALID_EVENT_TYPE):
1900             return JVMTI_ERROR_INVALID_EVENT_TYPE;
1901         case JDWP_ERROR(ILLEGAL_ARGUMENT):
1902             return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1903         case JDWP_ERROR(OUT_OF_MEMORY):
1904             return JVMTI_ERROR_OUT_OF_MEMORY;
1905         case JDWP_ERROR(ACCESS_DENIED):
1906             return JVMTI_ERROR_ACCESS_DENIED;
1907         case JDWP_ERROR(VM_DEAD):
1908             return JVMTI_ERROR_WRONG_PHASE;
1909         case JDWP_ERROR(UNATTACHED_THREAD):
1910             return JVMTI_ERROR_UNATTACHED_THREAD;
1911         case JDWP_ERROR(INVALID_TAG):
1912             return AGENT_ERROR_INVALID_TAG;
1913         case JDWP_ERROR(ALREADY_INVOKING):
1914             return AGENT_ERROR_ALREADY_INVOKING;
1915         case JDWP_ERROR(INVALID_INDEX):
1916             return AGENT_ERROR_INVALID_INDEX;
1917         case JDWP_ERROR(INVALID_LENGTH):
1918             return AGENT_ERROR_INVALID_LENGTH;
1919         case JDWP_ERROR(INVALID_STRING):
1920             return AGENT_ERROR_INVALID_STRING;
1921         case JDWP_ERROR(INVALID_CLASS_LOADER):
1922             return AGENT_ERROR_INVALID_CLASS_LOADER;
1923         case JDWP_ERROR(INVALID_ARRAY):
1924             return AGENT_ERROR_INVALID_ARRAY;
1925         case JDWP_ERROR(TRANSPORT_LOAD):
1926             return AGENT_ERROR_TRANSPORT_LOAD;
1927         case JDWP_ERROR(TRANSPORT_INIT):
1928             return AGENT_ERROR_TRANSPORT_INIT;
1929         case JDWP_ERROR(NATIVE_METHOD):
1930             return AGENT_ERROR_NATIVE_METHOD;
1931         case JDWP_ERROR(INVALID_COUNT):
1932             return AGENT_ERROR_INVALID_COUNT;
1933         case JDWP_ERROR(INTERNAL):
1934             return AGENT_ERROR_JDWP_INTERNAL;
1935     }
1936     return AGENT_ERROR_INTERNAL;
1937 }
1938 
1939 static jvmtiEvent index2jvmti[EI_max-EI_min+1];
1940 static jdwpEvent  index2jdwp [EI_max-EI_min+1];
1941 
1942 void
1943 eventIndexInit(void)
1944 {
1945     (void)memset(index2jvmti, 0, (int)sizeof(index2jvmti));
1946     (void)memset(index2jdwp,  0, (int)sizeof(index2jdwp));
1947 
1948     index2jvmti[EI_SINGLE_STEP        -EI_min] = JVMTI_EVENT_SINGLE_STEP;
1949     index2jvmti[EI_BREAKPOINT         -EI_min] = JVMTI_EVENT_BREAKPOINT;
1950     index2jvmti[EI_FRAME_POP          -EI_min] = JVMTI_EVENT_FRAME_POP;
1951     index2jvmti[EI_EXCEPTION          -EI_min] = JVMTI_EVENT_EXCEPTION;
1952     index2jvmti[EI_THREAD_START       -EI_min] = JVMTI_EVENT_THREAD_START;
1953     index2jvmti[EI_THREAD_END         -EI_min] = JVMTI_EVENT_THREAD_END;
1954     index2jvmti[EI_CLASS_PREPARE      -EI_min] = JVMTI_EVENT_CLASS_PREPARE;
1955     index2jvmti[EI_GC_FINISH          -EI_min] = JVMTI_EVENT_GARBAGE_COLLECTION_FINISH;
1956     index2jvmti[EI_CLASS_LOAD         -EI_min] = JVMTI_EVENT_CLASS_LOAD;
1957     index2jvmti[EI_FIELD_ACCESS       -EI_min] = JVMTI_EVENT_FIELD_ACCESS;
1958     index2jvmti[EI_FIELD_MODIFICATION -EI_min] = JVMTI_EVENT_FIELD_MODIFICATION;
1959     index2jvmti[EI_EXCEPTION_CATCH    -EI_min] = JVMTI_EVENT_EXCEPTION_CATCH;
1960     index2jvmti[EI_METHOD_ENTRY       -EI_min] = JVMTI_EVENT_METHOD_ENTRY;
1961     index2jvmti[EI_METHOD_EXIT        -EI_min] = JVMTI_EVENT_METHOD_EXIT;
1962     index2jvmti[EI_MONITOR_CONTENDED_ENTER      -EI_min] = JVMTI_EVENT_MONITOR_CONTENDED_ENTER;
1963     index2jvmti[EI_MONITOR_CONTENDED_ENTERED    -EI_min] = JVMTI_EVENT_MONITOR_CONTENDED_ENTERED;
1964     index2jvmti[EI_MONITOR_WAIT       -EI_min] = JVMTI_EVENT_MONITOR_WAIT;
1965     index2jvmti[EI_MONITOR_WAITED     -EI_min] = JVMTI_EVENT_MONITOR_WAITED;
1966     index2jvmti[EI_VM_INIT            -EI_min] = JVMTI_EVENT_VM_INIT;
1967     index2jvmti[EI_VM_DEATH           -EI_min] = JVMTI_EVENT_VM_DEATH;
1968 
1969     index2jdwp[EI_SINGLE_STEP         -EI_min] = JDWP_EVENT(SINGLE_STEP);
1970     index2jdwp[EI_BREAKPOINT          -EI_min] = JDWP_EVENT(BREAKPOINT);
1971     index2jdwp[EI_FRAME_POP           -EI_min] = JDWP_EVENT(FRAME_POP);
1972     index2jdwp[EI_EXCEPTION           -EI_min] = JDWP_EVENT(EXCEPTION);
1973     index2jdwp[EI_THREAD_START        -EI_min] = JDWP_EVENT(THREAD_START);
1974     index2jdwp[EI_THREAD_END          -EI_min] = JDWP_EVENT(THREAD_END);
1975     index2jdwp[EI_CLASS_PREPARE       -EI_min] = JDWP_EVENT(CLASS_PREPARE);
1976     index2jdwp[EI_GC_FINISH           -EI_min] = JDWP_EVENT(CLASS_UNLOAD);
1977     index2jdwp[EI_CLASS_LOAD          -EI_min] = JDWP_EVENT(CLASS_LOAD);
1978     index2jdwp[EI_FIELD_ACCESS        -EI_min] = JDWP_EVENT(FIELD_ACCESS);
1979     index2jdwp[EI_FIELD_MODIFICATION  -EI_min] = JDWP_EVENT(FIELD_MODIFICATION);
1980     index2jdwp[EI_EXCEPTION_CATCH     -EI_min] = JDWP_EVENT(EXCEPTION_CATCH);
1981     index2jdwp[EI_METHOD_ENTRY        -EI_min] = JDWP_EVENT(METHOD_ENTRY);
1982     index2jdwp[EI_METHOD_EXIT         -EI_min] = JDWP_EVENT(METHOD_EXIT);
1983     index2jdwp[EI_MONITOR_CONTENDED_ENTER             -EI_min] = JDWP_EVENT(MONITOR_CONTENDED_ENTER);
1984     index2jdwp[EI_MONITOR_CONTENDED_ENTERED           -EI_min] = JDWP_EVENT(MONITOR_CONTENDED_ENTERED);
1985     index2jdwp[EI_MONITOR_WAIT        -EI_min] = JDWP_EVENT(MONITOR_WAIT);
1986     index2jdwp[EI_MONITOR_WAITED      -EI_min] = JDWP_EVENT(MONITOR_WAITED);
1987     index2jdwp[EI_VM_INIT             -EI_min] = JDWP_EVENT(VM_INIT);
1988     index2jdwp[EI_VM_DEATH            -EI_min] = JDWP_EVENT(VM_DEATH);
1989 }
1990 
1991 jdwpEvent
1992 eventIndex2jdwp(EventIndex i)
1993 {
1994     if ( i < EI_min || i > EI_max ) {
1995         EXIT_ERROR(AGENT_ERROR_INVALID_INDEX,"bad EventIndex");
1996     }
1997     return index2jdwp[i-EI_min];
1998 }
1999 
2000 jvmtiEvent
2001 eventIndex2jvmti(EventIndex i)
2002 {
2003     if ( i < EI_min || i > EI_max ) {
2004         EXIT_ERROR(AGENT_ERROR_INVALID_INDEX,"bad EventIndex");
2005     }
2006     return index2jvmti[i-EI_min];
2007 }
2008 
2009 EventIndex
2010 jdwp2EventIndex(jdwpEvent eventType)
2011 {
2012     switch ( eventType ) {
2013         case JDWP_EVENT(SINGLE_STEP):
2014             return EI_SINGLE_STEP;
2015         case JDWP_EVENT(BREAKPOINT):
2016             return EI_BREAKPOINT;
2017         case JDWP_EVENT(FRAME_POP):
2018             return EI_FRAME_POP;
2019         case JDWP_EVENT(EXCEPTION):
2020             return EI_EXCEPTION;
2021         case JDWP_EVENT(THREAD_START):
2022             return EI_THREAD_START;
2023         case JDWP_EVENT(THREAD_END):
2024             return EI_THREAD_END;
2025         case JDWP_EVENT(CLASS_PREPARE):
2026             return EI_CLASS_PREPARE;
2027         case JDWP_EVENT(CLASS_UNLOAD):
2028             return EI_GC_FINISH;
2029         case JDWP_EVENT(CLASS_LOAD):
2030             return EI_CLASS_LOAD;
2031         case JDWP_EVENT(FIELD_ACCESS):
2032             return EI_FIELD_ACCESS;
2033         case JDWP_EVENT(FIELD_MODIFICATION):
2034             return EI_FIELD_MODIFICATION;
2035         case JDWP_EVENT(EXCEPTION_CATCH):
2036             return EI_EXCEPTION_CATCH;
2037         case JDWP_EVENT(METHOD_ENTRY):
2038             return EI_METHOD_ENTRY;
2039         case JDWP_EVENT(METHOD_EXIT):
2040             return EI_METHOD_EXIT;
2041         case JDWP_EVENT(METHOD_EXIT_WITH_RETURN_VALUE):
2042             return EI_METHOD_EXIT;
2043         case JDWP_EVENT(MONITOR_CONTENDED_ENTER):
2044             return EI_MONITOR_CONTENDED_ENTER;
2045         case JDWP_EVENT(MONITOR_CONTENDED_ENTERED):
2046             return EI_MONITOR_CONTENDED_ENTERED;
2047         case JDWP_EVENT(MONITOR_WAIT):
2048             return EI_MONITOR_WAIT;
2049         case JDWP_EVENT(MONITOR_WAITED):
2050             return EI_MONITOR_WAITED;
2051         case JDWP_EVENT(VM_INIT):
2052             return EI_VM_INIT;
2053         case JDWP_EVENT(VM_DEATH):
2054             return EI_VM_DEATH;
2055         default:
2056             break;
2057     }
2058 
2059     /*
2060      * Event type not recognized - don't exit with error as caller
2061      * may wish to return error to debugger.
2062      */
2063     return (EventIndex)0;
2064 }
2065 
2066 EventIndex
2067 jvmti2EventIndex(jvmtiEvent kind)
2068 {
2069     switch ( kind ) {
2070         case JVMTI_EVENT_SINGLE_STEP:
2071             return EI_SINGLE_STEP;
2072         case JVMTI_EVENT_BREAKPOINT:
2073             return EI_BREAKPOINT;
2074         case JVMTI_EVENT_FRAME_POP:
2075             return EI_FRAME_POP;
2076         case JVMTI_EVENT_EXCEPTION:
2077             return EI_EXCEPTION;
2078         case JVMTI_EVENT_THREAD_START:
2079             return EI_THREAD_START;
2080         case JVMTI_EVENT_THREAD_END:
2081             return EI_THREAD_END;
2082         case JVMTI_EVENT_CLASS_PREPARE:
2083             return EI_CLASS_PREPARE;
2084         case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
2085             return EI_GC_FINISH;
2086         case JVMTI_EVENT_CLASS_LOAD:
2087             return EI_CLASS_LOAD;
2088         case JVMTI_EVENT_FIELD_ACCESS:
2089             return EI_FIELD_ACCESS;
2090         case JVMTI_EVENT_FIELD_MODIFICATION:
2091             return EI_FIELD_MODIFICATION;
2092         case JVMTI_EVENT_EXCEPTION_CATCH:
2093             return EI_EXCEPTION_CATCH;
2094         case JVMTI_EVENT_METHOD_ENTRY:
2095             return EI_METHOD_ENTRY;
2096         case JVMTI_EVENT_METHOD_EXIT:
2097             return EI_METHOD_EXIT;
2098         /*
2099          * There is no JVMTI_EVENT_METHOD_EXIT_WITH_RETURN_VALUE.
2100          * The normal JVMTI_EVENT_METHOD_EXIT always contains the return value.
2101          */
2102         case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
2103             return EI_MONITOR_CONTENDED_ENTER;
2104         case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
2105             return EI_MONITOR_CONTENDED_ENTERED;
2106         case JVMTI_EVENT_MONITOR_WAIT:
2107             return EI_MONITOR_WAIT;
2108         case JVMTI_EVENT_MONITOR_WAITED:
2109             return EI_MONITOR_WAITED;
2110         case JVMTI_EVENT_VM_INIT:
2111             return EI_VM_INIT;
2112         case JVMTI_EVENT_VM_DEATH:
2113             return EI_VM_DEATH;
2114         default:
2115             EXIT_ERROR(AGENT_ERROR_INVALID_INDEX,"JVMTI to EventIndex mapping");
2116             break;
2117     }
2118     return (EventIndex)0;
2119 }
2120 
2121 /* This routine is commonly used, maps jvmti and agent errors to the best
2122  *    jdwp error code we can map to.
2123  */
2124 jdwpError
2125 map2jdwpError(jvmtiError error)
2126 {
2127     switch ( error ) {
2128         case JVMTI_ERROR_NONE:
2129             return JDWP_ERROR(NONE);
2130         case AGENT_ERROR_INVALID_THREAD:
2131         case JVMTI_ERROR_INVALID_THREAD:
2132             return JDWP_ERROR(INVALID_THREAD);
2133         case JVMTI_ERROR_INVALID_THREAD_GROUP:
2134             return JDWP_ERROR(INVALID_THREAD_GROUP);
2135         case JVMTI_ERROR_INVALID_PRIORITY:
2136             return JDWP_ERROR(INVALID_PRIORITY);
2137         case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
2138             return JDWP_ERROR(THREAD_NOT_SUSPENDED);
2139         case JVMTI_ERROR_THREAD_SUSPENDED:
2140             return JDWP_ERROR(THREAD_SUSPENDED);
2141         case JVMTI_ERROR_THREAD_NOT_ALIVE:
2142             return JDWP_ERROR(INVALID_THREAD);
2143         case AGENT_ERROR_INVALID_OBJECT:
2144         case JVMTI_ERROR_INVALID_OBJECT:
2145             return JDWP_ERROR(INVALID_OBJECT);
2146         case JVMTI_ERROR_INVALID_CLASS:
2147             return JDWP_ERROR(INVALID_CLASS);
2148         case JVMTI_ERROR_CLASS_NOT_PREPARED:
2149             return JDWP_ERROR(CLASS_NOT_PREPARED);
2150         case JVMTI_ERROR_INVALID_METHODID:
2151             return JDWP_ERROR(INVALID_METHODID);
2152         case JVMTI_ERROR_INVALID_LOCATION:
2153             return JDWP_ERROR(INVALID_LOCATION);
2154         case JVMTI_ERROR_INVALID_FIELDID:
2155             return JDWP_ERROR(INVALID_FIELDID);
2156         case AGENT_ERROR_NO_MORE_FRAMES:
2157         case JVMTI_ERROR_NO_MORE_FRAMES:
2158             return JDWP_ERROR(NO_MORE_FRAMES);
2159         case JVMTI_ERROR_OPAQUE_FRAME:
2160             return JDWP_ERROR(OPAQUE_FRAME);
2161         case JVMTI_ERROR_TYPE_MISMATCH:
2162             return JDWP_ERROR(TYPE_MISMATCH);
2163         case JVMTI_ERROR_INVALID_SLOT:
2164             return JDWP_ERROR(INVALID_SLOT);
2165         case JVMTI_ERROR_DUPLICATE:
2166             return JDWP_ERROR(DUPLICATE);
2167         case JVMTI_ERROR_NOT_FOUND:
2168             return JDWP_ERROR(NOT_FOUND);
2169         case JVMTI_ERROR_INVALID_MONITOR:
2170             return JDWP_ERROR(INVALID_MONITOR);
2171         case JVMTI_ERROR_NOT_MONITOR_OWNER:
2172             return JDWP_ERROR(NOT_MONITOR_OWNER);
2173         case JVMTI_ERROR_INTERRUPT:
2174             return JDWP_ERROR(INTERRUPT);
2175         case JVMTI_ERROR_INVALID_CLASS_FORMAT:
2176             return JDWP_ERROR(INVALID_CLASS_FORMAT);
2177         case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
2178             return JDWP_ERROR(CIRCULAR_CLASS_DEFINITION);
2179         case JVMTI_ERROR_FAILS_VERIFICATION:
2180             return JDWP_ERROR(FAILS_VERIFICATION);
2181         case JVMTI_ERROR_INVALID_TYPESTATE:
2182             return JDWP_ERROR(INVALID_TYPESTATE);
2183         case JVMTI_ERROR_UNSUPPORTED_VERSION:
2184             return JDWP_ERROR(UNSUPPORTED_VERSION);
2185         case JVMTI_ERROR_NAMES_DONT_MATCH:
2186             return JDWP_ERROR(NAMES_DONT_MATCH);
2187         case AGENT_ERROR_NULL_POINTER:
2188         case JVMTI_ERROR_NULL_POINTER:
2189             return JDWP_ERROR(NULL_POINTER);
2190         case JVMTI_ERROR_ABSENT_INFORMATION:
2191             return JDWP_ERROR(ABSENT_INFORMATION);
2192         case AGENT_ERROR_INVALID_EVENT_TYPE:
2193         case JVMTI_ERROR_INVALID_EVENT_TYPE:
2194             return JDWP_ERROR(INVALID_EVENT_TYPE);
2195         case AGENT_ERROR_ILLEGAL_ARGUMENT:
2196         case JVMTI_ERROR_ILLEGAL_ARGUMENT:
2197             return JDWP_ERROR(ILLEGAL_ARGUMENT);
2198         case JVMTI_ERROR_OUT_OF_MEMORY:
2199         case AGENT_ERROR_OUT_OF_MEMORY:
2200             return JDWP_ERROR(OUT_OF_MEMORY);
2201         case JVMTI_ERROR_ACCESS_DENIED:
2202             return JDWP_ERROR(ACCESS_DENIED);
2203         case JVMTI_ERROR_WRONG_PHASE:
2204         case AGENT_ERROR_VM_DEAD:
2205         case AGENT_ERROR_NO_JNI_ENV:
2206             return JDWP_ERROR(VM_DEAD);
2207         case AGENT_ERROR_JNI_EXCEPTION:
2208         case JVMTI_ERROR_UNATTACHED_THREAD:
2209             return JDWP_ERROR(UNATTACHED_THREAD);
2210         case JVMTI_ERROR_NOT_AVAILABLE:
2211         case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
2212             return JDWP_ERROR(NOT_IMPLEMENTED);
2213         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
2214             return JDWP_ERROR(HIERARCHY_CHANGE_NOT_IMPLEMENTED);
2215         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
2216             return JDWP_ERROR(DELETE_METHOD_NOT_IMPLEMENTED);
2217         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
2218             return JDWP_ERROR(ADD_METHOD_NOT_IMPLEMENTED);
2219         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
2220             return JDWP_ERROR(SCHEMA_CHANGE_NOT_IMPLEMENTED);
2221         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
2222             return JDWP_ERROR(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED);
2223         case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
2224             return JDWP_ERROR(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED);
2225         case AGENT_ERROR_NOT_CURRENT_FRAME:
2226             return JDWP_ERROR(NOT_CURRENT_FRAME);
2227         case AGENT_ERROR_INVALID_TAG:
2228             return JDWP_ERROR(INVALID_TAG);
2229         case AGENT_ERROR_ALREADY_INVOKING:
2230             return JDWP_ERROR(ALREADY_INVOKING);
2231         case AGENT_ERROR_INVALID_INDEX:
2232             return JDWP_ERROR(INVALID_INDEX);
2233         case AGENT_ERROR_INVALID_LENGTH:
2234             return JDWP_ERROR(INVALID_LENGTH);
2235         case AGENT_ERROR_INVALID_STRING:
2236             return JDWP_ERROR(INVALID_STRING);
2237         case AGENT_ERROR_INVALID_CLASS_LOADER:
2238             return JDWP_ERROR(INVALID_CLASS_LOADER);
2239         case AGENT_ERROR_INVALID_ARRAY:
2240             return JDWP_ERROR(INVALID_ARRAY);
2241         case AGENT_ERROR_TRANSPORT_LOAD:
2242             return JDWP_ERROR(TRANSPORT_LOAD);
2243         case AGENT_ERROR_TRANSPORT_INIT:
2244             return JDWP_ERROR(TRANSPORT_INIT);
2245         case AGENT_ERROR_NATIVE_METHOD:
2246             return JDWP_ERROR(NATIVE_METHOD);
2247         case AGENT_ERROR_INVALID_COUNT:
2248             return JDWP_ERROR(INVALID_COUNT);
2249         case AGENT_ERROR_INVALID_FRAMEID:
2250             return JDWP_ERROR(INVALID_FRAMEID);
2251         case JVMTI_ERROR_INTERNAL:
2252         case JVMTI_ERROR_INVALID_ENVIRONMENT:
2253         case AGENT_ERROR_INTERNAL:
2254         case AGENT_ERROR_JVMTI_INTERNAL:
2255         case AGENT_ERROR_JDWP_INTERNAL:
2256             return JDWP_ERROR(INTERNAL);
2257         default:
2258             break;
2259     }
2260     return JDWP_ERROR(INTERNAL);
2261 }
2262 
2263 jint
2264 map2jdwpSuspendStatus(jint state)
2265 {
2266     jint status = 0;
2267     if ( ( state & JVMTI_THREAD_STATE_SUSPENDED ) != 0 )  {
2268         status = JDWP_SUSPEND_STATUS(SUSPENDED);
2269     }
2270     return status;
2271 }
2272 
2273 jdwpThreadStatus
2274 map2jdwpThreadStatus(jint state)
2275 {
2276     jdwpThreadStatus status;
2277 
2278     status = (jdwpThreadStatus)(-1);
2279 
2280     if ( ! ( state & JVMTI_THREAD_STATE_ALIVE ) ) {
2281         if ( state & JVMTI_THREAD_STATE_TERMINATED ) {
2282             status = JDWP_THREAD_STATUS(ZOMBIE);
2283         } else {
2284             /* FIXUP? New JDWP #define for not started? */
2285             status = (jdwpThreadStatus)(-1);
2286         }
2287     } else {
2288         if ( state & JVMTI_THREAD_STATE_SLEEPING ) {
2289             status = JDWP_THREAD_STATUS(SLEEPING);
2290         } else if ( state & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER ) {
2291             status = JDWP_THREAD_STATUS(MONITOR);
2292         } else if ( state & JVMTI_THREAD_STATE_WAITING ) {
2293             status = JDWP_THREAD_STATUS(WAIT);
2294         } else if ( state & JVMTI_THREAD_STATE_RUNNABLE ) {
2295             status = JDWP_THREAD_STATUS(RUNNING);
2296         }
2297     }
2298     return status;
2299 }
2300 
2301 jint
2302 map2jdwpClassStatus(jint classStatus)
2303 {
2304     jint status = 0;
2305     if ( ( classStatus & JVMTI_CLASS_STATUS_VERIFIED ) != 0 ) {
2306         status |= JDWP_CLASS_STATUS(VERIFIED);
2307     }
2308     if ( ( classStatus & JVMTI_CLASS_STATUS_PREPARED ) != 0 ) {
2309         status |= JDWP_CLASS_STATUS(PREPARED);
2310     }
2311     if ( ( classStatus & JVMTI_CLASS_STATUS_INITIALIZED ) != 0 ) {
2312         status |= JDWP_CLASS_STATUS(INITIALIZED);
2313     }
2314     if ( ( classStatus & JVMTI_CLASS_STATUS_ERROR ) != 0 ) {
2315         status |= JDWP_CLASS_STATUS(ERROR);
2316     }
2317     return status;
2318 }
2319 
2320 void
2321 log_debugee_location(const char *func,
2322         jthread thread, jmethodID method, jlocation location)
2323 {
2324     int logging_locations = LOG_TEST(JDWP_LOG_LOC);
2325 
2326     if ( logging_locations ) {
2327         char *method_name;
2328         char *class_sig;
2329         jvmtiError error;
2330         jvmtiThreadInfo info;
2331         jint state;
2332 
2333         /* Get thread information */
2334         info.name = NULL;
2335         error = FUNC_PTR(gdata->jvmti,GetThreadInfo)
2336                                 (gdata->jvmti, thread, &info);
2337         if ( error != JVMTI_ERROR_NONE) {
2338             info.name = NULL;
2339         }
2340         error = FUNC_PTR(gdata->jvmti,GetThreadState)
2341                                 (gdata->jvmti, thread, &state);
2342         if ( error != JVMTI_ERROR_NONE) {
2343             state = 0;
2344         }
2345 
2346         /* Get method if necessary */
2347         if ( method==NULL ) {
2348             error = FUNC_PTR(gdata->jvmti,GetFrameLocation)
2349                         (gdata->jvmti, thread, 0, &method, &location);
2350             if ( error != JVMTI_ERROR_NONE ) {
2351                 method = NULL;
2352                 location = 0;
2353             }
2354         }
2355 
2356         /* Get method name */
2357         method_name = NULL;
2358         if ( method != NULL ) {
2359             error = methodSignature(method, &method_name, NULL, NULL);
2360             if ( error != JVMTI_ERROR_NONE ) {
2361                 method_name = NULL;
2362             }
2363         }
2364 
2365         /* Get class signature */
2366         class_sig = NULL;
2367         if ( method != NULL ) {
2368             jclass clazz;
2369 
2370             error = methodClass(method, &clazz);
2371             if ( error == JVMTI_ERROR_NONE ) {
2372                 error = classSignature(clazz, &class_sig, NULL);
2373                 if ( error != JVMTI_ERROR_NONE ) {
2374                     class_sig = NULL;
2375                 }
2376             }
2377         }
2378 
2379         /* Issue log message */
2380         LOG_LOC(("%s: debugee: thread=%p(%s:0x%x),method=%p(%s@%d;%s)",
2381                 func,
2382                 thread, info.name==NULL ? "?" : info.name, state,
2383                 method, method_name==NULL ? "?" : method_name,
2384                 (int)location, class_sig==NULL ? "?" : class_sig));
2385 
2386         /* Free memory */
2387         if ( class_sig != NULL ) {
2388             jvmtiDeallocate(class_sig);
2389         }
2390         if ( method_name != NULL ) {
2391             jvmtiDeallocate(method_name);
2392         }
2393         if ( info.name != NULL ) {
2394             jvmtiDeallocate(info.name);
2395         }
2396     }
2397 }
2398 
2399 /* ********************************************************************* */
2400 /* JDK 6.0: Use of new Heap Iteration functions */
2401 /* ********************************************************************* */
2402 
2403 /* ********************************************************************* */
2404 /* Instances */
2405 
2406 /* Structure to hold class instances heap iteration data (arg user_data) */
2407 typedef struct ClassInstancesData {
2408     jint         instCount;
2409     jint         maxInstances;
2410     jlong        objTag;
2411     jvmtiError   error;
2412 } ClassInstancesData;
2413 
2414 /* Callback for instance object tagging (heap_reference_callback). */
2415 static jint JNICALL
2416 cbObjectTagInstance(jvmtiHeapReferenceKind reference_kind,
2417      const jvmtiHeapReferenceInfo* reference_info, jlong class_tag,
2418      jlong referrer_class_tag, jlong size,
2419      jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data)
2420 {
2421     ClassInstancesData  *data;
2422 
2423     /* Check data structure */
2424     data = (ClassInstancesData*)user_data;
2425     if (data == NULL) {
2426         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2427         return JVMTI_VISIT_ABORT;
2428     }
2429 
2430     /* If we have tagged enough objects, just abort */
2431     if ( data->maxInstances != 0 && data->instCount >= data->maxInstances ) {
2432         return JVMTI_VISIT_ABORT;
2433     }
2434 
2435     /* If tagged already, just continue */
2436     if ( (*tag_ptr) != (jlong)0 ) {
2437         return JVMTI_VISIT_OBJECTS;
2438     }
2439 
2440     /* Tag the object so we don't count it again, and so we can retrieve it */
2441     (*tag_ptr) = data->objTag;
2442     data->instCount++;
2443     return JVMTI_VISIT_OBJECTS;
2444 }
2445 
2446 /* Get instances for one class */
2447 jvmtiError
2448 classInstances(jclass klass, ObjectBatch *instances, int maxInstances)
2449 {
2450     ClassInstancesData data;
2451     jvmtiHeapCallbacks heap_callbacks;
2452     jvmtiError         error;
2453     jvmtiEnv          *jvmti;
2454 
2455     /* Check interface assumptions */
2456 
2457     if (klass == NULL) {
2458         return AGENT_ERROR_INVALID_OBJECT;
2459     }
2460 
2461     if ( maxInstances < 0 || instances == NULL) {
2462         return AGENT_ERROR_ILLEGAL_ARGUMENT;
2463     }
2464 
2465     /* Initialize return information */
2466     instances->count   = 0;
2467     instances->objects = NULL;
2468 
2469     /* Get jvmti environment to use */
2470     jvmti = getSpecialJvmti();
2471     if ( jvmti == NULL ) {
2472         return AGENT_ERROR_INTERNAL;
2473     }
2474 
2475     /* Setup data to passed around the callbacks */
2476     data.instCount    = 0;
2477     data.maxInstances = maxInstances;
2478     data.objTag       = (jlong)1;
2479     data.error        = JVMTI_ERROR_NONE;
2480 
2481     /* Clear out callbacks structure */
2482     (void)memset(&heap_callbacks,0,sizeof(heap_callbacks));
2483 
2484     /* Set the callbacks we want */
2485     heap_callbacks.heap_reference_callback = &cbObjectTagInstance;
2486 
2487     /* Follow references, no initiating object, just this class, all objects */
2488     error = JVMTI_FUNC_PTR(jvmti,FollowReferences)
2489                  (jvmti, 0, klass, NULL, &heap_callbacks, &data);
2490     if ( error == JVMTI_ERROR_NONE ) {
2491         error = data.error;
2492     }
2493 
2494     /* Get all the instances now that they are tagged */
2495     if ( error == JVMTI_ERROR_NONE ) {
2496         error = JVMTI_FUNC_PTR(jvmti,GetObjectsWithTags)
2497                       (jvmti, 1, &(data.objTag), &(instances->count),
2498                        &(instances->objects), NULL);
2499         /* Verify we got the count we expected */
2500         if ( data.instCount != instances->count ) {
2501             error = AGENT_ERROR_INTERNAL;
2502         }
2503     }
2504 
2505     /* Dispose of any special jvmti environment */
2506     (void)JVMTI_FUNC_PTR(jvmti,DisposeEnvironment)(jvmti);
2507     return error;
2508 }
2509 
2510 /* ********************************************************************* */
2511 /* Instance counts. */
2512 
2513 /* Macros to convert a class or instance tag to an index and back again */
2514 #define INDEX2CLASSTAG(i)      ((jlong)((i)+1))
2515 #define CLASSTAG2INDEX(t)      (((int)(t))-1)
2516 #define JLONG_ABS(x)           (((x)<(jlong)0)?-(x):(x))
2517 
2518 /* Structure to hold class count heap traversal data (arg user_data) */
2519 typedef struct ClassCountData {
2520     int          classCount;
2521     jlong       *counts;
2522     jlong        negObjTag;
2523     jvmtiError   error;
2524 } ClassCountData;
2525 
2526 /* Two different cbObjectCounter's, one for FollowReferences, one for
2527  *    IterateThroughHeap. Pick a card, any card.
2528  */
2529 
2530 /* Callback for object count heap traversal (heap_reference_callback) */
2531 static jint JNICALL
2532 cbObjectCounterFromRef(jvmtiHeapReferenceKind reference_kind,
2533      const jvmtiHeapReferenceInfo* reference_info, jlong class_tag,
2534      jlong referrer_class_tag, jlong size,
2535      jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data)
2536 {
2537     ClassCountData  *data;
2538     int              index;
2539     jlong            jindex;
2540     jlong            tag;
2541 
2542     /* Check data structure */
2543     data = (ClassCountData*)user_data;
2544     if (data == NULL) {
2545         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2546         return JVMTI_VISIT_ABORT;
2547     }
2548 
2549     /* Classes with no class_tag should have been filtered out. */
2550     if ( class_tag == (jlong)0 ) {
2551         data->error = AGENT_ERROR_INTERNAL;
2552         return JVMTI_VISIT_ABORT;
2553     }
2554 
2555     /* Class tag not one we really want (jclass not in supplied list) */
2556     if ( class_tag == data->negObjTag ) {
2557         return JVMTI_VISIT_OBJECTS;
2558     }
2559 
2560     /* If object tag is negative, just continue, we counted it */
2561     tag = (*tag_ptr);
2562     if ( tag < (jlong)0 ) {
2563         return JVMTI_VISIT_OBJECTS;
2564     }
2565 
2566     /* Tag the object with a negative value just so we don't count it again */
2567     if ( tag == (jlong)0 ) {
2568         /* This object had no tag value, so we give it the negObjTag value */
2569         (*tag_ptr) = data->negObjTag;
2570     } else {
2571         /* If this object had a positive tag value, it must be one of the
2572          *    jclass objects we tagged. We need to preserve the value of
2573          *    this tag for later objects that might have this as a class
2574          *    tag, so we just make the existing tag value negative.
2575          */
2576         (*tag_ptr) = -tag;
2577     }
2578 
2579     /* Absolute value of class tag is an index into the counts[] array */
2580     jindex = JLONG_ABS(class_tag);
2581     index = CLASSTAG2INDEX(jindex);
2582     if (index < 0 || index >= data->classCount) {
2583         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2584         return JVMTI_VISIT_ABORT;
2585     }
2586 
2587     /* Bump instance count on this class */
2588     data->counts[index]++;
2589     return JVMTI_VISIT_OBJECTS;
2590 }
2591 
2592 /* Callback for instance count heap traversal (heap_iteration_callback) */
2593 static jint JNICALL
2594 cbObjectCounter(jlong class_tag, jlong size, jlong* tag_ptr, jint length,
2595                         void* user_data)
2596 {
2597     ClassCountData  *data;
2598     int              index;
2599 
2600     /* Check data structure */
2601     data = (ClassCountData*)user_data;
2602     if (data == NULL) {
2603         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2604         return JVMTI_VISIT_ABORT;
2605     }
2606 
2607     /* Classes with no tag should be filtered out. */
2608     if ( class_tag == (jlong)0 ) {
2609         data->error = AGENT_ERROR_INTERNAL;
2610         return JVMTI_VISIT_ABORT;
2611     }
2612 
2613     /* Class tag is actually an index into data arrays */
2614     index = CLASSTAG2INDEX(class_tag);
2615     if (index < 0 || index >= data->classCount) {
2616         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2617         return JVMTI_VISIT_ABORT;
2618     }
2619 
2620     /* Bump instance count on this class */
2621     data->counts[index]++;
2622     return JVMTI_VISIT_OBJECTS;
2623 }
2624 
2625 /* Get instance counts for a set of classes */
2626 jvmtiError
2627 classInstanceCounts(jint classCount, jclass *classes, jlong *counts)
2628 {
2629     jvmtiHeapCallbacks heap_callbacks;
2630     ClassCountData     data;
2631     jvmtiError         error;
2632     jvmtiEnv          *jvmti;
2633     int                i;
2634 
2635     /* Check interface assumptions */
2636     if ( classes == NULL || classCount <= 0 || counts == NULL ) {
2637         return AGENT_ERROR_ILLEGAL_ARGUMENT;
2638     }
2639 
2640     /* Initialize return information */
2641     for ( i = 0 ; i < classCount ; i++ ) {
2642         counts[i] = (jlong)0;
2643     }
2644 
2645     /* Get jvmti environment to use */
2646     jvmti = getSpecialJvmti();
2647     if ( jvmti == NULL ) {
2648         return AGENT_ERROR_INTERNAL;
2649     }
2650 
2651     /* Setup class data structure */
2652     data.error        = JVMTI_ERROR_NONE;
2653     data.classCount   = classCount;
2654     data.counts       = counts;
2655 
2656     error = JVMTI_ERROR_NONE;
2657     /* Set tags on classes, use index in classes[] as the tag value. */
2658     error             = JVMTI_ERROR_NONE;
2659     for ( i = 0 ; i < classCount ; i++ ) {
2660         if (classes[i] != NULL) {
2661             jlong tag;
2662 
2663             tag = INDEX2CLASSTAG(i);
2664             error = JVMTI_FUNC_PTR(jvmti,SetTag) (jvmti, classes[i], tag);
2665             if ( error != JVMTI_ERROR_NONE ) {
2666                 break;
2667             }
2668         }
2669     }
2670 
2671     /* Traverse heap, two ways to do this for instance counts. */
2672     if ( error == JVMTI_ERROR_NONE ) {
2673 
2674         /* Clear out callbacks structure */
2675         (void)memset(&heap_callbacks,0,sizeof(heap_callbacks));
2676 
2677         /* Check debug flags to see how to do this. */
2678         if ( (gdata->debugflags & USE_ITERATE_THROUGH_HEAP) == 0 ) {
2679 
2680             /* Using FollowReferences only gives us live objects, but we
2681              *   need to tag the objects to avoid counting them twice since
2682              *   the callback is per reference.
2683              *   The jclass objects have been tagged with their index in the
2684              *   supplied list, and that tag may flip to negative if it
2685              *   is also an object of interest.
2686              *   All other objects being counted that weren't in the
2687              *   supplied classes list will have a negative classCount
2688              *   tag value. So all objects counted will have negative tags.
2689              *   If the absolute tag value is an index in the supplied
2690              *   list, then it's one of the supplied classes.
2691              */
2692             data.negObjTag = -INDEX2CLASSTAG(classCount);
2693 
2694             /* Setup callbacks, only using object reference callback */
2695             heap_callbacks.heap_reference_callback = &cbObjectCounterFromRef;
2696 
2697             /* Follow references, no initiating object, tagged classes only */
2698             error = JVMTI_FUNC_PTR(jvmti,FollowReferences)
2699                           (jvmti, JVMTI_HEAP_FILTER_CLASS_UNTAGGED,
2700                            NULL, NULL, &heap_callbacks, &data);
2701 
2702         } else {
2703 
2704             /* Using IterateThroughHeap means that we will visit each object
2705              *   once, so no special tag tricks here. Just simple counting.
2706              *   However in this case the object might not be live, so we do
2707              *   a GC beforehand to make sure we minimize this.
2708              */
2709 
2710             /* FIXUP: Need some kind of trigger here to avoid excessive GC's? */
2711             error = JVMTI_FUNC_PTR(jvmti,ForceGarbageCollection)(jvmti);
2712             if ( error != JVMTI_ERROR_NONE ) {
2713 
2714                 /* Setup callbacks, just need object callback */
2715                 heap_callbacks.heap_iteration_callback = &cbObjectCounter;
2716 
2717                 /* Iterate through entire heap, tagged classes only */
2718                 error = JVMTI_FUNC_PTR(jvmti,IterateThroughHeap)
2719                               (jvmti, JVMTI_HEAP_FILTER_CLASS_UNTAGGED,
2720                                NULL, &heap_callbacks, &data);
2721 
2722             }
2723         }
2724 
2725         /* Use data error if needed */
2726         if ( error == JVMTI_ERROR_NONE ) {
2727             error = data.error;
2728         }
2729 
2730     }
2731 
2732     /* Dispose of any special jvmti environment */
2733     (void)JVMTI_FUNC_PTR(jvmti,DisposeEnvironment)(jvmti);
2734     return error;
2735 }
2736 
2737 /* ********************************************************************* */
2738 /* Referrers */
2739 
2740 /* Structure to hold object referrer heap traversal data (arg user_data) */
2741 typedef struct ReferrerData {
2742   int        refCount;
2743   int        maxObjects;
2744   jlong      refTag;
2745   jlong      objTag;
2746   jboolean   selfRef;
2747   jvmtiError error;
2748 } ReferrerData;
2749 
2750 /* Callback for referrers object tagging (heap_reference_callback). */
2751 static jint JNICALL
2752 cbObjectTagReferrer(jvmtiHeapReferenceKind reference_kind,
2753      const jvmtiHeapReferenceInfo* reference_info, jlong class_tag,
2754      jlong referrer_class_tag, jlong size,
2755      jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data)
2756 {
2757     ReferrerData  *data;
2758 
2759     /* Check data structure */
2760     data = (ReferrerData*)user_data;
2761     if (data == NULL) {
2762         data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
2763         return JVMTI_VISIT_ABORT;
2764     }
2765 
2766     /* If we have tagged enough objects, just abort */
2767     if ( data->maxObjects != 0 && data->refCount >= data->maxObjects ) {
2768         return JVMTI_VISIT_ABORT;
2769     }
2770 
2771     /* If not of interest, just continue */
2772     if ( (*tag_ptr) != data->objTag ) {
2773         return JVMTI_VISIT_OBJECTS;
2774     }
2775 
2776     /* Self reference that we haven't counted? */
2777     if ( tag_ptr == referrer_tag_ptr ) {
2778         if ( data->selfRef == JNI_FALSE ) {
2779             data->selfRef = JNI_TRUE;
2780             data->refCount++;
2781         }
2782         return JVMTI_VISIT_OBJECTS;
2783     }
2784 
2785     /* If the referrer can be tagged, and hasn't been tagged, tag it */
2786     if ( referrer_tag_ptr != NULL ) {
2787         if ( (*referrer_tag_ptr) == (jlong)0 ) {
2788             *referrer_tag_ptr = data->refTag;
2789             data->refCount++;
2790         }
2791     }
2792     return JVMTI_VISIT_OBJECTS;
2793 }
2794 
2795 /* Heap traversal to find referrers of an object */
2796 jvmtiError
2797 objectReferrers(jobject obj, ObjectBatch *referrers, int maxObjects)
2798 {
2799     jvmtiHeapCallbacks heap_callbacks;
2800     ReferrerData       data;
2801     jvmtiError         error;
2802     jvmtiEnv          *jvmti;
2803 
2804     /* Check interface assumptions */
2805     if (obj == NULL) {
2806         return AGENT_ERROR_INVALID_OBJECT;
2807     }
2808     if (referrers == NULL || maxObjects < 0 ) {
2809         return AGENT_ERROR_ILLEGAL_ARGUMENT;
2810     }
2811 
2812     /* Initialize return information */
2813     referrers->count = 0;
2814     referrers->objects = NULL;
2815 
2816     /* Get jvmti environment to use */
2817     jvmti = getSpecialJvmti();
2818     if ( jvmti == NULL ) {
2819         return AGENT_ERROR_INTERNAL;
2820     }
2821 
2822     /* Fill in the data structure passed around the callbacks */
2823     data.refCount   = 0;
2824     data.maxObjects = maxObjects;
2825     data.objTag     = (jlong)1;
2826     data.refTag     = (jlong)2;
2827     data.selfRef    = JNI_FALSE;
2828     data.error      = JVMTI_ERROR_NONE;
2829 
2830     /* Tag the object of interest */
2831     error = JVMTI_FUNC_PTR(jvmti,SetTag) (jvmti, obj, data.objTag);
2832 
2833     /* No need to go any further if we can't tag the object */
2834     if ( error == JVMTI_ERROR_NONE ) {
2835 
2836         /* Clear out callbacks structure */
2837         (void)memset(&heap_callbacks,0,sizeof(heap_callbacks));
2838 
2839         /* Setup callbacks we want */
2840         heap_callbacks.heap_reference_callback = &cbObjectTagReferrer;
2841 
2842         /* Follow references, no initiating object, all classes, 1 tagged objs */
2843         error = JVMTI_FUNC_PTR(jvmti,FollowReferences)
2844                       (jvmti, JVMTI_HEAP_FILTER_UNTAGGED,
2845                        NULL, NULL, &heap_callbacks, &data);
2846 
2847         /* Use data error if needed */
2848         if ( error == JVMTI_ERROR_NONE ) {
2849             error = data.error;
2850         }
2851 
2852     }
2853 
2854     /* Watch out for self-reference */
2855     if ( error == JVMTI_ERROR_NONE && data.selfRef == JNI_TRUE ) {
2856         /* Tag itself as a referer */
2857         error = JVMTI_FUNC_PTR(jvmti,SetTag) (jvmti, obj, data.refTag);
2858     }
2859 
2860     /* Get the jobjects for the tagged referrer objects.  */
2861     if ( error == JVMTI_ERROR_NONE ) {
2862         error = JVMTI_FUNC_PTR(jvmti,GetObjectsWithTags)
2863                     (jvmti, 1, &(data.refTag), &(referrers->count),
2864                           &(referrers->objects), NULL);
2865         /* Verify we got the count we expected */
2866         if ( data.refCount != referrers->count ) {
2867             error = AGENT_ERROR_INTERNAL;
2868         }
2869     }
2870 
2871     /* Dispose of any special jvmti environment */
2872     (void)JVMTI_FUNC_PTR(jvmti,DisposeEnvironment)(jvmti);
2873     return error;
2874 }