/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Handle messages from debugger.
 *
 * GENERAL NOTE: we're not currently testing the message length for
 * correctness.  This is usually a bad idea, but here we can probably
 * get away with it so long as the debugger isn't broken.  We can
 * change the "read" macros to use "dataLen" to avoid wandering into
 * bad territory, and have a single "is dataLen correct" check at the
 * end of each function.  Not needed at this time.
 */

#include "atomic.h"
#include "debugger.h"
#include "jdwp/jdwp_priv.h"
#include "jdwp/jdwp_handler.h"
#include "jdwp/jdwp_event.h"
#include "jdwp/jdwp_constants.h"
#include "jdwp/jdwp_expand_buf.h"
#include "logging.h"
#include "macros.h"
#include "stringprintf.h"

#include <stdlib.h>
#include <string.h>
#include <unistd.h>

namespace art {

namespace JDWP {

/*
 * Helper function: read a "location" from an input buffer.
 */
static void jdwpReadLocation(const uint8_t** pBuf, JdwpLocation* pLoc) {
  memset(pLoc, 0, sizeof(*pLoc));     /* allows memcmp() later */
  pLoc->typeTag = ReadTypeTag(pBuf);
  pLoc->classId = ReadObjectId(pBuf);
  pLoc->methodId = ReadMethodId(pBuf);
  pLoc->idx = Read8BE(pBuf);
}

/*
 * Helper function: write a "location" into the reply buffer.
 */
void AddLocation(ExpandBuf* pReply, const JdwpLocation* pLoc) {
  expandBufAdd1(pReply, pLoc->typeTag);
  expandBufAddObjectId(pReply, pLoc->classId);
  expandBufAddMethodId(pReply, pLoc->methodId);
  expandBufAdd8BE(pReply, pLoc->idx);
}

/*
 * Helper function: read a variable-width value from the input buffer.
 */
static uint64_t jdwpReadValue(const uint8_t** pBuf, size_t width) {
  uint64_t value = -1;
  switch (width) {
  case 1:     value = Read1(pBuf); break;
  case 2:     value = Read2BE(pBuf); break;
  case 4:     value = Read4BE(pBuf); break;
  case 8:     value = Read8BE(pBuf); break;
  default:    LOG(FATAL) << width; break;
  }
  return value;
}

/*
 * Helper function: write a variable-width value into the output input buffer.
 */
static void jdwpWriteValue(ExpandBuf* pReply, int width, uint64_t value) {
  switch (width) {
  case 1:     expandBufAdd1(pReply, value); break;
  case 2:     expandBufAdd2BE(pReply, value); break;
  case 4:     expandBufAdd4BE(pReply, value); break;
  case 8:     expandBufAdd8BE(pReply, value); break;
  default:    LOG(FATAL) << width; break;
  }
}

/*
 * Common code for *_InvokeMethod requests.
 *
 * If "isConstructor" is set, this returns "objectId" rather than the
 * expected-to-be-void return value of the called function.
 */
static JdwpError finishInvoke(JdwpState* state,
    const uint8_t* buf, int dataLen, ExpandBuf* pReply,
    ObjectId threadId, ObjectId objectId, RefTypeId classId, MethodId methodId,
    bool isConstructor)
{
  CHECK(!isConstructor || objectId != 0);

  uint32_t numArgs = Read4BE(&buf);

  VLOG(jdwp) << StringPrintf("    --> threadId=%llx objectId=%llx", threadId, objectId);
  VLOG(jdwp) << StringPrintf("        classId=%llx methodId=%x %s.%s", classId, methodId, Dbg::GetClassDescriptor(classId).c_str(), Dbg::GetMethodName(classId, methodId).c_str());
  VLOG(jdwp) << StringPrintf("        %d args:", numArgs);

  uint64_t* argArray = NULL;
  if (numArgs > 0) {
    argArray = (ObjectId*) malloc(sizeof(ObjectId) * numArgs);
  }

  for (uint32_t i = 0; i < numArgs; i++) {
    JDWP::JdwpTag typeTag = ReadTag(&buf);
    size_t width = Dbg::GetTagWidth(typeTag);
    uint64_t value = jdwpReadValue(&buf, width);

    VLOG(jdwp) << StringPrintf("          '%c'(%d): 0x%llx", typeTag, width, value);
    argArray[i] = value;
  }

  uint32_t options = Read4BE(&buf);  /* enum InvokeOptions bit flags */
  VLOG(jdwp) << StringPrintf("        options=0x%04x%s%s", options, (options & INVOKE_SINGLE_THREADED) ? " (SINGLE_THREADED)" : "", (options & INVOKE_NONVIRTUAL) ? " (NONVIRTUAL)" : "");

  JDWP::JdwpTag resultTag;
  uint64_t resultValue;
  ObjectId exceptObjId;
  JdwpError err = Dbg::InvokeMethod(threadId, objectId, classId, methodId, numArgs, argArray, options, &resultTag, &resultValue, &exceptObjId);
  if (err != ERR_NONE) {
    goto bail;
  }

  if (err == ERR_NONE) {
    if (isConstructor) {
      expandBufAdd1(pReply, JT_OBJECT);
      expandBufAddObjectId(pReply, objectId);
    } else {
      size_t width = Dbg::GetTagWidth(resultTag);

      expandBufAdd1(pReply, resultTag);
      if (width != 0) {
        jdwpWriteValue(pReply, width, resultValue);
      }
    }
    expandBufAdd1(pReply, JT_OBJECT);
    expandBufAddObjectId(pReply, exceptObjId);

    VLOG(jdwp) << StringPrintf("  --> returned '%c' 0x%llx (except=%08llx)", resultTag, resultValue, exceptObjId);

    /* show detailed debug output */
    if (resultTag == JT_STRING && exceptObjId == 0) {
      if (resultValue != 0) {
        VLOG(jdwp) << "      string '" << Dbg::StringToUtf8(resultValue) << "'";
      } else {
        VLOG(jdwp) << "      string (null)";
      }
    }
  }

bail:
  free(argArray);
  return err;
}


/*
 * Request for version info.
 */
static JdwpError handleVM_Version(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  /* text information on runtime version */
  std::string version(StringPrintf("Android Runtime %s", Runtime::Current()->GetVersion()));
  expandBufAddUtf8String(pReply, version);
  /* JDWP version numbers */
  expandBufAdd4BE(pReply, 1);        // major
  expandBufAdd4BE(pReply, 5);        // minor
  /* VM JRE version */
  expandBufAddUtf8String(pReply, "1.6.0");  /* e.g. 1.6.0_22 */
  /* target VM name */
  expandBufAddUtf8String(pReply, "DalvikVM");

  return ERR_NONE;
}

/*
 * Given a class JNI signature (e.g. "Ljava/lang/Error;"), return the
 * referenceTypeID.  We need to send back more than one if the class has
 * been loaded by multiple class loaders.
 */
static JdwpError handleVM_ClassesBySignature(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  std::string classDescriptor(ReadNewUtf8String(&buf));
  VLOG(jdwp) << "  Req for class by signature '" << classDescriptor << "'";

  std::vector<RefTypeId> ids;
  Dbg::FindLoadedClassBySignature(classDescriptor, ids);

  expandBufAdd4BE(pReply, ids.size());

  for (size_t i = 0; i < ids.size(); ++i) {
    // Get class vs. interface and status flags.
    JDWP::JdwpTypeTag typeTag;
    uint32_t status;
    if (!Dbg::GetClassInfo(ids[i], &typeTag, &status, NULL)) {
      return ERR_INVALID_CLASS;
    }

    expandBufAdd1(pReply, typeTag);
    expandBufAddRefTypeId(pReply, ids[i]);
    expandBufAdd4BE(pReply, status);
  }

  return ERR_NONE;
}

/*
 * Handle request for the thread IDs of all running threads.
 *
 * We exclude ourselves from the list, because we don't allow ourselves
 * to be suspended, and that violates some JDWP expectations.
 */
static JdwpError handleVM_AllThreads(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId* pThreadIds;
  uint32_t threadCount;
  Dbg::GetAllThreads(&pThreadIds, &threadCount);

  expandBufAdd4BE(pReply, threadCount);

  ObjectId* walker = pThreadIds;
  for (uint32_t i = 0; i < threadCount; i++) {
    expandBufAddObjectId(pReply, *walker++);
  }

  free(pThreadIds);

  return ERR_NONE;
}

/*
 * List all thread groups that do not have a parent.
 */
static JdwpError handleVM_TopLevelThreadGroups(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  /*
   * TODO: maintain a list of parentless thread groups in the VM.
   *
   * For now, just return "system".  Application threads are created
   * in "main", which is a child of "system".
   */
  uint32_t groups = 1;
  expandBufAdd4BE(pReply, groups);
  //threadGroupId = debugGetMainThreadGroup();
  //expandBufAdd8BE(pReply, threadGroupId);
  ObjectId threadGroupId = Dbg::GetSystemThreadGroupId();
  expandBufAddObjectId(pReply, threadGroupId);

  return ERR_NONE;
}

/*
 * Respond with the sizes of the basic debugger types.
 *
 * All IDs are 8 bytes.
 */
static JdwpError handleVM_IDSizes(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  expandBufAdd4BE(pReply, sizeof(FieldId));
  expandBufAdd4BE(pReply, sizeof(MethodId));
  expandBufAdd4BE(pReply, sizeof(ObjectId));
  expandBufAdd4BE(pReply, sizeof(RefTypeId));
  expandBufAdd4BE(pReply, sizeof(FrameId));
  return ERR_NONE;
}

/*
 * The debugger is politely asking to disconnect.  We're good with that.
 *
 * We could resume threads and clean up pinned references, but we can do
 * that when the TCP connection drops.
 */
static JdwpError handleVM_Dispose(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  return ERR_NONE;
}

/*
 * Suspend the execution of the application running in the VM (i.e. suspend
 * all threads).
 *
 * This needs to increment the "suspend count" on all threads.
 */
static JdwpError handleVM_Suspend(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  Dbg::SuspendVM();
  return ERR_NONE;
}

/*
 * Resume execution.  Decrements the "suspend count" of all threads.
 */
static JdwpError handleVM_Resume(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  Dbg::ResumeVM();
  return ERR_NONE;
}

/*
 * The debugger wants the entire VM to exit.
 */
static JdwpError handleVM_Exit(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  uint32_t exitCode = Get4BE(buf);

  LOG(WARNING) << "Debugger is telling the VM to exit with code=" << exitCode;

  Dbg::Exit(exitCode);
  return ERR_NOT_IMPLEMENTED;     // shouldn't get here
}

/*
 * Create a new string in the VM and return its ID.
 *
 * (Ctrl-Shift-I in Eclipse on an array of objects causes it to create the
 * string "java.util.Arrays".)
 */
static JdwpError handleVM_CreateString(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  std::string str(ReadNewUtf8String(&buf));
  VLOG(jdwp) << "  Req to create string '" << str << "'";
  ObjectId stringId = Dbg::CreateString(str);
  if (stringId == 0) {
    return ERR_OUT_OF_MEMORY;
  }
  expandBufAddObjectId(pReply, stringId);
  return ERR_NONE;
}

/*
 * Tell the debugger what we are capable of.
 */
static JdwpError handleVM_Capabilities(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  expandBufAdd1(pReply, false);   /* canWatchFieldModification */
  expandBufAdd1(pReply, false);   /* canWatchFieldAccess */
  expandBufAdd1(pReply, false);   /* canGetBytecodes */
  expandBufAdd1(pReply, true);    /* canGetSyntheticAttribute */
  expandBufAdd1(pReply, false);   /* canGetOwnedMonitorInfo */
  expandBufAdd1(pReply, false);   /* canGetCurrentContendedMonitor */
  expandBufAdd1(pReply, false);   /* canGetMonitorInfo */
  return ERR_NONE;
}

/*
 * Return classpath and bootclasspath.
 */
static JdwpError handleVM_ClassPaths(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  char baseDir[2] = "/";

  /*
   * TODO: make this real.  Not important for remote debugging, but
   * might be useful for local debugging.
   */
  uint32_t classPaths = 1;
  uint32_t bootClassPaths = 0;

  expandBufAddUtf8String(pReply, baseDir);
  expandBufAdd4BE(pReply, classPaths);
  for (uint32_t i = 0; i < classPaths; i++) {
    expandBufAddUtf8String(pReply, ".");
  }

  expandBufAdd4BE(pReply, bootClassPaths);
  for (uint32_t i = 0; i < classPaths; i++) {
    /* add bootclasspath components as strings */
  }

  return ERR_NONE;
}

/*
 * Release a list of object IDs.  (Seen in jdb.)
 *
 * Currently does nothing.
 */
static JdwpError HandleVM_DisposeObjects(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  return ERR_NONE;
}

/*
 * Tell the debugger what we are capable of.
 */
static JdwpError handleVM_CapabilitiesNew(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  expandBufAdd1(pReply, false);   /* canWatchFieldModification */
  expandBufAdd1(pReply, false);   /* canWatchFieldAccess */
  expandBufAdd1(pReply, false);   /* canGetBytecodes */
  expandBufAdd1(pReply, true);    /* canGetSyntheticAttribute */
  expandBufAdd1(pReply, false);   /* canGetOwnedMonitorInfo */
  expandBufAdd1(pReply, false);   /* canGetCurrentContendedMonitor */
  expandBufAdd1(pReply, false);   /* canGetMonitorInfo */
  expandBufAdd1(pReply, false);   /* canRedefineClasses */
  expandBufAdd1(pReply, false);   /* canAddMethod */
  expandBufAdd1(pReply, false);   /* canUnrestrictedlyRedefineClasses */
  expandBufAdd1(pReply, false);   /* canPopFrames */
  expandBufAdd1(pReply, false);   /* canUseInstanceFilters */
  expandBufAdd1(pReply, false);   /* canGetSourceDebugExtension */
  expandBufAdd1(pReply, false);   /* canRequestVMDeathEvent */
  expandBufAdd1(pReply, false);   /* canSetDefaultStratum */
  expandBufAdd1(pReply, false);   /* 1.6: canGetInstanceInfo */
  expandBufAdd1(pReply, false);   /* 1.6: canRequestMonitorEvents */
  expandBufAdd1(pReply, false);   /* 1.6: canGetMonitorFrameInfo */
  expandBufAdd1(pReply, false);   /* 1.6: canUseSourceNameFilters */
  expandBufAdd1(pReply, false);   /* 1.6: canGetConstantPool */
  expandBufAdd1(pReply, false);   /* 1.6: canForceEarlyReturn */

  /* fill in reserved22 through reserved32; note count started at 1 */
  for (int i = 22; i <= 32; i++) {
    expandBufAdd1(pReply, false);   /* reservedN */
  }
  return ERR_NONE;
}

/*
 * Cough up the complete list of classes.
 */
static JdwpError handleVM_AllClassesWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  std::vector<JDWP::RefTypeId> classes;
  Dbg::GetClassList(classes);

