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 
Request(const uint8_t * bytes,uint32_t available)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 
~Request()43 Request::~Request() {
44 }
45 
CheckConsumed()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 
ReadUtf8String()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.
ReadValue(size_t width)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 
ReadSigned32(const char * what)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 
ReadUnsigned32(const char * what)83 uint32_t Request::ReadUnsigned32(const char* what) {
84   uint32_t value = Read4BE();
85   VLOG(jdwp) << "    " << what << " " << value;
86   return value;
87 }
88 
ReadFieldId()89 FieldId Request::ReadFieldId() {
90   FieldId id = Read8BE();
91   VLOG(jdwp) << "    field id " << DescribeField(id);
92   return id;
93 }
94 
ReadMethodId()95 MethodId Request::ReadMethodId() {
96   MethodId id = Read8BE();
97   VLOG(jdwp) << "    method id " << DescribeMethod(id);
98   return id;
99 }
100 
ReadObjectId(const char * specific_kind)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 
ReadArrayId()107 ObjectId Request::ReadArrayId() {
108   return ReadObjectId("array");
109 }
110 
ReadObjectId()111 ObjectId Request::ReadObjectId() {
112   return ReadObjectId("object");
113 }
114 
ReadThreadId()115 ObjectId Request::ReadThreadId() {
116   return ReadObjectId("thread");
117 }
118 
ReadThreadGroupId()119 ObjectId Request::ReadThreadGroupId() {
120   return ReadObjectId("thread group");
121 }
122 
ReadRefTypeId()123 RefTypeId Request::ReadRefTypeId() {
124   RefTypeId id = Read8BE();
125   VLOG(jdwp) << "    ref type id " << DescribeRefTypeId(id);
126   return id;
127 }
128 
ReadFrameId()129 FrameId Request::ReadFrameId() {
130   FrameId id = Read8BE();
131   VLOG(jdwp) << "    frame id " << id;
132   return id;
133 }
134 
ReadTag()135 JdwpTag Request::ReadTag() {
136   return ReadEnum1<JdwpTag>("tag");
137 }
138 
ReadTypeTag()139 JdwpTypeTag Request::ReadTypeTag() {
140   return ReadEnum1<JdwpTypeTag>("type tag");
141 }
142 
ReadLocation()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 
ReadModKind()154 JdwpModKind Request::ReadModKind() {
155   return ReadEnum1<JdwpModKind>("mod kind");
156 }
157 
Read1()158 uint8_t Request::Read1() {
159   return *p_++;
160 }
161 
Read2BE()162 uint16_t Request::Read2BE() {
163   uint16_t result = p_[0] << 8 | p_[1];
164   p_ += 2;
165   return result;
166 }
167 
Read4BE()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 
Read8BE()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