• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = Read4BE();
91    VLOG(jdwp) << "    field id " << DescribeField(id);
92    return id;
93  }
94  
ReadMethodId()95  MethodId Request::ReadMethodId() {
96    MethodId id = Read4BE();
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