  expandBufAdd4BE(pReply, classes.size());

  for (size_t i = 0; i < classes.size(); ++i) {
    static const char genericSignature[1] = "";
    JDWP::JdwpTypeTag refTypeTag;
    std::string descriptor;
    uint32_t status;
    if (!Dbg::GetClassInfo(classes[i], &refTypeTag, &status, &descriptor)) {
      return ERR_INVALID_CLASS;
    }

    expandBufAdd1(pReply, refTypeTag);
    expandBufAddRefTypeId(pReply, classes[i]);
    expandBufAddUtf8String(pReply, descriptor);
    expandBufAddUtf8String(pReply, genericSignature);
    expandBufAdd4BE(pReply, status);
  }

  return ERR_NONE;
}

/*
 * Given a referenceTypeID, return a string with the JNI reference type
 * signature (e.g. "Ljava/lang/Error;").
 */
static JdwpError handleRT_Signature(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);

  VLOG(jdwp) << StringPrintf("  Req for signature of refTypeId=0x%llx", refTypeId);
  std::string signature;
  if (!Dbg::GetSignature(refTypeId, signature)) {
    return ERR_INVALID_CLASS;
  }
  expandBufAddUtf8String(pReply, signature);
  return ERR_NONE;
}

/*
 * Return the modifiers (a/k/a access flags) for a reference type.
 */
static JdwpError handleRT_Modifiers(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);
  uint32_t access_flags;
  if (!Dbg::GetAccessFlags(refTypeId, access_flags)) {
    return ERR_INVALID_CLASS;
  }
  expandBufAdd4BE(pReply, access_flags);
  return ERR_NONE;
}

/*
 * Get values from static fields in a reference type.
 */
