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