1 /* 2 * Copyright (C) 2016 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 17 #include "common_helper.h" 18 19 #include <sstream> 20 #include <string> 21 22 #include "android-base/stringprintf.h" 23 #include "jni.h" 24 #include "jvmti.h" 25 26 #include "jvmti_helper.h" 27 28 namespace art { 29 30 jobject GetJavaField(jvmtiEnv* jvmti, JNIEnv* env, jclass field_klass, jfieldID f) { 31 jint mods = 0; 32 if (JvmtiErrorToException(env, jvmti, jvmti->GetFieldModifiers(field_klass, f, &mods))) { 33 return nullptr; 34 } 35 36 bool is_static = (mods & kAccStatic) != 0; 37 return env->ToReflectedField(field_klass, f, is_static); 38 } 39 40 jobject GetJavaMethod(jvmtiEnv* jvmti, JNIEnv* env, jmethodID m) { 41 jint mods = 0; 42 if (JvmtiErrorToException(env, jvmti, jvmti->GetMethodModifiers(m, &mods))) { 43 return nullptr; 44 } 45 46 bool is_static = (mods & kAccStatic) != 0; 47 jclass method_klass = nullptr; 48 if (JvmtiErrorToException(env, jvmti, jvmti->GetMethodDeclaringClass(m, &method_klass))) { 49 return nullptr; 50 } 51 jobject res = env->ToReflectedMethod(method_klass, m, is_static); 52 env->DeleteLocalRef(method_klass); 53 return res; 54 } 55 56 jobject GetJavaValueByType(JNIEnv* env, char type, jvalue value) { 57 std::string name; 58 switch (type) { 59 case 'V': 60 return nullptr; 61 case '[': 62 case 'L': 63 return value.l; 64 case 'Z': 65 name = "java/lang/Boolean"; 66 break; 67 case 'B': 68 name = "java/lang/Byte"; 69 break; 70 case 'C': 71 name = "java/lang/Character"; 72 break; 73 case 'S': 74 name = "java/lang/Short"; 75 break; 76 case 'I': 77 name = "java/lang/Integer"; 78 break; 79 case 'J': 80 name = "java/lang/Long"; 81 break; 82 case 'F': 83 name = "java/lang/Float"; 84 break; 85 case 'D': 86 name = "java/lang/Double"; 87 break; 88 default: 89 LOG(FATAL) << "Unable to figure out type!"; 90 return nullptr; 91 } 92 std::ostringstream oss; 93 oss << "(" << type << ")L" << name << ";"; 94 std::string args = oss.str(); 95 jclass target = env->FindClass(name.c_str()); 96 jmethodID valueOfMethod = env->GetStaticMethodID(target, "valueOf", args.c_str()); 97 98 CHECK(valueOfMethod != nullptr) << args; 99 jobject res = env->CallStaticObjectMethodA(target, valueOfMethod, &value); 100 env->DeleteLocalRef(target); 101 return res; 102 } 103 104 jobject GetJavaValue(jvmtiEnv* jvmtienv, JNIEnv* env, jmethodID m, jvalue value) { 105 char *fname, *fsig, *fgen; 106 if (JvmtiErrorToException(env, jvmtienv, jvmtienv->GetMethodName(m, &fname, &fsig, &fgen))) { 107 return nullptr; 108 } 109 std::string type(fsig); 110 type = type.substr(type.find(')') + 1); 111 jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fsig)); 112 jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fname)); 113 jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fgen)); 114 return GetJavaValueByType(env, type[0], value); 115 } 116 117 } // namespace art 118