static JdwpError handleRT_GetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ReadRefTypeId(&buf); // We don't need this, but we need to skip over it in the request.
  uint32_t numFields = Read4BE(&buf);

  VLOG(jdwp) << "  RT_GetValues " << numFields << ":";

  expandBufAdd4BE(pReply, numFields);
  for (uint32_t i = 0; i < numFields; i++) {
    FieldId fieldId = ReadFieldId(&buf);
    Dbg::GetStaticFieldValue(fieldId, pReply);
  }

  return ERR_NONE;
}

/*
 * Get the name of the source file in which a reference type was declared.
 */
static JdwpError handleRT_SourceFile(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);
  std::string source_file;
  if (!Dbg::GetSourceFile(refTypeId, source_file)) {
    return ERR_ABSENT_INFORMATION;
  }
  expandBufAddUtf8String(pReply, source_file);
  return ERR_NONE;
}

/*
 * Return the current status of the reference type.
 */
static JdwpError handleRT_Status(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);
  JDWP::JdwpTypeTag typeTag;
  uint32_t status;
  if (!Dbg::GetClassInfo(refTypeId, &typeTag, &status, NULL)) {
    return ERR_INVALID_CLASS;
  }
  expandBufAdd4BE(pReply, status);
  return ERR_NONE;
}

/*
 * Return interfaces implemented directly by this class.
 */
static JdwpError handleRT_Interfaces(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);
  VLOG(jdwp) << StringPrintf("  Req for interfaces in %llx (%s)", refTypeId, Dbg::GetClassDescriptor(refTypeId).c_str());
  return Dbg::OutputDeclaredInterfaces(refTypeId, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
}

/*
 * Return the class object corresponding to this type.
 */
static JdwpError handleRT_ClassObject(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);
  ObjectId classObjectId;
  if (!Dbg::GetClassObject(refTypeId, classObjectId)) {
    return ERR_INVALID_CLASS;
  }
  VLOG(jdwp) << StringPrintf("  RefTypeId %llx -> ObjectId %llx", refTypeId, classObjectId);
  expandBufAddObjectId(pReply, classObjectId);
  return ERR_NONE;
}

/*
 * Returns the value of the SourceDebugExtension attribute.
 *
 * JDB seems interested, but DEX files don't currently support this.
 */
static JdwpError handleRT_SourceDebugExtension(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  /* referenceTypeId in, string out */
  return ERR_ABSENT_INFORMATION;
}

/*
 * Like RT_Signature but with the possibility of a "generic signature".
 */
static JdwpError handleRT_SignatureWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  static const char genericSignature[1] = "";

  RefTypeId refTypeId = ReadRefTypeId(&buf);

  VLOG(jdwp) << StringPrintf("  Req for signature of refTypeId=0x%llx", refTypeId);
  std::string signature;
  if (Dbg::GetSignature(refTypeId, signature)) {
    expandBufAddUtf8String(pReply, signature);
  } else {
    LOG(WARNING) << StringPrintf("No signature for refTypeId=0x%llx", refTypeId);
    expandBufAddUtf8String(pReply, "Lunknown;");
  }
  expandBufAddUtf8String(pReply, genericSignature);

  return ERR_NONE;
}

/*
 * Return the instance of java.lang.ClassLoader that loaded the specified
 * reference type, or null if it was loaded by the system loader.
 */
static JdwpError handleRT_ClassLoader(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);

  expandBufAddObjectId(pReply, Dbg::GetClassLoader(refTypeId));

  return ERR_NONE;
}

static std::string Describe(const RefTypeId& refTypeId) {
  std::string signature("unknown");
  Dbg::GetSignature(refTypeId, signature);
  return StringPrintf("refTypeId=0x%llx (%s)", refTypeId, signature.c_str());
}

/*
 * Given a referenceTypeId, return a block of stuff that describes the
 * fields declared by a class.
 */
static JdwpError handleRT_FieldsWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);
  VLOG(jdwp) << "  Req for fields in " << Describe(refTypeId);
  return Dbg::OutputDeclaredFields(refTypeId, true, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
}

// Obsolete equivalent of FieldsWithGeneric, without the generic type information.
static JdwpError handleRT_Fields(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);
  VLOG(jdwp) << "  Req for fields in " << Describe(refTypeId);
  return Dbg::OutputDeclaredFields(refTypeId, false, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
}

/*
 * Given a referenceTypeID, return a block of goodies describing the
 * methods declared by a class.
 */
static JdwpError handleRT_MethodsWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);
  VLOG(jdwp) << "  Req for methods in " << Describe(refTypeId);
  return Dbg::OutputDeclaredMethods(refTypeId, true, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
}

// Obsolete equivalent of MethodsWithGeneric, without the generic type information.
static JdwpError handleRT_Methods(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);
  VLOG(jdwp) << "  Req for methods in " << Describe(refTypeId);
  return Dbg::OutputDeclaredMethods(refTypeId, false, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
}

/*
 * Return the immediate superclass of a class.
 */
static JdwpError handleCT_Superclass(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId classId = ReadRefTypeId(&buf);
  RefTypeId superClassId;
  if (!Dbg::GetSuperclass(classId, superClassId)) {
    return ERR_INVALID_CLASS;
  }
  expandBufAddRefTypeId(pReply, superClassId);
  return ERR_NONE;
}

/*
 * Set static class values.
 */
static JdwpError handleCT_SetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId classId = ReadRefTypeId(&buf);
  uint32_t values = Read4BE(&buf);

  VLOG(jdwp) << StringPrintf("  Req to set %d values in classId=%llx", values, classId);

  for (uint32_t i = 0; i < values; i++) {
    FieldId fieldId = ReadFieldId(&buf);
    JDWP::JdwpTag fieldTag = Dbg::GetStaticFieldBasicTag(fieldId);
    size_t width = Dbg::GetTagWidth(fieldTag);
    uint64_t value = jdwpReadValue(&buf, width);

    VLOG(jdwp) << StringPrintf("    --> field=%x tag=%c -> %lld", fieldId, fieldTag, value);
    Dbg::SetStaticFieldValue(fieldId, value, width);
  }

  return ERR_NONE;
}

/*
 * Invoke a static method.
 *
 * Example: Eclipse sometimes uses java/lang/Class.forName(String s) on
 * values in the "variables" display.
 */
static JdwpError handleCT_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId classId = ReadRefTypeId(&buf);
  ObjectId threadId = ReadObjectId(&buf);
  MethodId methodId = ReadMethodId(&buf);

  return finishInvoke(state, buf, dataLen, pReply, threadId, 0, classId, methodId, false);
}

/*
 * Create a new object of the requested type, and invoke the specified
 * constructor.
 *
 * Example: in IntelliJ, create a watch on "new String(myByteArray)" to
 * see the contents of a byte[] as a string.
 */
static JdwpError handleCT_NewInstance(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId classId = ReadRefTypeId(&buf);
  ObjectId threadId = ReadObjectId(&buf);
  MethodId methodId = ReadMethodId(&buf);

  VLOG(jdwp) << "Creating instance of " << Dbg::GetClassDescriptor(classId);
  ObjectId objectId;
  if (!Dbg::CreateObject(classId, objectId)) {
    return ERR_INVALID_CLASS;
  }
  if (objectId == 0) {
    return ERR_OUT_OF_MEMORY;
  }
  return finishInvoke(state, buf, dataLen, pReply, threadId, objectId, classId, methodId, true);
}

/*
 * Create a new array object of the requested type and length.
 */
static JdwpError handleAT_newInstance(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId arrayTypeId = ReadRefTypeId(&buf);
  uint32_t length = Read4BE(&buf);

  VLOG(jdwp) << StringPrintf("Creating array %s[%u]", Dbg::GetClassDescriptor(arrayTypeId).c_str(), length);
  ObjectId objectId;
  if (!Dbg::CreateArrayObject(arrayTypeId, length, objectId)) {
    return ERR_INVALID_CLASS;
  }
  if (objectId == 0) {
    return ERR_OUT_OF_MEMORY;
  }
  expandBufAdd1(pReply, JT_ARRAY);
  expandBufAddObjectId(pReply, objectId);
  return ERR_NONE;
}

/*
 * Return line number information for the method, if present.
 */
