blob: 18f40a143ce8c92152540088f1ec41f9515d7fe2 [file] [log] [blame]
Elliott Hughes4b9702c2013-02-20 18:13:24 -08001/*
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
Ian Rogersd9e4e0c2014-01-23 20:11:40 -080019#include <inttypes.h>
20
Elliott Hughes4b9702c2013-02-20 18:13:24 -080021#include "base/stringprintf.h"
Elliott Hughescb693062013-02-21 09:48:08 -080022#include "jdwp/jdwp_priv.h"
Elliott Hughes4b9702c2013-02-20 18:13:24 -080023
24namespace art {
25
26namespace JDWP {
27
Elliott Hughescb693062013-02-21 09:48:08 -080028Request::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();
Elliott Hughes4b9702c2013-02-20 18:13:24 -080041}
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() {
Elliott Hughescb693062013-02-21 09:48:08 -080055 uint32_t length = Read4BE();
Elliott Hughes4b9702c2013-02-20 18:13:24 -080056 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) {
Elliott Hughescb693062013-02-21 09:48:08 -080068 case 1: value = Read1(); break;
Elliott Hughes4b9702c2013-02-20 18:13:24 -080069 case 2: value = Read2BE(); break;
Elliott Hughescb693062013-02-21 09:48:08 -080070 case 4: value = Read4BE(); break;
Elliott Hughes4b9702c2013-02-20 18:13:24 -080071 case 8: value = Read8BE(); break;
72 default: LOG(FATAL) << width; break;
73 }
74 return value;
75}
76
77int32_t Request::ReadSigned32(const char* what) {
Elliott Hughescb693062013-02-21 09:48:08 -080078 int32_t value = static_cast<int32_t>(Read4BE());
Elliott Hughes4b9702c2013-02-20 18:13:24 -080079 VLOG(jdwp) << " " << what << " " << value;
80 return value;
81}
82
83uint32_t Request::ReadUnsigned32(const char* what) {
Elliott Hughescb693062013-02-21 09:48:08 -080084 uint32_t value = Read4BE();
Elliott Hughes4b9702c2013-02-20 18:13:24 -080085 VLOG(jdwp) << " " << what << " " << value;
86 return value;
87}
88
89FieldId Request::ReadFieldId() {
Mathieu Chartierd3ed9a32015-04-10 14:23:35 -070090 FieldId id = Read8BE();
Elliott Hughes4b9702c2013-02-20 18:13:24 -080091 VLOG(jdwp) << " field id " << DescribeField(id);
92 return id;
93}
94
95MethodId Request::ReadMethodId() {
Mathieu Chartierd3ed9a32015-04-10 14:23:35 -070096 MethodId id = Read8BE();
Elliott Hughes4b9702c2013-02-20 18:13:24 -080097 VLOG(jdwp) << " method id " << DescribeMethod(id);
98 return id;
99}
100
101ObjectId Request::ReadObjectId(const char* specific_kind) {
102 ObjectId id = Read8BE();
Ian Rogersd9e4e0c2014-01-23 20:11:40 -0800103 VLOG(jdwp) << StringPrintf(" %s id %#" PRIx64, specific_kind, id);
Elliott Hughes4b9702c2013-02-20 18:13:24 -0800104 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;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700145 memset(&location, 0, sizeof(location)); // Allows memcmp(3) later.
Elliott Hughes4b9702c2013-02-20 18:13:24 -0800146 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
Elliott Hughescb693062013-02-21 09:48:08 -0800158uint8_t Request::Read1() {
159 return *p_++;
160}
161
Elliott Hughes4b9702c2013-02-20 18:13:24 -0800162uint16_t Request::Read2BE() {
163 uint16_t result = p_[0] << 8 | p_[1];
164 p_ += 2;
165 return result;
166}
167
Elliott Hughescb693062013-02-21 09:48:08 -0800168uint32_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
Elliott Hughes4b9702c2013-02-20 18:13:24 -0800177uint64_t Request::Read8BE() {
Elliott Hughescb693062013-02-21 09:48:08 -0800178 uint64_t high = Read4BE();
179 uint64_t low = Read4BE();
Elliott Hughes4b9702c2013-02-20 18:13:24 -0800180 return (high << 32) | low;
181}
182
183} // namespace JDWP
184
185} // namespace art