Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.jdi/share/classes/com/sun/tools/jdi/PacketStream.java
41161 views
1
/*
2
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package com.sun.tools.jdi;
27
28
import java.io.ByteArrayOutputStream;
29
import java.util.ArrayList;
30
import java.util.List;
31
32
import com.sun.jdi.BooleanValue;
33
import com.sun.jdi.ByteValue;
34
import com.sun.jdi.CharValue;
35
import com.sun.jdi.ClassType;
36
import com.sun.jdi.DoubleValue;
37
import com.sun.jdi.Field;
38
import com.sun.jdi.FloatValue;
39
import com.sun.jdi.IntegerValue;
40
import com.sun.jdi.InterfaceType;
41
import com.sun.jdi.InternalException;
42
import com.sun.jdi.InvalidTypeException;
43
import com.sun.jdi.Location;
44
import com.sun.jdi.LongValue;
45
import com.sun.jdi.ObjectReference;
46
import com.sun.jdi.PrimitiveValue;
47
import com.sun.jdi.ShortValue;
48
import com.sun.jdi.Value;
49
50
class PacketStream {
51
final VirtualMachineImpl vm;
52
private int inCursor = 0;
53
final Packet pkt;
54
private ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
55
private boolean isCommitted = false;
56
57
PacketStream(VirtualMachineImpl vm, int cmdSet, int cmd) {
58
this.vm = vm;
59
this.pkt = new Packet();
60
pkt.cmdSet = (short)cmdSet;
61
pkt.cmd = (short)cmd;
62
}
63
64
PacketStream(VirtualMachineImpl vm, Packet pkt) {
65
this.vm = vm;
66
this.pkt = pkt;
67
this.isCommitted = true; /* read only stream */
68
}
69
70
int id() {
71
return pkt.id;
72
}
73
74
void send() {
75
if (!isCommitted) {
76
pkt.data = dataStream.toByteArray();
77
vm.sendToTarget(pkt);
78
isCommitted = true;
79
}
80
}
81
82
void waitForReply() throws JDWPException {
83
if (!isCommitted) {
84
throw new InternalException("waitForReply without send");
85
}
86
87
vm.waitForTargetReply(pkt);
88
89
if (pkt.errorCode != Packet.ReplyNoError) {
90
throw new JDWPException(pkt.errorCode);
91
}
92
}
93
94
void writeBoolean(boolean data) {
95
if(data) {
96
dataStream.write( 1 );
97
} else {
98
dataStream.write( 0 );
99
}
100
}
101
102
void writeByte(byte data) {
103
dataStream.write( data );
104
}
105
106
void writeChar(char data) {
107
dataStream.write( (byte)((data >>> 8) & 0xFF) );
108
dataStream.write( (byte)((data >>> 0) & 0xFF) );
109
}
110
111
void writeShort(short data) {
112
dataStream.write( (byte)((data >>> 8) & 0xFF) );
113
dataStream.write( (byte)((data >>> 0) & 0xFF) );
114
}
115
116
void writeInt(int data) {
117
dataStream.write( (byte)((data >>> 24) & 0xFF) );
118
dataStream.write( (byte)((data >>> 16) & 0xFF) );
119
dataStream.write( (byte)((data >>> 8) & 0xFF) );
120
dataStream.write( (byte)((data >>> 0) & 0xFF) );
121
}
122
123
void writeLong(long data) {
124
dataStream.write( (byte)((data >>> 56) & 0xFF) );
125
dataStream.write( (byte)((data >>> 48) & 0xFF) );
126
dataStream.write( (byte)((data >>> 40) & 0xFF) );
127
dataStream.write( (byte)((data >>> 32) & 0xFF) );
128
129
dataStream.write( (byte)((data >>> 24) & 0xFF) );
130
dataStream.write( (byte)((data >>> 16) & 0xFF) );
131
dataStream.write( (byte)((data >>> 8) & 0xFF) );
132
dataStream.write( (byte)((data >>> 0) & 0xFF) );
133
}
134
135
void writeFloat(float data) {
136
writeInt(Float.floatToIntBits(data));
137
}
138
139
void writeDouble(double data) {
140
writeLong(Double.doubleToLongBits(data));
141
}
142
143
void writeID(int size, long data) {
144
switch (size) {
145
case 8:
146
writeLong(data);
147
break;
148
case 4:
149
writeInt((int)data);
150
break;
151
case 2:
152
writeShort((short)data);
153
break;
154
default:
155
throw new UnsupportedOperationException("JDWP: ID size not supported: " + size);
156
}
157
}
158
159
void writeNullObjectRef() {
160
writeObjectRef(0);
161
}
162
163
void writeObjectRef(long data) {
164
writeID(vm.sizeofObjectRef, data);
165
}
166
167
void writeClassRef(long data) {
168
writeID(vm.sizeofClassRef, data);
169
}
170
171
void writeMethodRef(long data) {
172
writeID(vm.sizeofMethodRef, data);
173
}
174
175
void writeModuleRef(long data) {
176
writeID(vm.sizeofModuleRef, data);
177
}
178
179
void writeFieldRef(long data) {
180
writeID(vm.sizeofFieldRef, data);
181
}
182
183
void writeFrameRef(long data) {
184
writeID(vm.sizeofFrameRef, data);
185
}
186
187
void writeByteArray(byte[] data) {
188
dataStream.write(data, 0, data.length);
189
}
190
191
void writeString(String string) {
192
try {
193
byte[] stringBytes = string.getBytes("UTF8");
194
writeInt(stringBytes.length);
195
writeByteArray(stringBytes);
196
} catch (java.io.UnsupportedEncodingException e) {
197
throw new InternalException("Cannot convert string to UTF8 bytes");
198
}
199
}
200
201
void writeLocation(Location location) {
202
ReferenceTypeImpl refType = (ReferenceTypeImpl)location.declaringType();
203
byte tag;
204
if (refType instanceof ClassType) {
205
tag = JDWP.TypeTag.CLASS;
206
} else if (refType instanceof InterfaceType) {
207
// It's possible to have executable code in an interface
208
tag = JDWP.TypeTag.INTERFACE;
209
} else {
210
throw new InternalException("Invalid Location");
211
}
212
writeByte(tag);
213
writeClassRef(refType.ref());
214
writeMethodRef(((MethodImpl)location.method()).ref());
215
writeLong(location.codeIndex());
216
}
217
218
void writeValue(Value val) {
219
try {
220
writeValueChecked(val);
221
} catch (InvalidTypeException exc) { // should never happen
222
throw new RuntimeException(
223
"Internal error: Invalid Tag/Type pair");
224
}
225
}
226
227
void writeValueChecked(Value val) throws InvalidTypeException {
228
writeByte(ValueImpl.typeValueKey(val));
229
writeUntaggedValue(val);
230
}
231
232
void writeUntaggedValue(Value val) {
233
try {
234
writeUntaggedValueChecked(val);
235
} catch (InvalidTypeException exc) { // should never happen
236
throw new RuntimeException(
237
"Internal error: Invalid Tag/Type pair");
238
}
239
}
240
241
void writeUntaggedValueChecked(Value val) throws InvalidTypeException {
242
byte tag = ValueImpl.typeValueKey(val);
243
if (isObjectTag(tag)) {
244
if (val == null) {
245
writeObjectRef(0);
246
} else {
247
if (!(val instanceof ObjectReference)) {
248
throw new InvalidTypeException();
249
}
250
writeObjectRef(((ObjectReferenceImpl)val).ref());
251
}
252
} else {
253
switch (tag) {
254
case JDWP.Tag.BYTE:
255
if(!(val instanceof ByteValue))
256
throw new InvalidTypeException();
257
258
writeByte(((PrimitiveValue)val).byteValue());
259
break;
260
261
case JDWP.Tag.CHAR:
262
if(!(val instanceof CharValue))
263
throw new InvalidTypeException();
264
265
writeChar(((PrimitiveValue)val).charValue());
266
break;
267
268
case JDWP.Tag.FLOAT:
269
if(!(val instanceof FloatValue))
270
throw new InvalidTypeException();
271
272
writeFloat(((PrimitiveValue)val).floatValue());
273
break;
274
275
case JDWP.Tag.DOUBLE:
276
if(!(val instanceof DoubleValue))
277
throw new InvalidTypeException();
278
279
writeDouble(((PrimitiveValue)val).doubleValue());
280
break;
281
282
case JDWP.Tag.INT:
283
if(!(val instanceof IntegerValue))
284
throw new InvalidTypeException();
285
286
writeInt(((PrimitiveValue)val).intValue());
287
break;
288
289
case JDWP.Tag.LONG:
290
if(!(val instanceof LongValue))
291
throw new InvalidTypeException();
292
293
writeLong(((PrimitiveValue)val).longValue());
294
break;
295
296
case JDWP.Tag.SHORT:
297
if(!(val instanceof ShortValue))
298
throw new InvalidTypeException();
299
300
writeShort(((PrimitiveValue)val).shortValue());
301
break;
302
303
case JDWP.Tag.BOOLEAN:
304
if(!(val instanceof BooleanValue))
305
throw new InvalidTypeException();
306
307
writeBoolean(((PrimitiveValue)val).booleanValue());
308
break;
309
}
310
}
311
}
312
313
/**
314
* Read byte represented as one bytes.
315
*/
316
byte readByte() {
317
byte ret = pkt.data[inCursor];
318
inCursor += 1;
319
return ret;
320
}
321
322
/**
323
* Read boolean represented as one byte.
324
*/
325
boolean readBoolean() {
326
byte ret = readByte();
327
return (ret != 0);
328
}
329
330
/**
331
* Read char represented as two bytes.
332
*/
333
char readChar() {
334
int b1, b2;
335
336
b1 = pkt.data[inCursor++] & 0xff;
337
b2 = pkt.data[inCursor++] & 0xff;
338
339
return (char)((b1 << 8) + b2);
340
}
341
342
/**
343
* Read short represented as two bytes.
344
*/
345
short readShort() {
346
int b1, b2;
347
348
b1 = pkt.data[inCursor++] & 0xff;
349
b2 = pkt.data[inCursor++] & 0xff;
350
351
return (short)((b1 << 8) + b2);
352
}
353
354
/**
355
* Read int represented as four bytes.
356
*/
357
int readInt() {
358
int b1,b2,b3,b4;
359
360
b1 = pkt.data[inCursor++] & 0xff;
361
b2 = pkt.data[inCursor++] & 0xff;
362
b3 = pkt.data[inCursor++] & 0xff;
363
b4 = pkt.data[inCursor++] & 0xff;
364
365
return ((b1 << 24) + (b2 << 16) + (b3 << 8) + b4);
366
}
367
368
/**
369
* Read long represented as eight bytes.
370
*/
371
long readLong() {
372
long b1,b2,b3,b4;
373
long b5,b6,b7,b8;
374
375
b1 = pkt.data[inCursor++] & 0xff;
376
b2 = pkt.data[inCursor++] & 0xff;
377
b3 = pkt.data[inCursor++] & 0xff;
378
b4 = pkt.data[inCursor++] & 0xff;
379
380
b5 = pkt.data[inCursor++] & 0xff;
381
b6 = pkt.data[inCursor++] & 0xff;
382
b7 = pkt.data[inCursor++] & 0xff;
383
b8 = pkt.data[inCursor++] & 0xff;
384
385
return ((b1 << 56) + (b2 << 48) + (b3 << 40) + (b4 << 32)
386
+ (b5 << 24) + (b6 << 16) + (b7 << 8) + b8);
387
}
388
389
/**
390
* Read float represented as four bytes.
391
*/
392
float readFloat() {
393
return Float.intBitsToFloat(readInt());
394
}
395
396
/**
397
* Read double represented as eight bytes.
398
*/
399
double readDouble() {
400
return Double.longBitsToDouble(readLong());
401
}
402
403
/**
404
* Read string represented as four byte length followed by
405
* characters of the string.
406
*/
407
String readString() {
408
String ret;
409
int len = readInt();
410
411
try {
412
ret = new String(pkt.data, inCursor, len, "UTF8");
413
} catch(java.io.UnsupportedEncodingException e) {
414
System.err.println(e);
415
ret = "Conversion error!";
416
}
417
inCursor += len;
418
return ret;
419
}
420
421
private long readID(int size) {
422
switch (size) {
423
case 8:
424
return readLong();
425
case 4:
426
return readInt();
427
case 2:
428
return readShort();
429
default:
430
throw new UnsupportedOperationException("JDWP: ID size not supported: " + size);
431
}
432
}
433
434
/**
435
* Read object represented as vm specific byte sequence.
436
*/
437
long readObjectRef() {
438
return readID(vm.sizeofObjectRef);
439
}
440
441
long readClassRef() {
442
return readID(vm.sizeofClassRef);
443
}
444
445
ObjectReferenceImpl readTaggedObjectReference() {
446
byte typeKey = readByte();
447
return vm.objectMirror(readObjectRef(), typeKey);
448
}
449
450
ObjectReferenceImpl readObjectReference() {
451
return vm.objectMirror(readObjectRef());
452
}
453
454
StringReferenceImpl readStringReference() {
455
long ref = readObjectRef();
456
return vm.stringMirror(ref);
457
}
458
459
ArrayReferenceImpl readArrayReference() {
460
long ref = readObjectRef();
461
return vm.arrayMirror(ref);
462
}
463
464
ThreadReferenceImpl readThreadReference() {
465
long ref = readObjectRef();
466
return vm.threadMirror(ref);
467
}
468
469
ThreadGroupReferenceImpl readThreadGroupReference() {
470
long ref = readObjectRef();
471
return vm.threadGroupMirror(ref);
472
}
473
474
ClassLoaderReferenceImpl readClassLoaderReference() {
475
long ref = readObjectRef();
476
return vm.classLoaderMirror(ref);
477
}
478
479
ClassObjectReferenceImpl readClassObjectReference() {
480
long ref = readObjectRef();
481
return vm.classObjectMirror(ref);
482
}
483
484
ReferenceTypeImpl readReferenceType() {
485
byte tag = readByte();
486
long ref = readObjectRef();
487
return vm.referenceType(ref, tag);
488
}
489
490
ModuleReferenceImpl readModule() {
491
long ref = readModuleRef();
492
return vm.moduleMirror(ref);
493
}
494
495
/**
496
* Read method reference represented as vm specific byte sequence.
497
*/
498
long readMethodRef() {
499
return readID(vm.sizeofMethodRef);
500
}
501
502
/**
503
* Read module reference represented as vm specific byte sequence.
504
*/
505
long readModuleRef() {
506
return readID(vm.sizeofModuleRef);
507
}
508
509
/**
510
* Read field reference represented as vm specific byte sequence.
511
*/
512
long readFieldRef() {
513
return readID(vm.sizeofFieldRef);
514
}
515
516
/**
517
* Read field represented as vm specific byte sequence.
518
*/
519
Field readField() {
520
ReferenceTypeImpl refType = readReferenceType();
521
long fieldRef = readFieldRef();
522
return refType.getFieldMirror(fieldRef);
523
}
524
525
/**
526
* Read frame represented as vm specific byte sequence.
527
*/
528
long readFrameRef() {
529
return readID(vm.sizeofFrameRef);
530
}
531
532
/**
533
* Read a value, first byte describes type of value to read.
534
*/
535
ValueImpl readValue() {
536
byte typeKey = readByte();
537
return readUntaggedValue(typeKey);
538
}
539
540
ValueImpl readUntaggedValue(byte typeKey) {
541
ValueImpl val = null;
542
543
if (isObjectTag(typeKey)) {
544
val = vm.objectMirror(readObjectRef(), typeKey);
545
} else {
546
switch(typeKey) {
547
case JDWP.Tag.BYTE:
548
val = new ByteValueImpl(vm, readByte());
549
break;
550
551
case JDWP.Tag.CHAR:
552
val = new CharValueImpl(vm, readChar());
553
break;
554
555
case JDWP.Tag.FLOAT:
556
val = new FloatValueImpl(vm, readFloat());
557
break;
558
559
case JDWP.Tag.DOUBLE:
560
val = new DoubleValueImpl(vm, readDouble());
561
break;
562
563
case JDWP.Tag.INT:
564
val = new IntegerValueImpl(vm, readInt());
565
break;
566
567
case JDWP.Tag.LONG:
568
val = new LongValueImpl(vm, readLong());
569
break;
570
571
case JDWP.Tag.SHORT:
572
val = new ShortValueImpl(vm, readShort());
573
break;
574
575
case JDWP.Tag.BOOLEAN:
576
val = new BooleanValueImpl(vm, readBoolean());
577
break;
578
579
case JDWP.Tag.VOID:
580
val = new VoidValueImpl(vm);
581
break;
582
}
583
}
584
return val;
585
}
586
587
/**
588
* Read location represented as vm specific byte sequence.
589
*/
590
Location readLocation() {
591
byte tag = readByte();
592
long classRef = readObjectRef();
593
long methodRef = readMethodRef();
594
long codeIndex = readLong();
595
if (classRef != 0) {
596
/* Valid location */
597
ReferenceTypeImpl refType = vm.referenceType(classRef, tag);
598
return new LocationImpl(vm, refType, methodRef, codeIndex);
599
} else {
600
/* Null location (example: uncaught exception) */
601
return null;
602
}
603
}
604
605
byte[] readByteArray(int length) {
606
byte[] array = new byte[length];
607
System.arraycopy(pkt.data, inCursor, array, 0, length);
608
inCursor += length;
609
return array;
610
}
611
612
List<Value> readArrayRegion() {
613
byte typeKey = readByte();
614
int length = readInt();
615
List<Value> list = new ArrayList<>(length);
616
boolean gettingObjects = isObjectTag(typeKey);
617
for (int i = 0; i < length; i++) {
618
/*
619
* Each object comes back with a type key which might
620
* identify a more specific type than the type key we
621
* passed in, so we use it in the decodeValue call.
622
* (For primitives, we just use the original one)
623
*/
624
if (gettingObjects) {
625
typeKey = readByte();
626
}
627
Value value = readUntaggedValue(typeKey);
628
list.add(value);
629
}
630
631
return list;
632
}
633
634
void writeArrayRegion(List<Value> srcValues) {
635
writeInt(srcValues.size());
636
for (int i = 0; i < srcValues.size(); i++) {
637
Value value = srcValues.get(i);
638
writeUntaggedValue(value);
639
}
640
}
641
642
int skipBytes(int n) {
643
inCursor += n;
644
return n;
645
}
646
647
byte command() {
648
return (byte)pkt.cmd;
649
}
650
651
static boolean isObjectTag(byte tag) {
652
return (tag == JDWP.Tag.OBJECT) ||
653
(tag == JDWP.Tag.ARRAY) ||
654
(tag == JDWP.Tag.STRING) ||
655
(tag == JDWP.Tag.THREAD) ||
656
(tag == JDWP.Tag.THREAD_GROUP) ||
657
(tag == JDWP.Tag.CLASS_LOADER) ||
658
(tag == JDWP.Tag.CLASS_OBJECT);
659
}
660
}
661
662