Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ClassFileLoadHook/classfloadhk005/classfloadhk005.cpp
40955 views
1
/*
2
* Copyright (c) 2003, 2018, 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
#include <string.h>
25
#include "jvmti.h"
26
#include "agent_common.h"
27
#include "jni_tools.h"
28
#include "jvmti_tools.h"
29
30
extern "C" {
31
32
/* ============================================================================= */
33
34
/* scaffold objects */
35
static jlong timeout = 0;
36
37
/* constant names */
38
#define DEBUGEE_CLASS_NAME "nsk/jvmti/ClassFileLoadHook/classfloadhk005"
39
#define TESTED_CLASS_NAME "nsk/jvmti/ClassFileLoadHook/classfloadhk005r"
40
#define TESTED_CLASS_SIG "L" TESTED_CLASS_NAME ";"
41
42
#define BYTECODE_FIELD_SIG "[B"
43
#define NEW_BYTECODE_FIELD_NAME "newClassBytes"
44
45
static jint newClassSize = 0;
46
static unsigned char* newClassBytes = NULL;
47
48
static volatile int eventsCount = 0;
49
50
/* ============================================================================= */
51
52
/** Check (strictly or not) if bytecode has expected size and bytes or complain an error. */
53
static int checkBytecode(const char kind[], jint size, const unsigned char bytes[],
54
jint expectedSize, const unsigned char expectedBytes[],
55
int strict) {
56
int success = NSK_TRUE;
57
58
NSK_DISPLAY3("Check %s bytecode: 0x%p:%d\n", kind, (void*)bytes, (int)size);
59
if (nsk_getVerboseMode()) {
60
nsk_printHexBytes(" ", 16, size, bytes);
61
}
62
63
if (bytes == NULL) {
64
NSK_COMPLAIN2("Unexpected NULL pointer to %s bytecode in CLASS_FILE_LOAD_HOOK: 0x%p\n",
65
kind, (void*)bytes);
66
return NSK_FALSE;
67
}
68
69
if (size <= 0) {
70
NSK_COMPLAIN2("Unexpected zero size of %s bytecode in CLASS_FILE_LOAD_HOOK: %d\n",
71
kind, (int)size);
72
return NSK_FALSE;
73
}
74
75
if (strict) {
76
if (size != expectedSize) {
77
NSK_COMPLAIN3("Unexpected size of %s bytecode in CLASS_FILE_LOAD_HOOK:\n"
78
"# got size: %d\n"
79
"# expected: %d\n",
80
kind, (int)size, (int)expectedSize);
81
success = NSK_FALSE;
82
} else {
83
jint different = 0;
84
jint i;
85
86
for (i = 0; i < size; i++) {
87
if (bytes[i] != expectedBytes[i]) {
88
different++;
89
}
90
}
91
if (different > 0) {
92
NSK_COMPLAIN2("Unexpected bytes in %s bytecode in CLASS_FILE_LOAD_HOOK:\n"
93
"# different bytes: %d\n"
94
"# total bytes: %d\n",
95
(int)different, (int)size);
96
success = NSK_FALSE;
97
}
98
}
99
100
if (!success) {
101
NSK_COMPLAIN2("Got %s bytecode is not equal to expected bytecode: %d bytes\n",
102
kind, expectedSize);
103
if (nsk_getVerboseMode()) {
104
nsk_printHexBytes(" ", 16, expectedSize, expectedBytes);
105
}
106
} else {
107
NSK_DISPLAY1("All %s bytecode is equal to expected one\n", kind);
108
}
109
}
110
111
return success;
112
}
113
114
/** Get classfile bytecode from a static field of given class. */
115
static int getBytecode(jvmtiEnv* jvmti, JNIEnv* jni, jclass cls,
116
const char fieldName[], const char fieldSig[],
117
jint* size, unsigned char* *bytes) {
118
119
jfieldID fieldID = NULL;
120
jbyteArray array = NULL;
121
jbyte* elements;
122
int i;
123
124
NSK_DISPLAY1("Find static field: %s\n", fieldName);
125
if (!NSK_JNI_VERIFY(jni, (fieldID =
126
jni->GetStaticFieldID(cls, fieldName, fieldSig)) != NULL)) {
127
nsk_jvmti_setFailStatus();
128
return NSK_FALSE;
129
}
130
NSK_DISPLAY1(" ... got fieldID: 0x%p\n", (void*)fieldID);
131
132
NSK_DISPLAY1("Get classfile bytes array from static field: %s\n", fieldName);
133
if (!NSK_JNI_VERIFY(jni, (array = (jbyteArray)
134
jni->GetStaticObjectField(cls, fieldID)) != NULL)) {
135
nsk_jvmti_setFailStatus();
136
return NSK_FALSE;
137
}
138
NSK_DISPLAY1(" ... got array object: 0x%p\n", (void*)array);
139
140
if (!NSK_JNI_VERIFY(jni, (*size = jni->GetArrayLength(array)) > 0)) {
141
nsk_jvmti_setFailStatus();
142
return NSK_FALSE;
143
}
144
NSK_DISPLAY1(" ... got array size: %d bytes\n", (int)*size);
145
146
{
147
jboolean isCopy;
148
if (!NSK_JNI_VERIFY(jni, (elements = jni->GetByteArrayElements(array, &isCopy)) != NULL)) {
149
nsk_jvmti_setFailStatus();
150
return NSK_FALSE;
151
}
152
}
153
NSK_DISPLAY1(" ... got elements list: 0x%p\n", (void*)elements);
154
155
if (!NSK_JVMTI_VERIFY(jvmti->Allocate(*size, bytes))) {
156
nsk_jvmti_setFailStatus();
157
return NSK_FALSE;
158
}
159
NSK_DISPLAY1(" ... created bytes array: 0x%p\n", (void*)*bytes);
160
161
for (i = 0; i < *size; i++) {
162
(*bytes)[i] = (unsigned char)elements[i];
163
}
164
NSK_DISPLAY1(" ... copied bytecode: %d bytes\n", (int)*size);
165
166
NSK_DISPLAY1("Release elements list: 0x%p\n", (void*)elements);
167
NSK_TRACE(jni->ReleaseByteArrayElements(array, elements, JNI_ABORT));
168
NSK_DISPLAY0(" ... released\n");
169
170
return NSK_TRUE;
171
}
172
173
/* ============================================================================= */
174
175
/** Agent algorithm. */
176
static void JNICALL
177
agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
178
NSK_DISPLAY0("Wait for debuggee to become ready\n");
179
if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
180
return;
181
182
/* perform testing */
183
{
184
NSK_DISPLAY0(">>> Obtain classloader and instrumented bytecode of tested class\n");
185
{
186
jclass debugeeClass = NULL;
187
188
NSK_DISPLAY1("Find debugee class: %s\n", DEBUGEE_CLASS_NAME);
189
if (!NSK_JNI_VERIFY(jni, (debugeeClass =
190
jni->FindClass(DEBUGEE_CLASS_NAME)) != NULL)) {
191
nsk_jvmti_setFailStatus();
192
return;
193
}
194
NSK_DISPLAY1(" ... found class: 0x%p\n", (void*)debugeeClass);
195
196
if (!NSK_VERIFY(getBytecode(jvmti, jni, debugeeClass,
197
NEW_BYTECODE_FIELD_NAME,
198
BYTECODE_FIELD_SIG,
199
&newClassSize, &newClassBytes)))
200
return;
201
}
202
203
NSK_DISPLAY0(">>> Testcase #1: Load tested class and replace bytecode in CLASS_FILE_LOAD_HOOK event\n");
204
{
205
jvmtiEvent event = JVMTI_EVENT_CLASS_FILE_LOAD_HOOK;
206
207
NSK_DISPLAY1("Enable event: %s\n", "CLASS_FILE_LOAD_HOOK");
208
if (!NSK_VERIFY(nsk_jvmti_enableEvents(JVMTI_ENABLE, 1, &event, NULL)))
209
return;
210
NSK_DISPLAY0(" ... event enabled\n");
211
212
NSK_DISPLAY0("Let debugee to load tested class\n");
213
if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
214
return;
215
NSK_DISPLAY0("Wait for tested class to be loaded\n");
216
if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
217
return;
218
219
NSK_DISPLAY1("Disable event: %s\n", "CLASS_FILE_LOAD_HOOK");
220
if (NSK_VERIFY(nsk_jvmti_enableEvents(JVMTI_DISABLE, 1, &event, NULL))) {
221
NSK_DISPLAY0(" ... event disabled\n");
222
}
223
224
NSK_DISPLAY1("Check if event was received: %s\n", "CLASS_FILE_LOAD_HOOK");
225
if (eventsCount != 1) {
226
NSK_COMPLAIN3("Unexpected number of %s events for tested class:\n"
227
"# got events: %d\n"
228
"# expected: %d\n",
229
"CLASS_FILE_LOAD_HOOK",
230
eventsCount, 1);
231
nsk_jvmti_setFailStatus();
232
} else {
233
NSK_DISPLAY1(" ... received: %d events\n", eventsCount);
234
}
235
}
236
237
NSK_DISPLAY0(">>> Clean used data\n");
238
{
239
}
240
}
241
242
NSK_DISPLAY0("Let debugee to finish\n");
243
if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
244
return;
245
}
246
247
/* ============================================================================= */
248
249
/** Callback for CLASS_FILE_LOAD_HOOK event **/
250
static void JNICALL
251
callbackClassFileLoadHook(jvmtiEnv *jvmti, JNIEnv *jni,
252
jclass class_being_redefined,
253
jobject loader, const char* name, jobject protection_domain,
254
jint class_data_len, const unsigned char* class_data,
255
jint *new_class_data_len, unsigned char** new_class_data) {
256
257
NSK_DISPLAY5(" <CLASS_FILE_LOAD_HOOK>: name: %s, loader: 0x%p, redefined: 0x%p, bytecode: 0x%p:%d\n",
258
nsk_null_string(name), (void*)loader, (void*)class_being_redefined,
259
(void*)class_data, (int)class_data_len);
260
261
if (name != NULL && (strcmp(name, TESTED_CLASS_NAME) == 0)) {
262
NSK_DISPLAY1("SUCCESS! CLASS_FILE_LOAD_HOOK for tested class: %s\n", TESTED_CLASS_NAME);
263
eventsCount++;
264
265
NSK_DISPLAY2("Received original bytecode of tested class: 0x%p:%d\n",
266
(void*)class_data, (int)class_data_len);
267
if (nsk_getVerboseMode()) {
268
nsk_printHexBytes(" ", 16, class_data_len, class_data);
269
}
270
271
NSK_DISPLAY1("Check pointer to new_class_data_len: 0x%p\n", (void*)new_class_data_len);
272
if (new_class_data_len == NULL) {
273
NSK_COMPLAIN1("NULL new_class_data_len pointer passed to CLASS_FILE_LOAD_HOOK: 0x%p\n",
274
(void*)new_class_data_len);
275
nsk_jvmti_setFailStatus();
276
}
277
278
NSK_DISPLAY1("Check pointer to new_class_data: 0x%p\n", (void*)new_class_data);
279
if (new_class_data == NULL) {
280
NSK_COMPLAIN1("NULL new_class_data pointer passed to CLASS_FILE_LOAD_HOOK: 0x%p\n",
281
(void*)new_class_data);
282
nsk_jvmti_setFailStatus();
283
}
284
285
if (new_class_data_len != NULL && new_class_data != NULL) {
286
NSK_DISPLAY2("Replace with instrumented bytecode: 0x%p:%d\n",
287
(void*)newClassBytes, (int)newClassSize);
288
if (nsk_getVerboseMode()) {
289
nsk_printHexBytes(" ", 16, newClassSize, newClassBytes);
290
}
291
292
*new_class_data_len = newClassSize;
293
*new_class_data = newClassBytes;
294
}
295
}
296
}
297
298
/* ============================================================================= */
299
300
/** Agent library initialization. */
301
#ifdef STATIC_BUILD
302
JNIEXPORT jint JNICALL Agent_OnLoad_classfloadhk005(JavaVM *jvm, char *options, void *reserved) {
303
return Agent_Initialize(jvm, options, reserved);
304
}
305
JNIEXPORT jint JNICALL Agent_OnAttach_classfloadhk005(JavaVM *jvm, char *options, void *reserved) {
306
return Agent_Initialize(jvm, options, reserved);
307
}
308
JNIEXPORT jint JNI_OnLoad_classfloadhk005(JavaVM *jvm, char *options, void *reserved) {
309
return JNI_VERSION_1_8;
310
}
311
#endif
312
jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
313
jvmtiEnv* jvmti = NULL;
314
315
/* init framework and parse options */
316
if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
317
return JNI_ERR;
318
319
timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
320
321
/* create JVMTI environment */
322
if (!NSK_VERIFY((jvmti =
323
nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
324
return JNI_ERR;
325
326
NSK_DISPLAY1("Add required capability: %s\n", "can_generate_eraly_class_hook_events");
327
{
328
jvmtiCapabilities caps;
329
330
memset(&caps, 0, sizeof(caps));
331
caps.can_generate_all_class_hook_events = 1;
332
if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) {
333
return JNI_ERR;
334
}
335
}
336
NSK_DISPLAY0(" ... added\n");
337
338
NSK_DISPLAY1("Set callback for event: %s\n", "CLASS_FILE_LOAD_HOOK");
339
{
340
jvmtiEventCallbacks callbacks;
341
jint size = (jint)sizeof(callbacks);
342
343
memset(&callbacks, 0, sizeof(callbacks));
344
callbacks.ClassFileLoadHook = callbackClassFileLoadHook;
345
if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, size))) {
346
return JNI_ERR;
347
}
348
}
349
NSK_DISPLAY0(" ... set\n");
350
351
/* register agent proc and arg */
352
if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
353
return JNI_ERR;
354
355
return JNI_OK;
356
}
357
358
/* ============================================================================= */
359
360
}
361
362