static JdwpError handleM_LineTable(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId refTypeId = ReadRefTypeId(&buf);
  MethodId methodId = ReadMethodId(&buf);

  VLOG(jdwp) << StringPrintf("  Req for line table in %s.%s", Dbg::GetClassDescriptor(refTypeId).c_str(), Dbg::GetMethodName(refTypeId,methodId).c_str());

  Dbg::OutputLineTable(refTypeId, methodId, pReply);

  return ERR_NONE;
}

/*
 * Pull out the LocalVariableTable goodies.
 */
static JdwpError handleM_VariableTableWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId classId = ReadRefTypeId(&buf);
  MethodId methodId = ReadMethodId(&buf);

  VLOG(jdwp) << StringPrintf("  Req for LocalVarTab in class=%s method=%s", Dbg::GetClassDescriptor(classId).c_str(), Dbg::GetMethodName(classId, methodId).c_str());

  /*
   * We could return ERR_ABSENT_INFORMATION here if the DEX file was
   * built without local variable information.  That will cause Eclipse
   * to make a best-effort attempt at displaying local variables
   * anonymously.  However, the attempt isn't very good, so we're probably
   * better off just not showing anything.
   */
  Dbg::OutputVariableTable(classId, methodId, true, pReply);
  return ERR_NONE;
}

/*
 * Given an object reference, return the runtime type of the object
 * (class or array).
 *
 * This can get called on different things, e.g. threadId gets
 * passed in here.
 */
static JdwpError handleOR_ReferenceType(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId objectId = ReadObjectId(&buf);
  VLOG(jdwp) << StringPrintf("  Req for type of objectId=0x%llx", objectId);

  JDWP::JdwpTypeTag refTypeTag;
  RefTypeId typeId;
  Dbg::GetObjectType(objectId, &refTypeTag, &typeId);

  expandBufAdd1(pReply, refTypeTag);
  expandBufAddRefTypeId(pReply, typeId);

  return ERR_NONE;
}

/*
 * Get values from the fields of an object.
 */
static JdwpError handleOR_GetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId objectId = ReadObjectId(&buf);
  uint32_t numFields = Read4BE(&buf);

  VLOG(jdwp) << StringPrintf("  Req for %d fields from objectId=0x%llx", numFields, objectId);

  expandBufAdd4BE(pReply, numFields);

  for (uint32_t i = 0; i < numFields; i++) {
    FieldId fieldId = ReadFieldId(&buf);
    Dbg::GetFieldValue(objectId, fieldId, pReply);
  }

  return ERR_NONE;
}

/*
 * Set values in the fields of an object.
 */
static JdwpError handleOR_SetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId objectId = ReadObjectId(&buf);
  uint32_t numFields = Read4BE(&buf);

  VLOG(jdwp) << StringPrintf("  Req to set %d fields in objectId=0x%llx", numFields, objectId);

  for (uint32_t i = 0; i < numFields; i++) {
    FieldId fieldId = ReadFieldId(&buf);

    JDWP::JdwpTag fieldTag = Dbg::GetFieldBasicTag(fieldId);
    size_t width = Dbg::GetTagWidth(fieldTag);
    uint64_t value = jdwpReadValue(&buf, width);

    VLOG(jdwp) << StringPrintf("    --> fieldId=%x tag='%c'(%d) value=%lld", fieldId, fieldTag, width, value);

    Dbg::SetFieldValue(objectId, fieldId, value, width);
  }

  return ERR_NONE;
}

/*
 * Invoke an instance method.  The invocation must occur in the specified
 * thread, which must have been suspended by an event.
 *
 * The call is synchronous.  All threads in the VM are resumed, unless the
 * SINGLE_THREADED flag is set.
 *
 * If you ask Eclipse to "inspect" an object (or ask JDB to "print" an
 * object), it will try to invoke the object's toString() function.  This
 * feature becomes crucial when examining ArrayLists with Eclipse.
 */
static JdwpError handleOR_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId objectId = ReadObjectId(&buf);
  ObjectId threadId = ReadObjectId(&buf);
  RefTypeId classId = ReadRefTypeId(&buf);
  MethodId methodId = ReadMethodId(&buf);

  return finishInvoke(state, buf, dataLen, pReply, threadId, objectId, classId, methodId, false);
}

/*
 * Disable garbage collection of the specified object.
 */
static JdwpError handleOR_DisableCollection(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  // this is currently a no-op
  return ERR_NONE;
}

/*
 * Enable garbage collection of the specified object.
 */
static JdwpError handleOR_EnableCollection(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  // this is currently a no-op
  return ERR_NONE;
}

/*
 * Determine whether an object has been garbage collected.
 */
static JdwpError handleOR_IsCollected(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId objectId;

  objectId = ReadObjectId(&buf);
  VLOG(jdwp) << StringPrintf("  Req IsCollected(0x%llx)", objectId);

  // TODO: currently returning false; must integrate with GC
  expandBufAdd1(pReply, 0);

  return ERR_NONE;
}

/*
 * Return the string value in a string object.
 */
static JdwpError handleSR_Value(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId stringObject = ReadObjectId(&buf);
  std::string str(Dbg::StringToUtf8(stringObject));

  VLOG(jdwp) << StringPrintf("  Req for str %llx --> '%s'", stringObject, PrintableString(str).c_str());

  expandBufAddUtf8String(pReply, str);

  return ERR_NONE;
}

/*
 * Return a thread's name.
 */
static JdwpError handleTR_Name(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadId = ReadObjectId(&buf);

  VLOG(jdwp) << StringPrintf("  Req for name of thread 0x%llx", threadId);
  std::string name;
  if (!Dbg::GetThreadName(threadId, name)) {
    return ERR_INVALID_THREAD;
  }
  VLOG(jdwp) << StringPrintf("  Name of thread 0x%llx is \"%s\"", threadId, name.c_str());
  expandBufAddUtf8String(pReply, name);

  return ERR_NONE;
}

/*
 * Suspend the specified thread.
 *
 * It's supposed to remain suspended even if interpreted code wants to
 * resume it; only the JDI is allowed to resume it.
 */
static JdwpError handleTR_Suspend(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadId = ReadObjectId(&buf);

  if (threadId == Dbg::GetThreadSelfId()) {
    LOG(INFO) << "  Warning: ignoring request to suspend self";
    return ERR_THREAD_NOT_SUSPENDED;
  }
  VLOG(jdwp) << StringPrintf("  Req to suspend thread 0x%llx", threadId);
  Dbg::SuspendThread(threadId);
  return ERR_NONE;
}

/*
 * Resume the specified thread.
 */
static JdwpError handleTR_Resume(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadId = ReadObjectId(&buf);

  if (threadId == Dbg::GetThreadSelfId()) {
    LOG(INFO) << "  Warning: ignoring request to resume self";
    return ERR_NONE;
  }
  VLOG(jdwp) << StringPrintf("  Req to resume thread 0x%llx", threadId);
  Dbg::ResumeThread(threadId);
  return ERR_NONE;
}

/*
 * Return status of specified thread.
 */
static JdwpError handleTR_Status(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadId = ReadObjectId(&buf);

  VLOG(jdwp) << StringPrintf("  Req for status of thread 0x%llx", threadId);

  JDWP::JdwpThreadStatus threadStatus;
  JDWP::JdwpSuspendStatus suspendStatus;
  if (!Dbg::GetThreadStatus(threadId, &threadStatus, &suspendStatus)) {
    return ERR_INVALID_THREAD;
  }

  VLOG(jdwp) << "    --> " << threadStatus << ", " << suspendStatus;

  expandBufAdd4BE(pReply, threadStatus);
  expandBufAdd4BE(pReply, suspendStatus);

  return ERR_NONE;
}

/*
 * Return the thread group that the specified thread is a member of.
 */
static JdwpError handleTR_ThreadGroup(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadId = ReadObjectId(&buf);

  /* currently not handling these */
  ObjectId threadGroupId = Dbg::GetThreadGroup(threadId);
  expandBufAddObjectId(pReply, threadGroupId);

  return ERR_NONE;
}

/*
 * Return the current call stack of a suspended thread.
 *
 * If the thread isn't suspended, the error code isn't defined, but should
 * be THREAD_NOT_SUSPENDED.
 */
