blob: 29eeff669471e3b548e0df53ab474f9bb29c27e9 [file] [log] [blame]
Andreas Gampee492ae32016-10-28 19:34:57 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Gampee492ae32016-10-28 19:34:57 -070017#include <stdio.h>
18
19#include "base/macros.h"
20#include "jni.h"
21#include "openjdkjvmti/jvmti.h"
22#include "ScopedLocalRef.h"
23
Andreas Gampe336c3c32016-11-08 17:02:19 -080024#include "ti-agent/common_helper.h"
Andreas Gampee492ae32016-10-28 19:34:57 -070025#include "ti-agent/common_load.h"
26
27namespace art {
28namespace Test912Classes {
29
Alex Lighte4a88632017-01-10 07:41:24 -080030extern "C" JNIEXPORT jboolean JNICALL Java_Main_isModifiableClass(
31 JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
32 jboolean res = JNI_FALSE;
33 jvmtiError result = jvmti_env->IsModifiableClass(klass, &res);
34 if (result != JVMTI_ERROR_NONE) {
35 char* err;
36 jvmti_env->GetErrorName(result, &err);
37 printf("Failure running IsModifiableClass: %s\n", err);
38 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
39 return JNI_FALSE;
40 }
41 return res;
42}
43
Andreas Gampee492ae32016-10-28 19:34:57 -070044extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassSignature(
45 JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
46 char* sig;
47 char* gen;
48 jvmtiError result = jvmti_env->GetClassSignature(klass, &sig, &gen);
49 if (result != JVMTI_ERROR_NONE) {
50 char* err;
51 jvmti_env->GetErrorName(result, &err);
52 printf("Failure running GetClassSignature: %s\n", err);
Alex Light41960712017-01-06 14:44:23 -080053 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
Andreas Gampee492ae32016-10-28 19:34:57 -070054 return nullptr;
55 }
56
Andreas Gampe336c3c32016-11-08 17:02:19 -080057 auto callback = [&](jint i) {
58 if (i == 0) {
59 return sig == nullptr ? nullptr : env->NewStringUTF(sig);
60 } else {
61 return gen == nullptr ? nullptr : env->NewStringUTF(gen);
62 }
63 };
64 jobjectArray ret = CreateObjectArray(env, 2, "java/lang/String", callback);
Andreas Gampee492ae32016-10-28 19:34:57 -070065
66 // Need to deallocate the strings.
67 if (sig != nullptr) {
68 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(sig));
69 }
70 if (gen != nullptr) {
71 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(gen));
72 }
73
74 return ret;
75}
76
Andreas Gampe4fd66ec2017-01-05 14:42:13 -080077extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInterface(
78 JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
79 jboolean is_interface = JNI_FALSE;
80 jvmtiError result = jvmti_env->IsInterface(klass, &is_interface);
81 if (result != JVMTI_ERROR_NONE) {
82 char* err;
83 jvmti_env->GetErrorName(result, &err);
84 printf("Failure running IsInterface: %s\n", err);
Alex Light41960712017-01-06 14:44:23 -080085 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
Andreas Gampe4fd66ec2017-01-05 14:42:13 -080086 return JNI_FALSE;
87 }
88 return is_interface;
89}
90
91extern "C" JNIEXPORT jboolean JNICALL Java_Main_isArrayClass(
92 JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
93 jboolean is_array_class = JNI_FALSE;
94 jvmtiError result = jvmti_env->IsArrayClass(klass, &is_array_class);
95 if (result != JVMTI_ERROR_NONE) {
96 char* err;
97 jvmti_env->GetErrorName(result, &err);
98 printf("Failure running IsArrayClass: %s\n", err);
Alex Light41960712017-01-06 14:44:23 -080099 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
Andreas Gampe4fd66ec2017-01-05 14:42:13 -0800100 return JNI_FALSE;
101 }
102 return is_array_class;
103}
104
Andreas Gampe64013e52017-01-06 13:07:19 -0800105extern "C" JNIEXPORT jint JNICALL Java_Main_getClassModifiers(
106 JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
107 jint mod;
108 jvmtiError result = jvmti_env->GetClassModifiers(klass, &mod);
109 if (result != JVMTI_ERROR_NONE) {
110 char* err;
111 jvmti_env->GetErrorName(result, &err);
112 printf("Failure running GetClassModifiers: %s\n", err);
113 return JNI_FALSE;
114 }
115 return mod;
116}
117
Andreas Gampeac587272017-01-05 15:21:34 -0800118extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassFields(
119 JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
120 jint count = 0;
121 jfieldID* fields = nullptr;
122 jvmtiError result = jvmti_env->GetClassFields(klass, &count, &fields);
123 if (result != JVMTI_ERROR_NONE) {
124 char* err;
125 jvmti_env->GetErrorName(result, &err);
126 printf("Failure running GetClassFields: %s\n", err);
Alex Light41960712017-01-06 14:44:23 -0800127 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
Andreas Gampeac587272017-01-05 15:21:34 -0800128 return nullptr;
129 }
130
131 auto callback = [&](jint i) {
132 jint modifiers;
133 // Ignore any errors for simplicity.
134 jvmti_env->GetFieldModifiers(klass, fields[i], &modifiers);
135 constexpr jint kStatic = 0x8;
136 return env->ToReflectedField(klass,
137 fields[i],
138 (modifiers & kStatic) != 0 ? JNI_TRUE : JNI_FALSE);
139 };
Andreas Gampe8b07e472017-01-06 14:20:39 -0800140 jobjectArray ret = CreateObjectArray(env, count, "java/lang/Object", callback);
141 if (fields != nullptr) {
142 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(fields));
143 }
144 return ret;
Andreas Gampeac587272017-01-05 15:21:34 -0800145}
146
Andreas Gampe18fee4d2017-01-06 11:36:35 -0800147extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassMethods(
148 JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
149 jint count = 0;
150 jmethodID* methods = nullptr;
151 jvmtiError result = jvmti_env->GetClassMethods(klass, &count, &methods);
152 if (result != JVMTI_ERROR_NONE) {
153 char* err;
154 jvmti_env->GetErrorName(result, &err);
155 printf("Failure running GetClassMethods: %s\n", err);
156 return nullptr;
157 }
158
159 auto callback = [&](jint i) {
160 jint modifiers;
161 // Ignore any errors for simplicity.
162 jvmti_env->GetMethodModifiers(methods[i], &modifiers);
163 constexpr jint kStatic = 0x8;
164 return env->ToReflectedMethod(klass,
165 methods[i],
166 (modifiers & kStatic) != 0 ? JNI_TRUE : JNI_FALSE);
167 };
Andreas Gampe8b07e472017-01-06 14:20:39 -0800168 jobjectArray ret = CreateObjectArray(env, count, "java/lang/Object", callback);
169 if (methods != nullptr) {
170 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(methods));
171 }
172 return ret;
173}
174
175extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getImplementedInterfaces(
176 JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
177 jint count = 0;
178 jclass* classes = nullptr;
179 jvmtiError result = jvmti_env->GetImplementedInterfaces(klass, &count, &classes);
180 if (result != JVMTI_ERROR_NONE) {
181 char* err;
182 jvmti_env->GetErrorName(result, &err);
183 printf("Failure running GetImplementedInterfaces: %s\n", err);
184 return nullptr;
185 }
186
187 auto callback = [&](jint i) {
188 return classes[i];
189 };
190 jobjectArray ret = CreateObjectArray(env, count, "java/lang/Class", callback);
191 if (classes != nullptr) {
192 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(classes));
193 }
194 return ret;
Andreas Gampe18fee4d2017-01-06 11:36:35 -0800195}
196
Andreas Gampeff9d2092017-01-06 09:12:49 -0800197extern "C" JNIEXPORT jint JNICALL Java_Main_getClassStatus(
198 JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
199 jint status;
200 jvmtiError result = jvmti_env->GetClassStatus(klass, &status);
201 if (result != JVMTI_ERROR_NONE) {
202 char* err;
203 jvmti_env->GetErrorName(result, &err);
204 printf("Failure running GetClassStatus: %s\n", err);
Alex Light41960712017-01-06 14:44:23 -0800205 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
Andreas Gampeff9d2092017-01-06 09:12:49 -0800206 return JNI_FALSE;
207 }
208 return status;
209}
210
Andreas Gampe8f5b6032017-01-06 15:50:55 -0800211extern "C" JNIEXPORT jobject JNICALL Java_Main_getClassLoader(
212 JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
213 jobject classloader;
214 jvmtiError result = jvmti_env->GetClassLoader(klass, &classloader);
215 if (result != JVMTI_ERROR_NONE) {
216 char* err;
217 jvmti_env->GetErrorName(result, &err);
218 printf("Failure running GetClassLoader: %s\n", err);
219 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
220 return nullptr;
221 }
222 return classloader;
223}
224
Andreas Gampe70f16392017-01-16 14:20:10 -0800225extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassLoaderClasses(
226 JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jobject jclassloader) {
227 jint count = 0;
228 jclass* classes = nullptr;
229 jvmtiError result = jvmti_env->GetClassLoaderClasses(jclassloader, &count, &classes);
230 if (JvmtiErrorToException(env, result)) {
231 return nullptr;
232 }
233
234 auto callback = [&](jint i) {
235 return classes[i];
236 };
237 jobjectArray ret = CreateObjectArray(env, count, "java/lang/Class", callback);
238 if (classes != nullptr) {
239 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(classes));
240 }
241 return ret;
242}
243
Andreas Gampe812a2442017-01-19 22:04:46 -0800244extern "C" JNIEXPORT jintArray JNICALL Java_Main_getClassVersion(
245 JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
246 jint major, minor;
247 jvmtiError result = jvmti_env->GetClassVersionNumbers(klass, &minor, &major);
248 if (JvmtiErrorToException(env, result)) {
249 return nullptr;
250 }
251
252 jintArray int_array = env->NewIntArray(2);
253 if (int_array == nullptr) {
254 return nullptr;
255 }
256 jint buf[2] = { major, minor };
257 env->SetIntArrayRegion(int_array, 0, 2, buf);
258
259 return int_array;
260}
261
Andreas Gampee492ae32016-10-28 19:34:57 -0700262} // namespace Test912Classes
263} // namespace art