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