static JdwpError handleTR_Frames(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadId = ReadObjectId(&buf);
  uint32_t startFrame = Read4BE(&buf);
  uint32_t length = Read4BE(&buf);

  if (!Dbg::ThreadExists(threadId)) {
    return ERR_INVALID_THREAD;
  }
  if (!Dbg::IsSuspended(threadId)) {
    LOG(WARNING) << StringPrintf("  Rejecting req for frames in running thread %llx", threadId);
    return ERR_THREAD_NOT_SUSPENDED;
  }

  size_t frameCount = Dbg::GetThreadFrameCount(threadId);

  VLOG(jdwp) << StringPrintf("  Request for frames: threadId=%llx start=%d length=%d [count=%d]", threadId, startFrame, length, frameCount);
  if (frameCount <= 0) {
    return ERR_THREAD_NOT_SUSPENDED;    /* == 0 means 100% native */
  }
  if (length == (uint32_t) -1) {
    length = frameCount;
  }
  CHECK_GE(startFrame, 0U);
  CHECK_LT(startFrame, frameCount);
  CHECK_LE(startFrame + length, frameCount);

  uint32_t frames = length;
  expandBufAdd4BE(pReply, frames);
  for (uint32_t i = startFrame; i < (startFrame+length); i++) {
    FrameId frameId;
    JdwpLocation loc;

    Dbg::GetThreadFrame(threadId, i, &frameId, &loc);

    expandBufAdd8BE(pReply, frameId);
    AddLocation(pReply, &loc);

    VLOG(jdwp) << StringPrintf("    Frame %d: id=%llx loc={type=%d cls=%llx mth=%x loc=%llx}", i, frameId, loc.typeTag, loc.classId, loc.methodId, loc.idx);
  }

  return ERR_NONE;
}

/*
 * Returns the #of frames on the specified thread, which must be suspended.
 */
static JdwpError handleTR_FrameCount(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadId = ReadObjectId(&buf);

  if (!Dbg::ThreadExists(threadId)) {
    return ERR_INVALID_THREAD;
  }
  if (!Dbg::IsSuspended(threadId)) {
    LOG(WARNING) << StringPrintf("  Rejecting req for frames in running thread %llx", threadId);
    return ERR_THREAD_NOT_SUSPENDED;
  }

  int frameCount = Dbg::GetThreadFrameCount(threadId);
  if (frameCount < 0) {
    return ERR_INVALID_THREAD;
  }
  expandBufAdd4BE(pReply, (uint32_t)frameCount);

  return ERR_NONE;
}

/*
 * Get the monitor that the thread is waiting on.
 */
static JdwpError handleTR_CurrentContendedMonitor(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadId;

  threadId = ReadObjectId(&buf);

  // TODO: create an Object to represent the monitor (we're currently
  // just using a raw Monitor struct in the VM)

  return ERR_NOT_IMPLEMENTED;
}

/*
 * Return the suspend count for the specified thread.
 *
 * (The thread *might* still be running -- it might not have examined
 * its suspend count recently.)
 */
static JdwpError handleTR_SuspendCount(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadId = ReadObjectId(&buf);

  uint32_t suspendCount = Dbg::GetThreadSuspendCount(threadId);
  expandBufAdd4BE(pReply, suspendCount);

  return ERR_NONE;
}

/*
 * Return the name of a thread group.
 *
 * The Eclipse debugger recognizes "main" and "system" as special.
 */
static JdwpError handleTGR_Name(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadGroupId = ReadObjectId(&buf);
  VLOG(jdwp) << StringPrintf("  Req for name of threadGroupId=0x%llx", threadGroupId);

  expandBufAddUtf8String(pReply, Dbg::GetThreadGroupName(threadGroupId));

  return ERR_NONE;
}

/*
 * Returns the thread group -- if any -- that contains the specified
 * thread group.
 */
static JdwpError handleTGR_Parent(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId groupId = ReadObjectId(&buf);

  ObjectId parentGroup = Dbg::GetThreadGroupParent(groupId);
  expandBufAddObjectId(pReply, parentGroup);

  return ERR_NONE;
}

/*
 * Return the active threads and thread groups that are part of the
 * specified thread group.
 */
static JdwpError handleTGR_Children(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadGroupId = ReadObjectId(&buf);
  VLOG(jdwp) << StringPrintf("  Req for threads in threadGroupId=0x%llx", threadGroupId);

  ObjectId* pThreadIds;
  uint32_t threadCount;
  Dbg::GetThreadGroupThreads(threadGroupId, &pThreadIds, &threadCount);

  expandBufAdd4BE(pReply, threadCount);

  for (uint32_t i = 0; i < threadCount; i++) {
    expandBufAddObjectId(pReply, pThreadIds[i]);
  }
  free(pThreadIds);

  /*
   * TODO: finish support for child groups
   *
   * For now, just show that "main" is a child of "system".
   */
  if (threadGroupId == Dbg::GetSystemThreadGroupId()) {
    expandBufAdd4BE(pReply, 1);
    expandBufAddObjectId(pReply, Dbg::GetMainThreadGroupId());
  } else {
    expandBufAdd4BE(pReply, 0);
  }

  return ERR_NONE;
}

/*
 * Return the #of components in the array.
 */
static JdwpError handleAR_Length(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId arrayId = ReadObjectId(&buf);
  VLOG(jdwp) << StringPrintf("  Req for length of array 0x%llx", arrayId);

  uint32_t arrayLength = Dbg::GetArrayLength(arrayId);

  VLOG(jdwp) << StringPrintf("    --> %d", arrayLength);

  expandBufAdd4BE(pReply, arrayLength);

  return ERR_NONE;
}

/*
 * Return the values from an array.
 */
static JdwpError handleAR_GetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId arrayId = ReadObjectId(&buf);
  uint32_t firstIndex = Read4BE(&buf);
  uint32_t length = Read4BE(&buf);

  uint8_t tag = Dbg::GetArrayElementTag(arrayId);
  VLOG(jdwp) << StringPrintf("  Req for array values 0x%llx first=%d len=%d (elem tag=%c)", arrayId, firstIndex, length, tag);

  expandBufAdd1(pReply, tag);
  expandBufAdd4BE(pReply, length);

  if (!Dbg::OutputArray(arrayId, firstIndex, length, pReply)) {
    return ERR_INVALID_LENGTH;
  }

  return ERR_NONE;
}

/*
 * Set values in an array.
 */
static JdwpError handleAR_SetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId arrayId = ReadObjectId(&buf);
  uint32_t firstIndex = Read4BE(&buf);
  uint32_t values = Read4BE(&buf);

  VLOG(jdwp) << StringPrintf("  Req to set array values 0x%llx first=%d count=%d", arrayId, firstIndex, values);

  if (!Dbg::SetArrayElements(arrayId, firstIndex, values, buf)) {
    return ERR_INVALID_LENGTH;
  }

  return ERR_NONE;
}

/*
 * Return the set of classes visible to a class loader.  All classes which
 * have the class loader as a defining or initiating loader are returned.
 */
static JdwpError handleCLR_VisibleClasses(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId classLoaderObject;
  uint32_t numClasses = 0;
  RefTypeId* classRefBuf = NULL;
  int i;

  classLoaderObject = ReadObjectId(&buf);

  Dbg::GetVisibleClassList(classLoaderObject, &numClasses, &classRefBuf);

  expandBufAdd4BE(pReply, numClasses);
  for (i = 0; i < (int) numClasses; i++) {
    uint8_t refTypeTag = Dbg::GetClassObjectType(classRefBuf[i]);

    expandBufAdd1(pReply, refTypeTag);
    expandBufAddRefTypeId(pReply, classRefBuf[i]);
  }

  return ERR_NONE;
}

/*
 * Return a newly-allocated string in which all occurrences of '.' have
 * been changed to '/'.  If we find a '/' in the original string, NULL
 * is returned to avoid ambiguity.
 */
char* dvmDotToSlash(const char* str) {
  char* newStr = strdup(str);
  char* cp = newStr;

  if (newStr == NULL) {
    return NULL;
  }

  while (*cp != '\0') {
    if (*cp == '/') {
      CHECK(false);
      return NULL;
    }
    if (*cp == '.') {
      *cp = '/';
    }
    cp++;
  }

  return newStr;
}

/*
 * Set an event trigger.
 *
 * Reply with a requestID.
 */
