Home | History | Annotate | Download | only in ti-agent
      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