Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/sde/InstallSDE.java
51715 views
1
/*
2
* Copyright (c) 2007, 2019, 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
package nsk.share.jdi.sde;
24
25
import java.io.File;
26
import java.io.FileInputStream;
27
import java.io.FileOutputStream;
28
import java.io.IOException;
29
import java.io.InputStream;
30
import java.io.UnsupportedEncodingException;
31
32
import nsk.share.Consts;
33
34
/*
35
* Inserts in class file 'SourceDebugExtension' attribute based on input .SMAP file.
36
*/
37
public class InstallSDE {
38
static final String nameSDE = "SourceDebugExtension";
39
40
private byte[] orig;
41
42
private byte[] sdeAttr;
43
44
private byte[] gen;
45
46
private int origPos = 0;
47
48
private int genPos = 0;
49
50
private int sdeIndex;
51
52
public static void install(File inClassFile, File smapFile, File outClassFile, boolean verbose) throws IOException {
53
new InstallSDE(inClassFile, smapFile, outClassFile, verbose);
54
}
55
56
public static void install(byte[] aOrig, byte[] aSdeAttr, File outClassFile, boolean verbose) throws IOException {
57
new InstallSDE(aOrig, aSdeAttr, outClassFile, verbose);
58
}
59
60
public static void install(File inOutClassFile, File attrFile, boolean verbose) throws IOException {
61
File tmpFile = new File(inOutClassFile.getPath() + "tmp-out");
62
File tmpInOutClassFile = new File(inOutClassFile.getPath() + "tmp-in");
63
64
// Workaround delayed file deletes on Windows using a tmp file name
65
if (!inOutClassFile.renameTo(tmpInOutClassFile)) {
66
throw new IOException("inOutClassFile.renameTo(tmpInOutClassFile) failed");
67
}
68
69
new InstallSDE(tmpInOutClassFile, attrFile, tmpFile, verbose);
70
71
if (!tmpInOutClassFile.delete()) {
72
throw new IOException("tmpInOutClassFile.delete() failed");
73
}
74
if (!tmpFile.renameTo(inOutClassFile)) {
75
throw new IOException("tmpFile.renameTo(inOutClassFile) failed");
76
}
77
}
78
79
private static void abort(String msg) {
80
System.err.println(msg);
81
System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_FAILED);
82
}
83
84
private InstallSDE(File inClassFile, File attrFile, File outClassFile, boolean verbose) throws IOException {
85
if (!inClassFile.exists()) {
86
abort("no such file: " + inClassFile);
87
}
88
if (!attrFile.exists()) {
89
abort("no such file: " + attrFile);
90
}
91
92
// get the bytes
93
orig = readWhole(inClassFile);
94
sdeAttr = readWhole(attrFile);
95
gen = new byte[orig.length + sdeAttr.length + 100];
96
97
// do it
98
addSDE(verbose);
99
100
// write result
101
FileOutputStream outStream = new FileOutputStream(outClassFile);
102
outStream.write(gen, 0, genPos);
103
outStream.close();
104
}
105
106
private InstallSDE(byte[] aOrig, byte[] aSdeAttr, File outClassFile, boolean verbose) throws IOException {
107
orig = aOrig;
108
sdeAttr = aSdeAttr;
109
gen = new byte[orig.length + sdeAttr.length + 100];
110
111
// do it
112
addSDE(verbose);
113
114
// write result
115
FileOutputStream outStream = new FileOutputStream(outClassFile);
116
outStream.write(gen, 0, genPos);
117
outStream.close();
118
}
119
120
private byte[] readWhole(File input) throws IOException {
121
FileInputStream inStream = new FileInputStream(input);
122
try {
123
return readWhole(inStream, (int) input.length());
124
} finally {
125
inStream.close();
126
}
127
}
128
129
private byte[] readWhole(InputStream inStream, int len) throws IOException {
130
byte[] bytes = new byte[len];
131
132
if (inStream.read(bytes, 0, len) != len) {
133
abort("expected size: " + len);
134
}
135
136
return bytes;
137
}
138
139
private void addSDE(boolean verbose) throws UnsupportedEncodingException {
140
copy(4 + 2 + 2); // magic min/maj version
141
int constantPoolCountPos = genPos;
142
int constantPoolCount = readU2();
143
writeU2(constantPoolCount);
144
// copy old constant pool return index of SDE symbol, if found
145
sdeIndex = copyConstantPool(constantPoolCount, verbose);
146
if (sdeIndex < 0) {
147
// if "SourceDebugExtension" symbol not there add it
148
writeUtf8ForSDE();
149
150
// increment the countantPoolCount
151
sdeIndex = constantPoolCount;
152
++constantPoolCount;
153
randomAccessWriteU2(constantPoolCountPos, constantPoolCount);
154
155
if (verbose) {
156
System.out.println("SourceDebugExtension not found, installed at: " + sdeIndex);
157
}
158
} else {
159
if (verbose) {
160
System.out.println("SourceDebugExtension found at: " + sdeIndex);
161
}
162
}
163
copy(2 + 2 + 2); // access, this, super
164
int interfaceCount = readU2();
165
writeU2(interfaceCount);
166
if (verbose) {
167
System.out.println("interfaceCount: " + interfaceCount);
168
}
169
copy(interfaceCount * 2);
170
copyMembers(verbose); // fields
171
copyMembers(verbose); // methods
172
int attrCountPos = genPos;
173
int attrCount = readU2();
174
writeU2(attrCount);
175
if (verbose) {
176
System.out.println("class attrCount: " + attrCount);
177
}
178
// copy the class attributes, return true if SDE attr found (not copied)
179
if (!copyAttrs(attrCount, verbose)) {
180
// we will be adding SDE and it isn't already counted
181
++attrCount;
182
randomAccessWriteU2(attrCountPos, attrCount);
183
if (verbose) {
184
System.out.println("class attrCount incremented");
185
}
186
}
187
writeAttrForSDE(sdeIndex);
188
}
189
190
private void copyMembers(boolean verbose) {
191
int count = readU2();
192
writeU2(count);
193
if (verbose) {
194
System.out.println("members count: " + count);
195
}
196
for (int i = 0; i < count; ++i) {
197
copy(6); // access, name, descriptor
198
int attrCount = readU2();
199
writeU2(attrCount);
200
if (verbose) {
201
System.out.println("member attr count: " + attrCount);
202
}
203
copyAttrs(attrCount, verbose);
204
}
205
}
206
207
private boolean copyAttrs(int attrCount, boolean verbose) {
208
boolean sdeFound = false;
209
for (int i = 0; i < attrCount; ++i) {
210
int nameIndex = readU2();
211
// don't write old SDE
212
if (nameIndex == sdeIndex) {
213
sdeFound = true;
214
if (verbose) {
215
System.out.println("SDE attr found");
216
}
217
} else {
218
writeU2(nameIndex); // name
219
int len = readU4();
220
writeU4(len);
221
copy(len);
222
if (verbose) {
223
System.out.println("attr len: " + len);
224
}
225
}
226
}
227
return sdeFound;
228
}
229
230
private void writeAttrForSDE(int index) {
231
writeU2(index);
232
writeU4(sdeAttr.length);
233
for (int i = 0; i < sdeAttr.length; ++i) {
234
writeU1(sdeAttr[i]);
235
}
236
}
237
238
private void randomAccessWriteU2(int pos, int val) {
239
int savePos = genPos;
240
genPos = pos;
241
writeU2(val);
242
genPos = savePos;
243
}
244
245
private int readU1() {
246
return ((int) orig[origPos++]) & 0xFF;
247
}
248
249
private int readU2() {
250
int res = readU1();
251
return (res << 8) + readU1();
252
}
253
254
private int readU4() {
255
int res = readU2();
256
return (res << 16) + readU2();
257
}
258
259
private void writeU1(int val) {
260
gen[genPos++] = (byte) val;
261
}
262
263
private void writeU2(int val) {
264
writeU1(val >> 8);
265
writeU1(val & 0xFF);
266
}
267
268
private void writeU4(int val) {
269
writeU2(val >> 16);
270
writeU2(val & 0xFFFF);
271
}
272
273
private void copy(int count) {
274
for (int i = 0; i < count; ++i) {
275
gen[genPos++] = orig[origPos++];
276
}
277
}
278
279
private byte[] readBytes(int count) {
280
byte[] bytes = new byte[count];
281
for (int i = 0; i < count; ++i) {
282
bytes[i] = orig[origPos++];
283
}
284
return bytes;
285
}
286
287
private void writeBytes(byte[] bytes) {
288
for (int i = 0; i < bytes.length; ++i) {
289
gen[genPos++] = bytes[i];
290
}
291
}
292
293
private int copyConstantPool(int constantPoolCount, boolean verbose) throws UnsupportedEncodingException {
294
int sdeIndex = -1;
295
// copy const pool index zero not in class file
296
if ( verbose )
297
System.out.println("cp count=" + constantPoolCount);
298
for (int i = 1; i < constantPoolCount; ++i) {
299
int tag = readU1();
300
writeU1(tag);
301
if ( verbose )
302
System.out.println(i + ": tag=" + tag);
303
switch (tag) {
304
case 7: // Class
305
case 8: // String
306
case 16: // MethodType
307
copy(2);
308
break;
309
case 15: // MethodHandle
310
copy(3);
311
break;
312
case 9: // Field
313
case 10: // Method
314
case 11: // InterfaceMethod
315
case 3: // Integer
316
case 4: // Float
317
case 12: // NameAndType
318
case 17: // InvokeDynamic_17 (will go away)
319
case 18: // InokeDynamic
320
copy(4);
321
break;
322
case 5: // Long
323
case 6: // Double
324
copy(8);
325
++i;
326
break;
327
case 1: // Utf8
328
int len = readU2();
329
writeU2(len);
330
byte[] utf8 = readBytes(len);
331
String str = new String(utf8, "UTF-8");
332
if (verbose) {
333
System.out.println(i + " read class attr -- '" + str + "'");
334
}
335
if (str.equals(nameSDE)) {
336
sdeIndex = i;
337
}
338
writeBytes(utf8);
339
break;
340
default:
341
abort("unexpected tag: " + tag);
342
break;
343
}
344
}
345
return sdeIndex;
346
}
347
348
private void writeUtf8ForSDE() {
349
int len = nameSDE.length();
350
writeU1(1); // Utf8 tag
351
writeU2(len);
352
for (int i = 0; i < len; ++i) {
353
writeU1(nameSDE.charAt(i));
354
}
355
}
356
}
357
358