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