Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions/libAllowedFunctions.c
41155 views
1
/*
2
* Copyright (c) 2017, 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 <stdint.h>
25
#include <stdio.h>
26
#include <stdlib.h>
27
#include <string.h>
28
#include "jvmti.h"
29
30
#ifdef __cplusplus
31
extern "C" {
32
#endif
33
34
#ifndef JNI_ENV_ARG
35
36
#ifdef __cplusplus
37
#define JNI_ENV_ARG(x, y) y
38
#define JNI_ENV_PTR(x) x
39
#else
40
#define JNI_ENV_ARG(x,y) x, y
41
#define JNI_ENV_PTR(x) (*x)
42
#endif
43
44
#endif
45
46
#define PASSED 0
47
#define FAILED 2
48
49
static jint result = PASSED;
50
51
static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved);
52
53
JNIEXPORT
54
jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
55
return Agent_Initialize(jvm, options, reserved);
56
}
57
58
JNIEXPORT
59
jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {
60
return Agent_Initialize(jvm, options, reserved);
61
}
62
63
JNIEXPORT
64
jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
65
return JNI_VERSION_9;
66
}
67
68
static void check_jvmti_error(jvmtiEnv *jvmti, char* fname, jvmtiError err) {
69
if (err != JVMTI_ERROR_NONE) {
70
printf(" ## %s error: %d\n", fname, err);
71
exit(err);
72
}
73
}
74
75
static void deallocate(jvmtiEnv *jvmti, char* mem) {
76
jvmtiError err = (*jvmti)->Deallocate(jvmti, (unsigned char*)mem);
77
check_jvmti_error(jvmti, "Deallocate", err);
78
}
79
80
static void get_phase(jvmtiEnv *jvmti, jvmtiPhase *phase_ptr) {
81
jvmtiError err = (*jvmti)->GetPhase(jvmti, phase_ptr);
82
check_jvmti_error(jvmti, "GetPhase", err);
83
}
84
85
static jthread get_cur_thread(jvmtiEnv *jvmti) {
86
jthread cur_thread = NULL;
87
jvmtiError err = (*jvmti)->GetCurrentThread(jvmti, &cur_thread);
88
check_jvmti_error(jvmti, "GetCurrentThread", err);
89
return cur_thread;
90
}
91
92
static intptr_t get_thread_local(jvmtiEnv *jvmti, jthread thread) {
93
void *val = NULL;
94
jvmtiError err = (*jvmti)->GetThreadLocalStorage(jvmti, thread, &val);
95
check_jvmti_error(jvmti, "GetThreadLocalStorage", err);
96
return (intptr_t)val;
97
}
98
99
static void set_thread_local(jvmtiEnv *jvmti, jthread thread, intptr_t x) {
100
void *val = (void*)x;
101
jvmtiError err = (*jvmti)->SetThreadLocalStorage(jvmti, thread, val);
102
check_jvmti_error(jvmti, "SetThreadLocalStorage", err);
103
}
104
105
static void print_class_status(jvmtiEnv *jvmti, jclass klass) {
106
jint status = 0;
107
jvmtiError err = (*jvmti)->GetClassStatus(jvmti, klass, &status);
108
109
check_jvmti_error(jvmti, "GetClassStatus", err);
110
// This function is only used in a ClassPrepare event context
111
if ((status & JVMTI_CLASS_STATUS_VERIFIED) == 0 ||
112
(status & JVMTI_CLASS_STATUS_PREPARED) == 0 ||
113
(status & JVMTI_CLASS_STATUS_INITIALIZED) != 0 ||
114
(status & JVMTI_CLASS_STATUS_ERROR) != 0) {
115
printf(" ## Error: unexpected class status: 0x%08x\n", status);
116
}
117
printf(" Class status: 0x%08x\n", status);
118
}
119
120
static void print_class_signature(jvmtiEnv *jvmti, jclass klass) {
121
char* name = NULL;
122
jvmtiError err = (*jvmti)->GetClassSignature(jvmti, klass, &name, NULL);
123
124
check_jvmti_error(jvmti, "GetClassSignature", err);
125
if (name != NULL) {
126
printf(" class: '%s'\n", name);
127
deallocate(jvmti, name);
128
}
129
}
130
131
static void print_class_source_file_name(jvmtiEnv *jvmti, jclass klass) {
132
char* name = NULL;
133
jvmtiError err = (*jvmti)->GetSourceFileName(jvmti, klass, &name);
134
135
check_jvmti_error(jvmti, "GetSourceFileName", err);
136
if (name != NULL) {
137
printf(" Class source file name: '%s'\n", name);
138
deallocate(jvmti, name);
139
}
140
}
141
142
static void print_class_info(jvmtiEnv *jvmti, jclass klass) {
143
jint mods = 0;
144
jboolean is_interface = JNI_FALSE;
145
jboolean is_array = JNI_FALSE;
146
jboolean is_modifiable = JNI_FALSE;
147
jvmtiError err = (*jvmti)->GetClassModifiers(jvmti, klass, &mods);
148
149
check_jvmti_error(jvmti, "GetClassModifiers", err);
150
printf(" Class modifiers: 0x%08x\n", mods);
151
152
err = (*jvmti)->IsInterface(jvmti, klass, &is_interface);
153
check_jvmti_error(jvmti, "IsInterface", err);
154
printf(" Class is interface: %d\n", is_interface);
155
156
err = (*jvmti)->IsArrayClass(jvmti, klass, &is_array);
157
check_jvmti_error(jvmti, "IsArrayClass", err);
158
printf(" Class is array: %d\n", is_array);
159
160
err = (*jvmti)->IsModifiableClass(jvmti, klass, &is_modifiable);
161
check_jvmti_error(jvmti, "IsModifiableClass", err);
162
printf(" Class is modifiable: %d\n", is_modifiable);
163
}
164
165
static jint get_class_methods(jvmtiEnv *jvmti, jclass klass, jmethodID** methods_ptr) {
166
jint count = 0;
167
jvmtiError err = (*jvmti)->GetClassMethods(jvmti, klass, &count, methods_ptr);
168
check_jvmti_error(jvmti, "GetClassMethods", err);
169
return count;
170
}
171
172
static jint get_class_fields(jvmtiEnv *jvmti, jclass klass, jfieldID** fields_ptr) {
173
jint count = 0;
174
jvmtiError err = (*jvmti)->GetClassFields(jvmti, klass, &count, fields_ptr);
175
check_jvmti_error(jvmti, "GetClassFields", err);
176
return count;
177
}
178
179
static void print_method_name_sign(jvmtiEnv *jvmti, jmethodID method) {
180
char* name = NULL;
181
char* sign = NULL;
182
jvmtiError err = (*jvmti)->GetMethodName(jvmti, method, &name, &sign, NULL);
183
184
check_jvmti_error(jvmti, "GetMethodName", err);
185
printf(" Method: %s%s\n", name, sign);
186
deallocate(jvmti, name);
187
deallocate(jvmti, sign);
188
}
189
190
static void print_method_declaring_class(jvmtiEnv *jvmti, jmethodID method) {
191
jclass dclass = NULL;
192
jvmtiError err = (*jvmti)->GetMethodDeclaringClass(jvmti, method, &dclass);
193
194
check_jvmti_error(jvmti, "GetMethodDeclaringClass", err);
195
printf(" Method declaring");
196
print_class_signature(jvmti, dclass);
197
}
198
199
static void print_method_info(jvmtiEnv *jvmti, jmethodID method) {
200
jint mods = 0;
201
jint locals_max = 0;
202
jint args_size = 0;
203
jboolean is_native = JNI_FALSE;
204
jboolean is_synth = JNI_FALSE;
205
jboolean is_obsolete = JNI_FALSE;
206
jvmtiError err = (*jvmti)->GetMethodModifiers(jvmti, method, &mods);
207
208
check_jvmti_error(jvmti, "GetMethodModifiers", err);
209
printf(" Method modifiers: 0x%08x\n", mods);
210
211
err = (*jvmti)->IsMethodNative(jvmti, method, &is_native);
212
check_jvmti_error(jvmti, "IsMethodNative", err);
213
printf(" Method is native: %d\n", is_native);
214
215
if (is_native == JNI_FALSE) {
216
err = (*jvmti)->GetMaxLocals(jvmti, method, &locals_max);
217
check_jvmti_error(jvmti, "GetMaxLocals", err);
218
printf(" Method max locals: %d\n", locals_max);
219
220
err = (*jvmti)->GetArgumentsSize(jvmti, method, &args_size);
221
check_jvmti_error(jvmti, "GetArgumentsSize", err);
222
printf(" Method arguments size: %d\n", args_size);
223
}
224
225
err = (*jvmti)->IsMethodSynthetic(jvmti, method, &is_synth);
226
check_jvmti_error(jvmti, "IsMethodSynthetic", err);
227
printf(" Method is synthetic: %d\n", is_synth);
228
229
err = (*jvmti)->IsMethodObsolete(jvmti, method, &is_obsolete);
230
check_jvmti_error(jvmti, "IsMethodObsolete", err);
231
printf(" Method is obsolete: %d\n", is_obsolete);
232
}
233
234
static void test_method_functions(jvmtiEnv *jvmti, jmethodID method) {
235
print_method_name_sign(jvmti, method);
236
print_method_declaring_class(jvmti, method);
237
print_method_info(jvmti, method);
238
}
239
240
static void print_field_name_sign(jvmtiEnv *jvmti, jclass klass, jfieldID field) {
241
char* name = NULL;
242
char* sign = NULL;
243
jvmtiError err = (*jvmti)->GetFieldName(jvmti, klass, field, &name, &sign, NULL);
244
245
check_jvmti_error(jvmti, "GetFieldName", err);
246
printf(" Field: %s %s\n", sign, name);
247
deallocate(jvmti, name);
248
deallocate(jvmti, sign);
249
}
250
251
static void print_field_declaring_class(jvmtiEnv *jvmti, jclass klass, jfieldID field) {
252
jclass dclass = NULL;
253
jvmtiError err = (*jvmti)->GetFieldDeclaringClass(jvmti, klass, field, &dclass);
254
255
check_jvmti_error(jvmti, "GetFieldDeclaringClass", err);
256
printf(" Field declaring");
257
print_class_signature(jvmti, dclass);
258
}
259
260
static void print_field_info(jvmtiEnv *jvmti, jclass klass, jfieldID field) {
261
jint mods = 0;
262
jboolean is_synth = JNI_FALSE;
263
jvmtiError err = (*jvmti)->GetFieldModifiers(jvmti, klass, field, &mods);
264
265
check_jvmti_error(jvmti, "GetFieldModifiers", err);
266
printf(" Field modifiers: 0x%08x\n", mods);
267
268
err = (*jvmti)->IsFieldSynthetic(jvmti, klass, field, &is_synth);
269
check_jvmti_error(jvmti, "IsFieldSynthetic", err);
270
printf(" Field is synthetic: %d\n", is_synth);
271
}
272
273
static void test_field_functions(jvmtiEnv *jvmti, jclass klass, jfieldID field) {
274
print_field_name_sign(jvmti, klass, field);
275
print_field_declaring_class(jvmti, klass, field);
276
print_field_info(jvmti, klass, field);
277
}
278
279
static void test_class_functions(jvmtiEnv *jvmti, JNIEnv *env, jthread thread, jclass klass) {
280
jint count = 0;
281
jint idx = 0;
282
jmethodID* methods = NULL;
283
jfieldID* fields = NULL;
284
285
print_class_signature(jvmti, klass);
286
print_class_status(jvmti, klass);
287
print_class_source_file_name(jvmti, klass);
288
print_class_info(jvmti, klass);
289
290
count = get_class_methods(jvmti, klass, &methods);
291
for (idx = 0; idx < count; idx++) {
292
test_method_functions(jvmti, methods[idx]);
293
}
294
if (methods != NULL) {
295
deallocate(jvmti, (char*)methods);
296
}
297
count = get_class_fields(jvmti, klass, &fields);
298
for (idx = 0; idx < count; idx++) {
299
test_field_functions(jvmti, klass, fields[idx]);
300
}
301
if (fields != NULL) {
302
deallocate(jvmti, (char*)fields);
303
}
304
}
305
306
static void JNICALL
307
VMStart(jvmtiEnv *jvmti, JNIEnv* jni) {
308
jvmtiPhase phase;
309
310
printf("VMStart event\n");
311
get_phase(jvmti, &phase);
312
if (phase != JVMTI_PHASE_START && phase != JVMTI_PHASE_LIVE) {
313
printf(" ## Error: unexpected phase: %d, expected: %d or %d\n",
314
phase, JVMTI_PHASE_START, JVMTI_PHASE_LIVE);
315
result = FAILED;
316
}
317
}
318
319
static void JNICALL
320
VMInit(jvmtiEnv *jvmti, JNIEnv* jnii, jthread thread) {
321
jvmtiPhase phase;
322
323
printf("VMInit event\n");
324
get_phase(jvmti, &phase);
325
if (phase != JVMTI_PHASE_LIVE) {
326
printf(" ## Error: unexpected phase: %d, expected: %d\n",
327
phase, JVMTI_PHASE_LIVE);
328
result = FAILED;
329
}
330
}
331
332
static void JNICALL
333
ClassPrepare(jvmtiEnv *jvmti, JNIEnv *env, jthread thread, jclass klass) {
334
static const jint EVENTS_LIMIT = 2;
335
static jint event_no = 0;
336
jthread cur_thread = get_cur_thread(jvmti);
337
jvmtiPhase phase;
338
intptr_t exp_val = 777;
339
intptr_t act_val;
340
341
get_phase(jvmti, &phase);
342
if (phase != JVMTI_PHASE_START && phase != JVMTI_PHASE_LIVE) {
343
printf(" ## Error: unexpected phase: %d, expected: %d or %d\n",
344
phase, JVMTI_PHASE_START, JVMTI_PHASE_LIVE);
345
return;
346
}
347
if (phase == JVMTI_PHASE_START && event_no < EVENTS_LIMIT) {
348
printf("\nClassPrepare event during the start phase: #%d\n", event_no);
349
// Test the JVMTI class functions during the start phase
350
test_class_functions(jvmti, env, thread, klass);
351
352
set_thread_local(jvmti, thread, exp_val);
353
act_val = get_thread_local(jvmti, cur_thread);
354
if (act_val != exp_val) { // Actual value does not match the expected
355
printf(" ## Unexpected thread-local: %ld, expected: %ld\n",
356
(long)act_val, (long)exp_val);
357
result = FAILED;
358
} else {
359
printf(" Got expected thread-local: %ld\n", (long)exp_val);
360
}
361
event_no++;
362
}
363
}
364
365
static
366
jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
367
jboolean with_early_vm_start_capability = JNI_FALSE;
368
jvmtiEnv *jvmti = NULL;
369
jvmtiError err;
370
jint res, size;
371
jvmtiCapabilities caps;
372
jvmtiEventCallbacks callbacks;
373
374
if (options != NULL && strstr(options, "with_early_vmstart") != NULL) {
375
with_early_vm_start_capability = JNI_TRUE;
376
}
377
378
res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), JVMTI_VERSION_9);
379
if (res != JNI_OK || jvmti == NULL) {
380
printf("## Agent_Initialize: Error in GetEnv: res: %d, jvmti env: %p\n", res, jvmti);
381
return JNI_ERR;
382
}
383
384
memset(&caps, 0, sizeof(caps));
385
caps.can_get_source_file_name = 1;
386
caps.can_get_synthetic_attribute = 1;
387
388
if (with_early_vm_start_capability == JNI_TRUE) {
389
caps.can_generate_early_vmstart = 1;
390
printf("Capability enabled: can_generate_early_vmstart\n");
391
} else {
392
printf("Capability disabled: can_generate_early_vmstart\n");
393
}
394
err = (*jvmti)->AddCapabilities(jvmti, &caps);
395
check_jvmti_error(jvmti, "## Agent_Initialize: AddCapabilites", err);
396
397
size = (jint)sizeof(callbacks);
398
memset(&callbacks, 0, size);
399
callbacks.VMStart = VMStart;
400
callbacks.VMInit = VMInit;
401
callbacks.ClassPrepare = ClassPrepare;
402
403
err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size);
404
check_jvmti_error(jvmti, "## Agent_Initialize: SetEventCallbacks", err);
405
406
err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL);
407
check_jvmti_error(jvmti, "## Agent_Initialize: SetEventNotificationMode VM_START", err);
408
409
err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
410
check_jvmti_error(jvmti, "## Agent_Initialize: SetEventNotificationMode VM_INIT", err);
411
412
err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL);
413
check_jvmti_error(jvmti, "## Agent_Initialize: SetEventNotificationMode CLASS_PREPARE", err);
414
return JNI_OK;
415
}
416
417
JNIEXPORT jint JNICALL
418
Java_AllowedFunctions_check(JNIEnv *env, jclass cls) {
419
return result;
420
}
421
422
#ifdef __cplusplus
423
}
424
#endif
425
426