Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/DebuggerBase.java
41161 views
1
/*
2
* Copyright (c) 2001, 2021, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
package sun.jvm.hotspot.debugger;
26
27
/** <P> DebuggerBase is a recommended base class for debugger
28
implementations. It can use a PageCache to cache data from the
29
target process. Note that this class would not be suitable if the
30
system were used to reflect upon itself; it would never be safe to
31
store the value in an OopHandle in anything but an OopHandle.
32
However, it provides a fair amount of code sharing to the current
33
dbx and win32 implementations. </P>
34
35
<P> NOTE that much of the code sharing is achieved by having this
36
class implement many of the methods in the Win32Debugger and
37
DbxDebugger interfaces. </P> */
38
39
public abstract class DebuggerBase implements Debugger {
40
41
// May be set lazily, but must be set before calling any of the read
42
// routines below
43
protected MachineDescription machDesc;
44
protected DebuggerUtilities utils;
45
// Java primitive type sizes, set during bootstrapping. Do not call
46
// any of the Java read routines until these are set up.
47
protected long jbooleanSize;
48
protected long jbyteSize;
49
protected long jcharSize;
50
protected long jdoubleSize;
51
protected long jfloatSize;
52
protected long jintSize;
53
protected long jlongSize;
54
protected long jshortSize;
55
protected boolean javaPrimitiveTypesConfigured;
56
// heap data.
57
protected long oopSize;
58
protected long heapOopSize;
59
protected long narrowOopBase; // heap base for compressed oops.
60
protected int narrowOopShift; // shift to decode compressed oops.
61
// class metadata space
62
protected long klassPtrSize;
63
protected long narrowKlassBase; // heap base for compressed klass ptrs.
64
protected int narrowKlassShift; // shift to decode compressed klass ptrs.
65
// Should be initialized if desired by calling initCache()
66
private PageCache cache;
67
68
// State for faster accessors that don't allocate memory on each read
69
private boolean useFastAccessors;
70
private boolean bigEndian;
71
72
// Page-fetching functionality for LRU cache
73
class Fetcher implements PageFetcher {
74
public Page fetchPage(long pageBaseAddress, long numBytes) {
75
// This assumes that if any byte is unmapped, that the entire
76
// page is. The common case, however, is that the page is
77
// mapped, so we always fetch the entire thing all at once to
78
// avoid two round-trip communications per page fetch, even
79
// though fetching of unmapped pages will be slow.
80
ReadResult res = readBytesFromProcess(pageBaseAddress, numBytes);
81
if (res.getData() == null) {
82
return new Page(pageBaseAddress, numBytes);
83
}
84
return new Page(pageBaseAddress, res.getData());
85
}
86
}
87
88
protected DebuggerBase() {
89
}
90
91
/** From the JVMDebugger interface. This is the only public method
92
of this class. */
93
public void configureJavaPrimitiveTypeSizes(long jbooleanSize,
94
long jbyteSize,
95
long jcharSize,
96
long jdoubleSize,
97
long jfloatSize,
98
long jintSize,
99
long jlongSize,
100
long jshortSize) {
101
this.jbooleanSize = jbooleanSize;
102
this.jbyteSize = jbyteSize;
103
this.jcharSize = jcharSize;
104
this.jdoubleSize = jdoubleSize;
105
this.jfloatSize = jfloatSize;
106
this.jintSize = jintSize;
107
this.jlongSize = jlongSize;
108
this.jshortSize = jshortSize;
109
110
if (jbooleanSize < 1) {
111
throw new RuntimeException("jboolean size is too small");
112
}
113
114
if (jbyteSize < 1) {
115
throw new RuntimeException("jbyte size is too small");
116
}
117
118
if (jcharSize < 2) {
119
throw new RuntimeException("jchar size is too small");
120
}
121
122
if (jdoubleSize < 8) {
123
throw new RuntimeException("jdouble size is too small");
124
}
125
126
if (jfloatSize < 4) {
127
throw new RuntimeException("jfloat size is too small");
128
}
129
130
if (jintSize < 4) {
131
throw new RuntimeException("jint size is too small");
132
}
133
134
if (jlongSize < 8) {
135
throw new RuntimeException("jlong size is too small");
136
}
137
138
if (jshortSize < 2) {
139
throw new RuntimeException("jshort size is too small");
140
}
141
142
if (jintSize != jfloatSize) {
143
// If dataToJFloat were rewritten, this wouldn't be necessary
144
throw new RuntimeException("jint size and jfloat size must be equal");
145
}
146
147
if (jlongSize != jdoubleSize) {
148
// If dataToJDouble were rewritten, this wouldn't be necessary
149
throw new RuntimeException("jlong size and jdouble size must be equal");
150
}
151
152
useFastAccessors =
153
((cache != null) &&
154
(jbooleanSize == 1) &&
155
(jbyteSize == 1) &&
156
(jcharSize == 2) &&
157
(jdoubleSize == 8) &&
158
(jfloatSize == 4) &&
159
(jintSize == 4) &&
160
(jlongSize == 8) &&
161
(jshortSize == 2));
162
163
javaPrimitiveTypesConfigured = true;
164
}
165
166
public void putHeapConst(long heapOopSize, long klassPtrSize, long narrowOopBase, int narrowOopShift,
167
long narrowKlassBase, int narrowKlassShift) {
168
this.heapOopSize = heapOopSize;
169
this.klassPtrSize = klassPtrSize;
170
this.narrowOopBase = narrowOopBase;
171
this.narrowOopShift = narrowOopShift;
172
this.narrowKlassBase = narrowKlassBase;
173
this.narrowKlassShift = narrowKlassShift;
174
}
175
176
/** May be called by subclasses if desired to initialize the page
177
cache but may not be overridden */
178
protected final void initCache(long pageSize, long maxNumPages) {
179
cache = new PageCache(pageSize, maxNumPages, new Fetcher());
180
if (machDesc != null) {
181
bigEndian = machDesc.isBigEndian();
182
}
183
}
184
185
/** May be called by subclasses if needed (if the machine
186
description is not available at the time of cache
187
initialization, as on Solaris) but may not be overridden */
188
protected final void setBigEndian(boolean bigEndian) {
189
this.bigEndian = bigEndian;
190
}
191
192
/** May be called by subclasses to clear out the cache but may not
193
be overridden. For convenience, this can be called even if the
194
cache has not been initialized. */
195
protected final void clearCache() {
196
if (cache != null) {
197
cache.clear();
198
}
199
}
200
201
/** May be called by subclasses to disable the cache (for example,
202
when the target process has been resumed) but may not be
203
overridden. For convenience, this can be called even if the
204
cache has not been initialized. */
205
protected final void disableCache() {
206
if (cache != null) {
207
cache.disable();
208
}
209
}
210
211
/** May be called by subclasses to re-enable the cache (for example,
212
when the target process has been suspended) but may not be
213
overridden. For convenience, this can be called even if the
214
cache has not been initialized. */
215
protected final void enableCache() {
216
if (cache != null) {
217
cache.enable();
218
}
219
}
220
221
/** May be called by subclasses directly but may not be overridden */
222
protected final byte[] readBytes(long address, long numBytes)
223
throws UnmappedAddressException, DebuggerException {
224
if (cache != null) {
225
return cache.getData(address, numBytes);
226
} else {
227
ReadResult res = readBytesFromProcess(address, numBytes);
228
if (res.getData() != null) {
229
return res.getData();
230
}
231
throw new UnmappedAddressException(res.getFailureAddress());
232
}
233
}
234
235
/** May be called by subclasses directly but may not be overridden */
236
protected final void writeBytes(long address, long numBytes, byte[] data)
237
throws UnmappedAddressException, DebuggerException {
238
if (cache != null) {
239
cache.clear(address, numBytes);
240
}
241
writeBytesToProcess(address, numBytes, data);
242
}
243
244
public boolean readJBoolean(long address)
245
throws UnmappedAddressException, UnalignedAddressException {
246
checkJavaConfigured();
247
utils.checkAlignment(address, jbooleanSize);
248
if (useFastAccessors) {
249
return (cache.getByte(address) != 0);
250
} else {
251
byte[] data = readBytes(address, jbooleanSize);
252
return utils.dataToJBoolean(data, jbooleanSize);
253
}
254
}
255
256
public byte readJByte(long address)
257
throws UnmappedAddressException, UnalignedAddressException {
258
checkJavaConfigured();
259
utils.checkAlignment(address, jbyteSize);
260
if (useFastAccessors) {
261
return cache.getByte(address);
262
} else {
263
byte[] data = readBytes(address, jbyteSize);
264
return utils.dataToJByte(data, jbyteSize);
265
}
266
}
267
268
// NOTE: assumes value does not span pages (may be bad assumption on
269
// Solaris/x86; see unalignedAccessesOkay in DbxDebugger hierarchy)
270
public char readJChar(long address)
271
throws UnmappedAddressException, UnalignedAddressException {
272
checkJavaConfigured();
273
utils.checkAlignment(address, jcharSize);
274
if (useFastAccessors) {
275
return cache.getChar(address, bigEndian);
276
} else {
277
byte[] data = readBytes(address, jcharSize);
278
return (char) utils.dataToJChar(data, jcharSize);
279
}
280
}
281
282
// NOTE: assumes value does not span pages (may be bad assumption on
283
// Solaris/x86; see unalignedAccessesOkay in DbxDebugger hierarchy)
284
public double readJDouble(long address)
285
throws UnmappedAddressException, UnalignedAddressException {
286
checkJavaConfigured();
287
utils.checkAlignment(address, jdoubleSize);
288
if (useFastAccessors) {
289
return cache.getDouble(address, bigEndian);
290
} else {
291
byte[] data = readBytes(address, jdoubleSize);
292
return utils.dataToJDouble(data, jdoubleSize);
293
}
294
}
295
296
// NOTE: assumes value does not span pages (may be bad assumption on
297
// Solaris/x86; see unalignedAccessesOkay in DbxDebugger hierarchy)
298
public float readJFloat(long address)
299
throws UnmappedAddressException, UnalignedAddressException {
300
checkJavaConfigured();
301
utils.checkAlignment(address, jfloatSize);
302
if (useFastAccessors) {
303
return cache.getFloat(address, bigEndian);
304
} else {
305
byte[] data = readBytes(address, jfloatSize);
306
return utils.dataToJFloat(data, jfloatSize);
307
}
308
}
309
310
// NOTE: assumes value does not span pages (may be bad assumption on
311
// Solaris/x86; see unalignedAccessesOkay in DbxDebugger hierarchy)
312
public int readJInt(long address)
313
throws UnmappedAddressException, UnalignedAddressException {
314
checkJavaConfigured();
315
utils.checkAlignment(address, jintSize);
316
if (useFastAccessors) {
317
return cache.getInt(address, bigEndian);
318
} else {
319
byte[] data = readBytes(address, jintSize);
320
return utils.dataToJInt(data, jintSize);
321
}
322
}
323
324
// NOTE: assumes value does not span pages (may be bad assumption on
325
// Solaris/x86; see unalignedAccessesOkay in DbxDebugger hierarchy)
326
public long readJLong(long address)
327
throws UnmappedAddressException, UnalignedAddressException {
328
checkJavaConfigured();
329
utils.checkAlignment(address, jlongSize);
330
if (useFastAccessors) {
331
return cache.getLong(address, bigEndian);
332
} else {
333
byte[] data = readBytes(address, jlongSize);
334
return utils.dataToJLong(data, jlongSize);
335
}
336
}
337
338
// NOTE: assumes value does not span pages (may be bad assumption on
339
// Solaris/x86; see unalignedAccessesOkay in DbxDebugger hierarchy)
340
public short readJShort(long address)
341
throws UnmappedAddressException, UnalignedAddressException {
342
checkJavaConfigured();
343
utils.checkAlignment(address, jshortSize);
344
if (useFastAccessors) {
345
return cache.getShort(address, bigEndian);
346
} else {
347
byte[] data = readBytes(address, jshortSize);
348
return utils.dataToJShort(data, jshortSize);
349
}
350
}
351
352
// NOTE: assumes value does not span pages (may be bad assumption on
353
// Solaris/x86; see unalignedAccessesOkay in DbxDebugger hierarchy)
354
public long readCInteger(long address, long numBytes, boolean isUnsigned)
355
throws UnmappedAddressException, UnalignedAddressException {
356
checkConfigured();
357
utils.checkAlignment(address, numBytes);
358
if (useFastAccessors) {
359
if (isUnsigned) {
360
switch((int) numBytes) {
361
case 1: return cache.getByte(address) & 0xFF;
362
case 2: return cache.getShort(address, bigEndian) & 0xFFFF;
363
case 4: return cache.getInt(address, bigEndian) & 0xFFFFFFFFL;
364
case 8: return cache.getLong(address, bigEndian);
365
default: {
366
byte[] data = readBytes(address, numBytes);
367
return utils.dataToCInteger(data, isUnsigned);
368
}
369
}
370
} else {
371
switch((int) numBytes) {
372
case 1: return cache.getByte(address);
373
case 2: return cache.getShort(address, bigEndian);
374
case 4: return cache.getInt(address, bigEndian);
375
case 8: return cache.getLong(address, bigEndian);
376
default: {
377
byte[] data = readBytes(address, numBytes);
378
return utils.dataToCInteger(data, isUnsigned);
379
}
380
}
381
}
382
} else {
383
byte[] data = readBytes(address, numBytes);
384
return utils.dataToCInteger(data, isUnsigned);
385
}
386
}
387
388
public void writeJBoolean(long address, boolean value)
389
throws UnmappedAddressException, UnalignedAddressException {
390
checkJavaConfigured();
391
utils.checkAlignment(address, jbooleanSize);
392
byte[] data = utils.jbooleanToData(value);
393
writeBytes(address, jbooleanSize, data);
394
}
395
396
public void writeJByte(long address, byte value)
397
throws UnmappedAddressException, UnalignedAddressException {
398
checkJavaConfigured();
399
utils.checkAlignment(address, jbyteSize);
400
byte[] data = utils.jbyteToData(value);
401
writeBytes(address, jbyteSize, data);
402
}
403
404
public void writeJChar(long address, char value)
405
throws UnmappedAddressException, UnalignedAddressException {
406
checkJavaConfigured();
407
utils.checkAlignment(address, jcharSize);
408
byte[] data = utils.jcharToData(value);
409
writeBytes(address, jcharSize, data);
410
}
411
412
public void writeJDouble(long address, double value)
413
throws UnmappedAddressException, UnalignedAddressException {
414
checkJavaConfigured();
415
utils.checkAlignment(address, jdoubleSize);
416
byte[] data = utils.jdoubleToData(value);
417
writeBytes(address, jdoubleSize, data);
418
}
419
420
public void writeJFloat(long address, float value)
421
throws UnmappedAddressException, UnalignedAddressException {
422
checkJavaConfigured();
423
utils.checkAlignment(address, jfloatSize);
424
byte[] data = utils.jfloatToData(value);
425
writeBytes(address, jfloatSize, data);
426
}
427
428
public void writeJInt(long address, int value)
429
throws UnmappedAddressException, UnalignedAddressException {
430
checkJavaConfigured();
431
utils.checkAlignment(address, jintSize);
432
byte[] data = utils.jintToData(value);
433
writeBytes(address, jintSize, data);
434
}
435
436
public void writeJLong(long address, long value)
437
throws UnmappedAddressException, UnalignedAddressException {
438
checkJavaConfigured();
439
utils.checkAlignment(address, jlongSize);
440
byte[] data = utils.jlongToData(value);
441
writeBytes(address, jlongSize, data);
442
}
443
444
public void writeJShort(long address, short value)
445
throws UnmappedAddressException, UnalignedAddressException {
446
checkJavaConfigured();
447
utils.checkAlignment(address, jshortSize);
448
byte[] data = utils.jshortToData(value);
449
writeBytes(address, jshortSize, data);
450
}
451
452
public void writeCInteger(long address, long numBytes, long value)
453
throws UnmappedAddressException, UnalignedAddressException {
454
checkConfigured();
455
utils.checkAlignment(address, numBytes);
456
byte[] data = utils.cIntegerToData(numBytes, value);
457
writeBytes(address, numBytes, data);
458
}
459
460
protected long readAddressValue(long address)
461
throws UnmappedAddressException, UnalignedAddressException {
462
return readCInteger(address, machDesc.getAddressSize(), true);
463
}
464
465
protected long readCompOopAddressValue(long address)
466
throws UnmappedAddressException, UnalignedAddressException {
467
long value = readCInteger(address, getHeapOopSize(), true);
468
if (value != 0) {
469
// See oop.inline.hpp decode_heap_oop
470
value = (long)(narrowOopBase + (long)(value << narrowOopShift));
471
}
472
return value;
473
}
474
475
protected long readCompKlassAddressValue(long address)
476
throws UnmappedAddressException, UnalignedAddressException {
477
long value = readCInteger(address, getKlassPtrSize(), true);
478
if (value != 0) {
479
value = (long)(narrowKlassBase + (long)(value << narrowKlassShift));
480
}
481
return value;
482
}
483
484
protected void writeAddressValue(long address, long value)
485
throws UnmappedAddressException, UnalignedAddressException {
486
writeCInteger(address, machDesc.getAddressSize(), value);
487
}
488
489
/** Can be called by subclasses but can not be overridden */
490
protected final void checkConfigured() {
491
if (machDesc == null) {
492
throw new RuntimeException("MachineDescription must have been set by this point");
493
}
494
if (utils == null) {
495
throw new RuntimeException("DebuggerUtilities must have been set by this point");
496
}
497
}
498
499
/** Can be called by subclasses but can not be overridden */
500
protected final void checkJavaConfigured() {
501
checkConfigured();
502
503
if (!javaPrimitiveTypesConfigured) {
504
throw new RuntimeException("Java primitive type sizes have not yet been configured");
505
}
506
}
507
508
/** Possibly override page cache size with user-specified property */
509
protected int parseCacheNumPagesProperty(int defaultNum) {
510
String cacheNumPagesString = System.getProperty("cacheNumPages");
511
if (cacheNumPagesString != null) {
512
try {
513
return Integer.parseInt(cacheNumPagesString);
514
} catch (Exception e) {
515
System.err.println("Error parsing cacheNumPages property:");
516
e.printStackTrace();
517
}
518
}
519
return defaultNum;
520
}
521
522
/** Interim solution for allowing subclasses to write bytes to
523
process until we make that functionality available in the basic
524
Address interface */
525
protected void invalidatePageCache(long startAddress, long numBytes) {
526
cache.clear(startAddress, numBytes);
527
}
528
529
@Override
530
public String findSymbol(String symbol) {
531
Address addr = lookup(null, symbol);
532
if (addr == null && getOS().equals("win32")) {
533
// On win32 symbols are prefixed with the dll name. Do the user
534
// a favor and see if this is a symbol in jvm.dll or java.dll.
535
addr = lookup(null, "jvm!" + symbol);
536
if (addr == null) {
537
addr = lookup(null, "java!" + symbol);
538
}
539
}
540
if (addr == null) {
541
return null;
542
}
543
var builder = new StringBuilder(addr.toString());
544
var cdbg = getCDebugger();
545
var loadObject = cdbg.loadObjectContainingPC(addr);
546
// Print the shared library path and the offset of the symbol
547
if (loadObject != null) {
548
builder.append(": ").append(loadObject.getName());
549
long diff = addr.minus(loadObject.getBase());
550
if (diff != 0L) {
551
builder.append(" + 0x").append(Long.toHexString(diff));
552
}
553
}
554
return builder.toString();
555
}
556
557
public long getJBooleanSize() {
558
return jbooleanSize;
559
}
560
561
public long getJByteSize() {
562
return jbyteSize;
563
}
564
565
public long getJCharSize() {
566
return jcharSize;
567
}
568
569
public long getJDoubleSize() {
570
return jdoubleSize;
571
}
572
573
public long getJFloatSize() {
574
return jfloatSize;
575
}
576
577
public long getJIntSize() {
578
return jintSize;
579
}
580
581
public long getJLongSize() {
582
return jlongSize;
583
}
584
585
public long getJShortSize() {
586
return jshortSize;
587
}
588
589
public long getHeapOopSize() {
590
return heapOopSize;
591
}
592
593
public long getNarrowOopBase() {
594
return narrowOopBase;
595
}
596
public int getNarrowOopShift() {
597
return narrowOopShift;
598
}
599
600
public long getKlassPtrSize() {
601
return klassPtrSize;
602
}
603
604
public long getNarrowKlassBase() {
605
return narrowKlassBase;
606
}
607
public int getNarrowKlassShift() {
608
return narrowKlassShift;
609
}
610
}
611
612