Home | History | Annotate | Download | only in jdwp
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "jdwp/jdwp.h"
     18 
     19 #include "base/stringprintf.h"
     20 #include "jdwp/jdwp_priv.h"
     21 
     22 namespace art {
     23 
     24 namespace JDWP {
     25 
     26 Request::Request(const uint8_t* bytes, uint32_t available) : p_(bytes) {
     27   byte_count_ = Read4BE();
     28   end_ =  bytes + byte_count_;
     29   CHECK_LE(byte_count_, available);
     30 
     31   id_ = Read4BE();
     32   int8_t flags = Read1();
     33   if ((flags & kJDWPFlagReply) != 0) {
     34     LOG(FATAL) << "reply?!";
     35   }
     36 
     37   command_set_ = Read1();
     38   command_ = Read1();
     39 }
     40 
     41 Request::~Request() {
     42 }
     43 
     44 void Request::CheckConsumed() {
     45   if (p_ < end_) {
     46     CHECK(p_ == end_) << "read too few bytes: " << (end_ - p_);
     47   } else if (p_ > end_) {
     48     CHECK(p_ == end_) << "read too many bytes: " << (p_ - end_);
     49   }
     50 }
     51 
     52 std::string Request::ReadUtf8String() {
     53   uint32_t length = Read4BE();
     54   std::string s;
     55   s.resize(length);
     56   memcpy(&s[0], p_, length);
     57   p_ += length;
     58   VLOG(jdwp) << "    string \"" << s << "\"";
     59   return s;
     60 }
     61 
     62 // Helper function: read a variable-width value from the input buffer.
     63 uint64_t Request::ReadValue(size_t width) {
     64   uint64_t value = -1;
     65   switch (width) {
     66     case 1: value = Read1(); break;
     67     case 2: value = Read2BE(); break;
     68     case 4: value = Read4BE(); break;
     69     case 8: value = Read8BE(); break;
     70     default: LOG(FATAL) << width; break;
     71   }
     72   return value;
     73 }
     74 
     75 int32_t Request::ReadSigned32(const char* what) {
     76   int32_t value = static_cast<int32_t>(Read4BE());
     77   VLOG(jdwp) << "    " << what << " " << value;
     78   return value;
     79 }
     80 
     81 uint32_t Request::ReadUnsigned32(const char* what) {
     82   uint32_t value = Read4BE();
     83   VLOG(jdwp) << "    " << what << " " << value;
     84   return value;
     85 }
     86 
     87 FieldId Request::ReadFieldId() {
     88   FieldId id = Read4BE();
     89   VLOG(jdwp) << "    field id " << DescribeField(id);
     90   return id;
     91 }
     92 
     93 MethodId Request::ReadMethodId() {
     94   MethodId id = Read4BE();
     95   VLOG(jdwp) << "    method id " << DescribeMethod(id);
     96   return id;
     97 }
     98 
     99 ObjectId Request::ReadObjectId(const char* specific_kind) {
    100   ObjectId id = Read8BE();
    101   VLOG(jdwp) << StringPrintf("    %s id %#llx", specific_kind, id);
    102   return id;
    103 }
    104 
    105 ObjectId Request::ReadArrayId() {
    106   return ReadObjectId("array");
    107 }
    108 
    109 ObjectId Request::ReadObjectId() {
    110   return ReadObjectId("object");
    111 }
    112 
    113 ObjectId Request::ReadThreadId() {
    114   return ReadObjectId("thread");
    115 }
    116 
    117 ObjectId Request::ReadThreadGroupId() {
    118   return ReadObjectId("thread group");
    119 }
    120 
    121 RefTypeId Request::ReadRefTypeId() {
    122   RefTypeId id = Read8BE();
    123   VLOG(jdwp) << "    ref type id " << DescribeRefTypeId(id);
    124   return id;
    125 }
    126 
    127 FrameId Request::ReadFrameId() {
    128   FrameId id = Read8BE();
    129   VLOG(jdwp) << "    frame id " << id;
    130   return id;
    131 }
    132 
    133 JdwpTag Request::ReadTag() {
    134   return ReadEnum1<JdwpTag>("tag");
    135 }
    136 
    137 JdwpTypeTag Request::ReadTypeTag() {
    138   return ReadEnum1<JdwpTypeTag>("type tag");
    139 }
    140 
    141 JdwpLocation Request::ReadLocation() {
    142   JdwpLocation location;
    143   memset(&location, 0, sizeof(location));  // Allows memcmp(3) later.
    144   location.type_tag = ReadTypeTag();
    145   location.class_id = ReadObjectId("class");
    146   location.method_id = ReadMethodId();
    147   location.dex_pc = Read8BE();
    148   VLOG(jdwp) << "    location " << location;
    149   return location;
    150 }
    151 
    152 JdwpModKind Request::ReadModKind() {
    153   return ReadEnum1<JdwpModKind>("mod kind");
    154 }
    155 
    156 uint8_t Request::Read1() {
    157   return *p_++;
    158 }
    159 
    160 uint16_t Request::Read2BE() {
    161   uint16_t result = p_[0] << 8 | p_[1];
    162   p_ += 2;
    163   return result;
    164 }
    165 
    166 uint32_t Request::Read4BE() {
    167   uint32_t result = p_[0] << 24;
    168   result |= p_[1] << 16;
    169   result |= p_[2] << 8;
    170   result |= p_[3];
    171   p_ += 4;
    172   return result;
    173 }
    174 
    175 uint64_t Request::Read8BE() {
    176   uint64_t high = Read4BE();
    177   uint64_t low = Read4BE();
    178   return (high << 32) | low;
    179 }
    180 
    181 }  // namespace JDWP
    182 
    183 }  // namespace art
    184