static JdwpError handleER_Set(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  const uint8_t* origBuf = buf;

  uint8_t eventKind = Read1(&buf);
  uint8_t suspendPolicy = Read1(&buf);
  uint32_t modifierCount = Read4BE(&buf);

  VLOG(jdwp) << "  Set(kind=" << JdwpEventKind(eventKind)
               << " suspend=" << JdwpSuspendPolicy(suspendPolicy)
               << " mods=" << modifierCount << ")";

  CHECK_LT(modifierCount, 256U);    /* reasonableness check */

  JdwpEvent* pEvent = EventAlloc(modifierCount);
  pEvent->eventKind = static_cast<JdwpEventKind>(eventKind);
  pEvent->suspendPolicy = static_cast<JdwpSuspendPolicy>(suspendPolicy);
  pEvent->modCount = modifierCount;

  /*
   * Read modifiers.  Ordering may be significant (see explanation of Count
   * mods in JDWP doc).
   */
  for (uint32_t idx = 0; idx < modifierCount; idx++) {
    JdwpModKind modKind = static_cast<JdwpModKind>(Read1(&buf));

    pEvent->mods[idx].modKind = modKind;

    switch (modKind) {
    case MK_COUNT:          /* report once, when "--count" reaches 0 */
      {
        uint32_t count = Read4BE(&buf);
        VLOG(jdwp) << "    Count: " << count;
        if (count == 0) {
          return ERR_INVALID_COUNT;
        }
        pEvent->mods[idx].count.count = count;
      }
      break;
    case MK_CONDITIONAL:    /* conditional on expression) */
      {
        uint32_t exprId = Read4BE(&buf);
        VLOG(jdwp) << "    Conditional: " << exprId;
        pEvent->mods[idx].conditional.exprId = exprId;
      }
      break;
    case MK_THREAD_ONLY:    /* only report events in specified thread */
      {
        ObjectId threadId = ReadObjectId(&buf);
        VLOG(jdwp) << StringPrintf("    ThreadOnly: %llx", threadId);
        pEvent->mods[idx].threadOnly.threadId = threadId;
      }
      break;
    case MK_CLASS_ONLY:     /* for ClassPrepare, MethodEntry */
      {
        RefTypeId clazzId = ReadRefTypeId(&buf);
        VLOG(jdwp) << StringPrintf("    ClassOnly: %llx (%s)", clazzId, Dbg::GetClassDescriptor(clazzId).c_str());
        pEvent->mods[idx].classOnly.refTypeId = clazzId;
      }
      break;
    case MK_CLASS_MATCH:    /* restrict events to matching classes */
      {
        std::string pattern(ReadNewUtf8String(&buf));
        VLOG(jdwp) << StringPrintf("    ClassMatch: '%s'", pattern.c_str());
        /* pattern is "java.foo.*", we want "java/foo/ *" */
        pEvent->mods[idx].classMatch.classPattern = dvmDotToSlash(pattern.c_str());
      }
      break;
    case MK_CLASS_EXCLUDE:  /* restrict events to non-matching classes */
      {
        std::string pattern(ReadNewUtf8String(&buf));
        VLOG(jdwp) << StringPrintf("    ClassExclude: '%s'", pattern.c_str());
        pEvent->mods[idx].classExclude.classPattern = dvmDotToSlash(pattern.c_str());
      }
      break;
    case MK_LOCATION_ONLY:  /* restrict certain events based on loc */
      {
        JdwpLocation loc;

        jdwpReadLocation(&buf, &loc);
        VLOG(jdwp) << StringPrintf("    LocationOnly: typeTag=%d classId=%llx methodId=%x idx=%llx",
        loc.typeTag, loc.classId, loc.methodId, loc.idx);
        pEvent->mods[idx].locationOnly.loc = loc;
      }
      break;
    case MK_EXCEPTION_ONLY: /* modifies EK_EXCEPTION events */
      {
        RefTypeId exceptionOrNull;      /* null == all exceptions */
        uint8_t caught, uncaught;

        exceptionOrNull = ReadRefTypeId(&buf);
        caught = Read1(&buf);
        uncaught = Read1(&buf);
        VLOG(jdwp) << StringPrintf("    ExceptionOnly: type=%llx(%s) caught=%d uncaught=%d",
            exceptionOrNull, (exceptionOrNull == 0) ? "null" : Dbg::GetClassDescriptor(exceptionOrNull).c_str(), caught, uncaught);

        pEvent->mods[idx].exceptionOnly.refTypeId = exceptionOrNull;
        pEvent->mods[idx].exceptionOnly.caught = caught;
        pEvent->mods[idx].exceptionOnly.uncaught = uncaught;
      }
      break;
    case MK_FIELD_ONLY:     /* for field access/mod events */
      {
        RefTypeId declaring = ReadRefTypeId(&buf);
        FieldId fieldId = ReadFieldId(&buf);
        VLOG(jdwp) << StringPrintf("    FieldOnly: %llx %x", declaring, fieldId);
        pEvent->mods[idx].fieldOnly.refTypeId = declaring;
        pEvent->mods[idx].fieldOnly.fieldId = fieldId;
      }
      break;
    case MK_STEP:           /* for use with EK_SINGLE_STEP */
      {
        ObjectId threadId;
        uint32_t size, depth;

        threadId = ReadObjectId(&buf);
        size = Read4BE(&buf);
        depth = Read4BE(&buf);
        VLOG(jdwp) << StringPrintf("    Step: thread=%llx", threadId)
                     << " size=" << JdwpStepSize(size) << " depth=" << JdwpStepDepth(depth);

        pEvent->mods[idx].step.threadId = threadId;
        pEvent->mods[idx].step.size = size;
        pEvent->mods[idx].step.depth = depth;
      }
      break;
    case MK_INSTANCE_ONLY:  /* report events related to a specific obj */
      {
        ObjectId instance = ReadObjectId(&buf);
        VLOG(jdwp) << StringPrintf("    InstanceOnly: %llx", instance);
        pEvent->mods[idx].instanceOnly.objectId = instance;
      }
      break;
    default:
      LOG(WARNING) << "GLITCH: unsupported modKind=" << modKind;
      break;
    }
  }

  /*
   * Make sure we consumed all data.  It is possible that the remote side
   * has sent us bad stuff, but for now we blame ourselves.
   */
  if (buf != origBuf + dataLen) {
    LOG(WARNING) << "GLITCH: dataLen is " << dataLen << ", we have consumed " << (buf - origBuf);
  }

  /*
   * We reply with an integer "requestID".
   */
  uint32_t requestId = state->NextEventSerial();
  expandBufAdd4BE(pReply, requestId);

  pEvent->requestId = requestId;

  VLOG(jdwp) << StringPrintf("    --> event requestId=%#x", requestId);

  /* add it to the list */
  JdwpError err = state->RegisterEvent(pEvent);
  if (err != ERR_NONE) {
    /* registration failed, probably because event is bogus */
    EventFree(pEvent);
    LOG(WARNING) << "WARNING: event request rejected";
  }
  return err;
}

/*
 * Clear an event.  Failure to find an event with a matching ID is a no-op
 * and does not return an error.
 */
static JdwpError handleER_Clear(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  uint8_t eventKind;
  eventKind = Read1(&buf);
  uint32_t requestId = Read4BE(&buf);

  VLOG(jdwp) << StringPrintf("  Req to clear eventKind=%d requestId=%#x", eventKind, requestId);

  state->UnregisterEventById(requestId);

  return ERR_NONE;
}

/*
 * Return the values of arguments and local variables.
 */
static JdwpError handleSF_GetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadId = ReadObjectId(&buf);
  FrameId frameId = ReadFrameId(&buf);
  uint32_t slots = Read4BE(&buf);

  VLOG(jdwp) << StringPrintf("  Req for %d slots in threadId=%llx frameId=%llx", slots, threadId, frameId);

  expandBufAdd4BE(pReply, slots);     /* "int values" */
  for (uint32_t i = 0; i < slots; i++) {
    uint32_t slot = Read4BE(&buf);
    JDWP::JdwpTag reqSigByte = ReadTag(&buf);

    VLOG(jdwp) << StringPrintf("    --> slot %d '%c'", slot, reqSigByte);

    size_t width = Dbg::GetTagWidth(reqSigByte);
    uint8_t* ptr = expandBufAddSpace(pReply, width+1);
    Dbg::GetLocalValue(threadId, frameId, slot, reqSigByte, ptr, width);
  }

  return ERR_NONE;
}

/*
 * Set the values of arguments and local variables.
 */
