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