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 <stdio.h>
25 #include <string.h>
26 #include "jvmti.h"
27 #include "agent_common.h"
28 #include "JVMTITools.h"
29 
30 extern "C" {
31 
32 
33 #define PASSED 0
34 #define STATUS_FAILED 2
35 
36 typedef struct {
37     int class_id;
38     const char *name;
39     const char *signature;
40     jboolean is_static;
41     jboolean is_synthetic;
42 } method_info;
43 
44 static jvmtiEnv *jvmti = NULL;
45 static jvmtiCapabilities caps;
46 static jint result = PASSED;
47 static jboolean printdump = JNI_FALSE;
48 static method_info methods[] = {
49     { 1, "meth_stat", "(ILjava/lang/String;)[F", JNI_TRUE, JNI_FALSE },
50     { 1, "meth_1", "(CCC)C", JNI_FALSE, JNI_FALSE },
51     { 1, "class$", "(Ljava/lang/String;)Ljava/lang/Class;", JNI_TRUE, JNI_TRUE },
52     { 1, "access$000",
53         "(Lnsk/jvmti/IsMethodSynthetic/issynth001a;)I", JNI_TRUE, JNI_TRUE },
54     { 1, "nmeth", "()V", JNI_FALSE, JNI_FALSE },
55     { 1, "check", "(Ljava/lang/Class;Ljava/lang/Class;)I", JNI_TRUE, JNI_FALSE },
56 
57     { 2, "<init>", "()V", JNI_FALSE, JNI_FALSE },
58     { 2, "run",
59         "([Ljava/lang/String;Ljava/io/PrintStream;)I", JNI_TRUE, JNI_FALSE },
60 
61     { 3, "meth_inn", "(Ljava/lang/String;J)V", JNI_FALSE, JNI_FALSE },
62 };
63 
64 #ifdef STATIC_BUILD
Agent_OnLoad_issynth001(JavaVM * jvm,char * options,void * reserved)65 JNIEXPORT jint JNICALL Agent_OnLoad_issynth001(JavaVM *jvm, char *options, void *reserved) {
66     return Agent_Initialize(jvm, options, reserved);
67 }
Agent_OnAttach_issynth001(JavaVM * jvm,char * options,void * reserved)68 JNIEXPORT jint JNICALL Agent_OnAttach_issynth001(JavaVM *jvm, char *options, void *reserved) {
69     return Agent_Initialize(jvm, options, reserved);
70 }
JNI_OnLoad_issynth001(JavaVM * jvm,char * options,void * reserved)71 JNIEXPORT jint JNI_OnLoad_issynth001(JavaVM *jvm, char *options, void *reserved) {
72     return JNI_VERSION_1_8;
73 }
74 #endif
Agent_Initialize(JavaVM * jvm,char * options,void * reserved)75 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
76     jint res;
77     jvmtiError err;
78 
79     if (options != NULL && strcmp(options, "printdump") == 0) {
80         printdump = JNI_TRUE;
81     }
82 
83     res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
84     if (res != JNI_OK || jvmti == NULL) {
85         printf("Wrong result of a valid call to GetEnv!\n");
86         return JNI_ERR;
87     }
88 
89     err = jvmti->GetPotentialCapabilities(&caps);
90     if (err != JVMTI_ERROR_NONE) {
91         printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n",
92                TranslateError(err), err);
93         return JNI_ERR;
94     }
95 
96     err = jvmti->AddCapabilities(&caps);
97     if (err != JVMTI_ERROR_NONE) {
98         printf("(AddCapabilities) unexpected error: %s (%d)\n",
99                TranslateError(err), err);
100         return JNI_ERR;
101     }
102 
103     err = jvmti->GetCapabilities(&caps);
104     if (err != JVMTI_ERROR_NONE) {
105         printf("(GetCapabilities) unexpected error: %s (%d)\n",
106                TranslateError(err), err);
107         return JNI_ERR;
108     }
109 
110     if (!caps.can_get_synthetic_attribute) {
111         printf("Warning: IsMethodSynthetic is not implemented\n");
112     }
113 
114     return JNI_OK;
115 }
116 
jbooleanToString(jboolean flag)117 char const *jbooleanToString(jboolean flag) {
118     return ((flag == JNI_TRUE) ? "true" : "false");
119 }
120 
121 JNIEXPORT jint JNICALL
Java_nsk_jvmti_IsMethodSynthetic_issynth001a_check(JNIEnv * env,jclass cls1,jclass cls2,jclass cls3)122 Java_nsk_jvmti_IsMethodSynthetic_issynth001a_check(JNIEnv *env,
123         jclass cls1, jclass cls2, jclass cls3) {
124     jvmtiError err;
125     jclass cl;
126     jmethodID mid;
127     jboolean is_synthetic;
128     size_t i;
129 
130     if (!caps.can_get_synthetic_attribute) {
131         return result;
132     }
133 
134     for (i = 0; i < sizeof(methods)/sizeof(method_info); i++) {
135         cl = ((methods[i].class_id == 1) ? cls1 :
136                 ((methods[i].class_id == 2) ? cls2 : cls3));
137         if (methods[i].is_static == JNI_TRUE) {
138             mid = env->GetStaticMethodID(cl, methods[i].name, methods[i].signature);
139         } else {
140             mid = env->GetMethodID(cl, methods[i].name, methods[i].signature);
141         }
142         if (mid == NULL) {
143             printf("Cannot find MethodID for \"%s%s\"\n",
144                 methods[i].name, methods[i].signature);
145             result = STATUS_FAILED;
146             continue;
147         }
148 
149         err = jvmti->IsMethodSynthetic(mid, &is_synthetic);
150         if (err != JVMTI_ERROR_NONE) {
151             printf("(IsMethodSynthetic) unexpected error: %s (%d)\n",
152                    TranslateError(err), err);
153             result = STATUS_FAILED;
154         }
155 
156         if (printdump == JNI_TRUE) {
157             printf(">>> %s%s - %s\n", methods[i].name, methods[i].signature,
158                    jbooleanToString(is_synthetic));
159         }
160 
161         if (is_synthetic != methods[i].is_synthetic) {
162             printf("(%s%s) wrong is_synthetic value: %s, expected: %s\n",
163                 methods[i].name, methods[i].signature,
164                 jbooleanToString(is_synthetic),
165                 jbooleanToString(methods[i].is_synthetic));
166             result = STATUS_FAILED;
167         }
168     }
169 
170     return result;
171 }
172 
173 JNIEXPORT void JNICALL
Java_nsk_jvmti_IsMethodSynthetic_issynth001a_nmeth(JNIEnv * env,jclass cls)174 Java_nsk_jvmti_IsMethodSynthetic_issynth001a_nmeth(JNIEnv *env, jclass cls) {
175 }
176 
177 }
178