static JdwpError handleSF_SetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ObjectId threadId = ReadObjectId(&buf);
  FrameId frameId = ReadFrameId(&buf);
  uint32_t slots = Read4BE(&buf);

  VLOG(jdwp) << StringPrintf("  Req to set %d slots in threadId=%llx frameId=%llx", slots, threadId, frameId);

  for (uint32_t i = 0; i < slots; i++) {
    uint32_t slot = Read4BE(&buf);
    JDWP::JdwpTag sigByte = ReadTag(&buf);
    size_t width = Dbg::GetTagWidth(sigByte);
    uint64_t value = jdwpReadValue(&buf, width);

    VLOG(jdwp) << StringPrintf("    --> slot %d '%c' %llx", slot, sigByte, value);
    Dbg::SetLocalValue(threadId, frameId, slot, sigByte, value, width);
  }

  return ERR_NONE;
}

/*
 * Returns the value of "this" for the specified frame.
 */
static JdwpError handleSF_ThisObject(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  ReadObjectId(&buf); // Skip thread id.
  FrameId frameId = ReadFrameId(&buf);

  ObjectId objectId;
  if (!Dbg::GetThisObject(frameId, &objectId)) {
    return ERR_INVALID_FRAMEID;
  }

  uint8_t objectTag = Dbg::GetObjectTag(objectId);
  VLOG(jdwp) << StringPrintf("  Req for 'this' in frame=%llx --> %llx '%c'", frameId, objectId, (char)objectTag);

  expandBufAdd1(pReply, objectTag);
  expandBufAddObjectId(pReply, objectId);

  return ERR_NONE;
}

/*
 * Return the reference type reflected by this class object.
 *
 * This appears to be required because ReferenceTypeId values are NEVER
 * reused, whereas ClassIds can be recycled like any other object.  (Either
 * that, or I have no idea what this is for.)
 */
static JdwpError handleCOR_ReflectedType(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  RefTypeId classObjectId = ReadRefTypeId(&buf);

  VLOG(jdwp) << StringPrintf("  Req for refTypeId for class=%llx (%s)", classObjectId, Dbg::GetClassDescriptor(classObjectId).c_str());

  bool is_interface;
  if (!Dbg::IsInterface(classObjectId, is_interface)) {
    return ERR_INVALID_CLASS;
  }

  expandBufAdd1(pReply, is_interface ? TT_INTERFACE : TT_CLASS);
  expandBufAddRefTypeId(pReply, classObjectId);

  return ERR_NONE;
}

/*
 * Handle a DDM packet with a single chunk in it.
 */
static JdwpError handleDDM_Chunk(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  uint8_t* replyBuf = NULL;
  int replyLen = -1;

  VLOG(jdwp) << StringPrintf("  Handling DDM packet (%.4s)", buf);

  /*
   * On first DDM packet, notify all handlers that DDM is running.
   */
  if (!state->ddmActive) {
    state->ddmActive = true;
    Dbg::DdmConnected();
  }

  /*
   * If they want to send something back, we copy it into the buffer.
   * A no-copy approach would be nicer.
   *
   * TODO: consider altering the JDWP stuff to hold the packet header
   * in a separate buffer.  That would allow us to writev() DDM traffic
   * instead of copying it into the expanding buffer.  The reduction in
   * heap requirements is probably more valuable than the efficiency.
   */
  if (Dbg::DdmHandlePacket(buf, dataLen, &replyBuf, &replyLen)) {
    CHECK(replyLen > 0 && replyLen < 1*1024*1024);
    memcpy(expandBufAddSpace(pReply, replyLen), replyBuf, replyLen);
    free(replyBuf);
  }
  return ERR_NONE;
}

/*
 * Handler map decl.
 */
typedef JdwpError (*JdwpRequestHandler)(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* reply);

struct JdwpHandlerMap {
  uint8_t  cmdSet;
  uint8_t  cmd;
  JdwpRequestHandler  func;
  const char* descr;
};

/*
 * Map commands to functions.
 *
 * Command sets 0-63 are incoming requests, 64-127 are outbound requests,
 * and 128-256 are vendor-defined.
 */
static const JdwpHandlerMap gHandlerMap[] = {
  /* VirtualMachine command set (1) */
  { 1,    1,  handleVM_Version,       "VirtualMachine.Version" },
  { 1,    2,  handleVM_ClassesBySignature, "VirtualMachine.ClassesBySignature" },
  { 1,    3,  NULL, "VirtualMachine.AllClasses" },
  { 1,    4,  handleVM_AllThreads,    "VirtualMachine.AllThreads" },
  { 1,    5,  handleVM_TopLevelThreadGroups, "VirtualMachine.TopLevelThreadGroups" },
  { 1,    6,  handleVM_Dispose,       "VirtualMachine.Dispose" },
  { 1,    7,  handleVM_IDSizes,       "VirtualMachine.IDSizes" },
  { 1,    8,  handleVM_Suspend,       "VirtualMachine.Suspend" },
  { 1,    9,  handleVM_Resume,        "VirtualMachine.Resume" },
  { 1,    10, handleVM_Exit,          "VirtualMachine.Exit" },
  { 1,    11, handleVM_CreateString,  "VirtualMachine.CreateString" },
  { 1,    12, handleVM_Capabilities,  "VirtualMachine.Capabilities" },
  { 1,    13, handleVM_ClassPaths,    "VirtualMachine.ClassPaths" },
  { 1,    14, HandleVM_DisposeObjects, "VirtualMachine.DisposeObjects" },
  { 1,    15, NULL, "VirtualMachine.HoldEvents" },
  { 1,    16, NULL, "VirtualMachine.ReleaseEvents" },
  { 1,    17, handleVM_CapabilitiesNew, "VirtualMachine.CapabilitiesNew" },
  { 1,    18, NULL, "VirtualMachine.RedefineClasses" },
  { 1,    19, NULL, "VirtualMachine.SetDefaultStratum" },
  { 1,    20, handleVM_AllClassesWithGeneric, "VirtualMachine.AllClassesWithGeneric" },
  { 1,    21, NULL, "VirtualMachine.InstanceCounts" },

  /* ReferenceType command set (2) */
  { 2,    1,  handleRT_Signature,     "ReferenceType.Signature" },
  { 2,    2,  handleRT_ClassLoader,   "ReferenceType.ClassLoader" },
  { 2,    3,  handleRT_Modifiers,     "ReferenceType.Modifiers" },
  { 2,    4,  handleRT_Fields,        "ReferenceType.Fields" },
  { 2,    5,  handleRT_Methods,       "ReferenceType.Methods" },
  { 2,    6,  handleRT_GetValues,     "ReferenceType.GetValues" },
  { 2,    7,  handleRT_SourceFile,    "ReferenceType.SourceFile" },
  { 2,    8,  NULL, "ReferenceType.NestedTypes" },
  { 2,    9,  handleRT_Status,        "ReferenceType.Status" },
  { 2,    10, handleRT_Interfaces,    "ReferenceType.Interfaces" },
  { 2,    11, handleRT_ClassObject,   "ReferenceType.ClassObject" },
  { 2,    12, handleRT_SourceDebugExtension, "ReferenceType.SourceDebugExtension" },
  { 2,    13, handleRT_SignatureWithGeneric, "ReferenceType.SignatureWithGeneric" },
  { 2,    14, handleRT_FieldsWithGeneric, "ReferenceType.FieldsWithGeneric" },
  { 2,    15, handleRT_MethodsWithGeneric, "ReferenceType.MethodsWithGeneric" },
  { 2,    16, NULL, "ReferenceType.Instances" },
  { 2,    17, NULL, "ReferenceType.ClassFileVersion" },
  { 2,    18, NULL, "ReferenceType.ConstantPool" },

  /* ClassType command set (3) */
  { 3,    1,  handleCT_Superclass,    "ClassType.Superclass" },
  { 3,    2,  handleCT_SetValues,     "ClassType.SetValues" },
  { 3,    3,  handleCT_InvokeMethod,  "ClassType.InvokeMethod" },
  { 3,    4,  handleCT_NewInstance,   "ClassType.NewInstance" },

  /* ArrayType command set (4) */
  { 4,    1,  handleAT_newInstance,   "ArrayType.NewInstance" },

  /* InterfaceType command set (5) */

  /* Method command set (6) */
  { 6,    1,  handleM_LineTable,      "Method.LineTable" },
  { 6,    2,  NULL, "Method.VariableTable" },
  { 6,    3,  NULL, "Method.Bytecodes" },
  { 6,    4,  NULL, "Method.IsObsolete" },
  { 6,    5,  handleM_VariableTableWithGeneric, "Method.VariableTableWithGeneric" },

  /* Field command set (8) */

  /* ObjectReference command set (9) */
  { 9,    1,  handleOR_ReferenceType, "ObjectReference.ReferenceType" },
  { 9,    2,  handleOR_GetValues,     "ObjectReference.GetValues" },
  { 9,    3,  handleOR_SetValues,     "ObjectReference.SetValues" },
  { 9,    4,  NULL, "ObjectReference.UNUSED" },
  { 9,    5,  NULL, "ObjectReference.MonitorInfo" },
  { 9,    6,  handleOR_InvokeMethod,  "ObjectReference.InvokeMethod" },
  { 9,    7,  handleOR_DisableCollection, "ObjectReference.DisableCollection" },
  { 9,    8,  handleOR_EnableCollection, "ObjectReference.EnableCollection" },
  { 9,    9,  handleOR_IsCollected,   "ObjectReference.IsCollected" },
  { 9,    10, NULL, "ObjectReference.ReferringObjects" },

  /* StringReference command set (10) */
  { 10,   1,  handleSR_Value,         "StringReference.Value" },

  /* ThreadReference command set (11) */
  { 11,   1,  handleTR_Name,          "ThreadReference.Name" },
  { 11,   2,  handleTR_Suspend,       "ThreadReference.Suspend" },
  { 11,   3,  handleTR_Resume,        "ThreadReference.Resume" },
  { 11,   4,  handleTR_Status,        "ThreadReference.Status" },
  { 11,   5,  handleTR_ThreadGroup,   "ThreadReference.ThreadGroup" },
  { 11,   6,  handleTR_Frames,        "ThreadReference.Frames" },
  { 11,   7,  handleTR_FrameCount,    "ThreadReference.FrameCount" },
  { 11,   8,  NULL, "ThreadReference.OwnedMonitors" },
  { 11,   9,  handleTR_CurrentContendedMonitor, "ThreadReference.CurrentContendedMonitor" },
  { 11,   10, NULL, "ThreadReference.Stop" },
  { 11,   11, NULL,"ThreadReference.Interrupt" },
  { 11,   12, handleTR_SuspendCount,  "ThreadReference.SuspendCount" },
  { 11,   13, NULL, "ThreadReference.OwnedMonitorsStackDepthInfo" },
  { 11,   14, NULL, "ThreadReference.ForceEarlyReturn" },

  /* ThreadGroupReference command set (12) */
  { 12,   1,  handleTGR_Name,         "ThreadGroupReference.Name" },
  { 12,   2,  handleTGR_Parent,       "ThreadGroupReference.Parent" },
  { 12,   3,  handleTGR_Children,     "ThreadGroupReference.Children" },

  /* ArrayReference command set (13) */
  { 13,   1,  handleAR_Length,        "ArrayReference.Length" },
  { 13,   2,  handleAR_GetValues,     "ArrayReference.GetValues" },
  { 13,   3,  handleAR_SetValues,     "ArrayReference.SetValues" },

  /* ClassLoaderReference command set (14) */
  { 14,   1,  handleCLR_VisibleClasses, "ClassLoaderReference.VisibleClasses" },

  /* EventRequest command set (15) */
  { 15,   1,  handleER_Set,           "EventRequest.Set" },
  { 15,   2,  handleER_Clear,         "EventRequest.Clear" },
  { 15,   3,  NULL, "EventRequest.ClearAllBreakpoints" },

  /* StackFrame command set (16) */
  { 16,   1,  handleSF_GetValues,     "StackFrame.GetValues" },
  { 16,   2,  handleSF_SetValues,     "StackFrame.SetValues" },
  { 16,   3,  handleSF_ThisObject,    "StackFrame.ThisObject" },
  { 16,   4,  NULL, "StackFrame.PopFrames" },

  /* ClassObjectReference command set (17) */
  { 17,   1,  handleCOR_ReflectedType,"ClassObjectReference.ReflectedType" },

  /* Event command set (64) */
  { 64,  100, NULL, "Event.Composite" }, // sent from VM to debugger, never received by VM

  { 199,  1,  handleDDM_Chunk,        "DDM.Chunk" },
};

