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