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