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