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