static const char* GetCommandName(size_t cmdSet, size_t cmd) {
  for (int i = 0; i < (int) arraysize(gHandlerMap); i++) {
    if (gHandlerMap[i].cmdSet == cmdSet && gHandlerMap[i].cmd == cmd) {
      return gHandlerMap[i].descr;
    }
  }
  return "?UNKNOWN?";
}

static std::string DescribeCommand(const JdwpReqHeader* pHeader, int dataLen) {
  std::string result;
  result += "REQ: ";
  result += GetCommandName(pHeader->cmdSet, pHeader->cmd);
  result += StringPrintf(" (dataLen=%d id=0x%06x)", dataLen, pHeader->id);
  return result;
}

/*
 * Process a request from the debugger.
 *
 * On entry, the JDWP thread is in VMWAIT.
 */
void JdwpState::ProcessRequest(const JdwpReqHeader* pHeader, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
  JdwpError result = ERR_NONE;

  if (pHeader->cmdSet != kJDWPDdmCmdSet) {
    /*
     * Activity from a debugger, not merely ddms.  Mark us as having an
     * active debugger session, and zero out the last-activity timestamp
     * so waitForDebugger() doesn't return if we stall for a bit here.
     */
    Dbg::GoActive();
    QuasiAtomicSwap64(0, &lastActivityWhen);
  }

  /*
   * If a debugger event has fired in another thread, wait until the
   * initiating thread has suspended itself before processing messages
   * from the debugger.  Otherwise we (the JDWP thread) could be told to
   * resume the thread before it has suspended.
   *
   * We call with an argument of zero to wait for the current event
   * thread to finish, and then clear the block.  Depending on the thread
   * suspend policy, this may allow events in other threads to fire,
   * but those events have no bearing on what the debugger has sent us
   * in the current request.
   *
   * Note that we MUST clear the event token before waking the event
   * thread up, or risk waiting for the thread to suspend after we've
   * told it to resume.
   */
  SetWaitForEventThread(0);

  /*
   * Tell the VM that we're running and shouldn't be interrupted by GC.
   * Do this after anything that can stall indefinitely.
   */
  Dbg::ThreadRunning();

  expandBufAddSpace(pReply, kJDWPHeaderLen);

  size_t i;
  for (i = 0; i < arraysize(gHandlerMap); i++) {
    if (gHandlerMap[i].cmdSet == pHeader->cmdSet && gHandlerMap[i].cmd == pHeader->cmd && gHandlerMap[i].func != NULL) {
      VLOG(jdwp) << DescribeCommand(pHeader, dataLen);
      result = (*gHandlerMap[i].func)(this, buf, dataLen, pReply);
      break;
    }
  }
  if (i == arraysize(gHandlerMap)) {
    LOG(ERROR) << DescribeCommand(pHeader, dataLen);
    if (dataLen > 0) {
      HexDump(buf, dataLen);
    }
    LOG(ERROR) << "command not implemented";
    result = ERR_NOT_IMPLEMENTED;
  }

  /*
   * Set up the reply header.
   *
   * If we encountered an error, only send the header back.
   */
  uint8_t* replyBuf = expandBufGetBuffer(pReply);
  Set4BE(replyBuf + 4, pHeader->id);
  Set1(replyBuf + 8, kJDWPFlagReply);
  Set2BE(replyBuf + 9, result);
  if (result == ERR_NONE) {
    Set4BE(replyBuf + 0, expandBufGetLength(pReply));
  } else {
    Set4BE(replyBuf + 0, kJDWPHeaderLen);
  }

  size_t respLen = expandBufGetLength(pReply) - kJDWPHeaderLen;
  if (false) {
    LOG(INFO) << "reply: dataLen=" << respLen << " err=" << result << (result != ERR_NONE ? " **FAILED**" : "");
    if (respLen > 0) {
      HexDump(expandBufGetBuffer(pReply) + kJDWPHeaderLen, respLen);
    }
  }

  /*
   * Update last-activity timestamp.  We really only need this during
   * the initial setup.  Only update if this is a non-DDMS packet.
   */
  if (pHeader->cmdSet != kJDWPDdmCmdSet) {
    QuasiAtomicSwap64(MilliTime(), &lastActivityWhen);
  }

  /* tell the VM that GC is okay again */
  Dbg::ThreadWaiting();
}

}  // namespace JDWP

}  // namespace art
