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 <inttypes.h>
     20 
     21 #include "android-base/stringprintf.h"
     22 
     23 #include "jdwp/jdwp_priv.h"
     24 
     25 namespace art {
     26 
     27 namespace JDWP {
     28 
     29 Request::Request(const uint8_t* bytes, uint32_t available) : p_(bytes) {
     30   byte_count_ = Read4BE();
     31   end_ =  bytes + byte_count_;
     32   CHECK_LE(byte_count_, available);
     33 
     34   id_ = Read4BE();
     35   int8_t flags = Read1();
     36   if ((flags & kJDWPFlagReply) != 0) {
     37     LOG(FATAL) << "reply?!";
     38   }
     39 
     40   command_set_ = Read1();
     41   command_ = Read1();
     42 }
     43 
     44 Request::~Request() {
     45 }
     46 
     47 void Request::CheckConsumed() {
     48   if (p_ < end_) {
     49     CHECK(p_ == end_) << "read too few bytes: " << (end_ - p_);
     50   } else if (p_ > end_) {
     51     CHECK(p_ == end_) << "read too many bytes: " << (p_ - end_);
     52   }
     53 }
     54 
     55 std::string Request::ReadUtf8String() {
     56   uint32_t length = Read4BE();
     57   std::string s;
     58   s.resize(length);
     59   memcpy(&s[0], p_, length);
     60   p_ += length;
     61   VLOG(jdwp) << "    string \"" << s << "\"";
     62   return s;
     63 }
     64 
     65 // Helper function: read a variable-width value from the input buffer.
     66 uint64_t Request::ReadValue(size_t width) {
     67   uint64_t value = -1;
     68   switch (width) {
     69     case 1: value = Read1(); break;
     70     case 2: value = Read2BE(); break;
     71     case 4: value = Read4BE(); break;
     72     case 8: value = Read8BE(); break;
     73     default: LOG(FATAL) << width; break;
     74   }
     75   return value;
     76 }
     77 
     78 int32_t Request::ReadSigned32(const char* what) {
     79   int32_t value = static_cast<int32_t>(Read4BE());
     80   VLOG(jdwp) << "    " << what << " " << value;
     81   return value;
     82 }
     83 
     84 uint32_t Request::ReadUnsigned32(const char* what) {
     85   uint32_t value = Read4BE();
     86   VLOG(jdwp) << "    " << what << " " << value;
     87   return value;
     88 }
     89 
     90 FieldId Request::ReadFieldId() {
     91   FieldId id = Read8BE();
     92   VLOG(jdwp) << "    field id " << DescribeField(id);
     93   return id;
     94 }
     95 
     96 MethodId Request::ReadMethodId() {
     97   MethodId id = Read8BE();
     98   VLOG(jdwp) << "    method id " << DescribeMethod(id);
     99   return id;
    100 }
    101 
    102 ObjectId Request::ReadObjectId(const char* specific_kind) {
    103   ObjectId id = Read8BE();
    104   VLOG(jdwp) << android::base::StringPrintf("    %s id %#" PRIx64, specific_kind, id);
    105   return id;
    106 }
    107 
    108 ObjectId Request::ReadArrayId() {
    109   return ReadObjectId("array");
    110 }
    111 
    112 ObjectId Request::ReadObjectId() {
    113   return ReadObjectId("object");
    114 }
    115 
    116 ObjectId Request::ReadThreadId() {
    117   return ReadObjectId("thread");
    118 }
    119 
    120 ObjectId Request::ReadThreadGroupId() {
    121   return ReadObjectId("thread group");
    122 }
    123 
    124 RefTypeId Request::ReadRefTypeId() {
    125   RefTypeId id = Read8BE();
    126   VLOG(jdwp) << "    ref type id " << DescribeRefTypeId(id);
    127   return id;
    128 }
    129 
    130 FrameId Request::ReadFrameId() {
    131   FrameId id = Read8BE();
    132   VLOG(jdwp) << "    frame id " << id;
    133   return id;
    134 }
    135 
    136 JdwpTag Request::ReadTag() {
    137   return ReadEnum1<JdwpTag>("tag");
    138 }
    139 
    140 JdwpTypeTag Request::ReadTypeTag() {
    141   return ReadEnum1<JdwpTypeTag>("type tag");
    142 }
    143 
    144 JdwpLocation Request::ReadLocation() {
    145   JdwpLocation location;
    146   memset(&location, 0, sizeof(location));  // Allows memcmp(3) later.
    147   location.type_tag = ReadTypeTag();
    148   location.class_id = ReadObjectId("class");
    149   location.method_id = ReadMethodId();
    150   location.dex_pc = Read8BE();
    151   VLOG(jdwp) << "    location " << location;
    152   return location;
    153 }
    154 
    155 JdwpModKind Request::ReadModKind() {
    156   return ReadEnum1<JdwpModKind>("mod kind");
    157 }
    158 
    159 uint8_t Request::Read1() {
    160   return *p_++;
    161 }
    162 
    163 uint16_t Request::Read2BE() {
    164   uint16_t result = p_[0] << 8 | p_[1];
    165   p_ += 2;
    166   return result;
    167 }
    168 
    169 uint32_t Request::Read4BE() {
    170   uint32_t result = p_[0] << 24;
    171   result |= p_[1] << 16;
    172   result |= p_[2] << 8;
    173   result |= p_[3];
    174   p_ += 4;
    175   return result;
    176 }
    177 
    178 uint64_t Request::Read8BE() {
    179   uint64_t high = Read4BE();
    180   uint64_t low = Read4BE();
    181   return (high << 32) | low;
    182 }
    183 
    184 }  // namespace JDWP
    185 
    186 }  // namespace art
    187