1 /*
2  * Copyright (C) 2017 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 #ifndef ART_TEST_TI_AGENT_JVMTI_HELPER_H_
18 #define ART_TEST_TI_AGENT_JVMTI_HELPER_H_
19 
20 #include <memory>
21 #include <ostream>
22 
23 #include "jni.h"
24 #include "jvmti.h"
25 
26 #include "android-base/logging.h"
27 
28 namespace art {
29 
30 // Get a standard set of capabilities for use in tests.
31 jvmtiCapabilities GetStandardCapabilities();
32 
33 // Add all the standard capabilities to the given env.
34 void SetStandardCapabilities(jvmtiEnv* env);
35 
36 // Add all capabilities to the given env.
37 // TODO Remove this in the future.
38 void SetAllCapabilities(jvmtiEnv* env);
39 
40 // Check whether the given error is NONE. If not, print out the corresponding error message
41 // and abort.
42 void CheckJvmtiError(jvmtiEnv* env, jvmtiError error);
43 
44 // Convert the given error to a RuntimeException with a message derived from the error. Returns
45 // true on error, false if error is JVMTI_ERROR_NONE.
46 bool JvmtiErrorToException(JNIEnv* env, jvmtiEnv* jvmtienv, jvmtiError error);
47 
48 class JvmtiDeleter {
49  public:
JvmtiDeleter()50   JvmtiDeleter() : env_(nullptr) {}
JvmtiDeleter(jvmtiEnv * env)51   explicit JvmtiDeleter(jvmtiEnv* env) : env_(env) {}
52 
53   JvmtiDeleter(JvmtiDeleter&) = default;
54   JvmtiDeleter(JvmtiDeleter&&) = default;
55   JvmtiDeleter& operator=(const JvmtiDeleter&) = default;
56 
operator()57   void operator()(unsigned char* ptr) const {
58     CHECK(env_ != nullptr);
59     jvmtiError ret = env_->Deallocate(ptr);
60     CheckJvmtiError(env_, ret);
61   }
62 
63  private:
64   mutable jvmtiEnv* env_;
65 };
66 
67 using JvmtiUniquePtr = std::unique_ptr<unsigned char, JvmtiDeleter>;
68 
69 template <typename T>
MakeJvmtiUniquePtr(jvmtiEnv * env,T * mem)70 static inline JvmtiUniquePtr MakeJvmtiUniquePtr(jvmtiEnv* env, T* mem) {
71   return JvmtiUniquePtr(reinterpret_cast<unsigned char*>(mem), JvmtiDeleter(env));
72 }
73 
74 template <typename T>
Deallocate(jvmtiEnv * env,T * mem)75 static inline jvmtiError Deallocate(jvmtiEnv* env, T* mem) {
76   return env->Deallocate(reinterpret_cast<unsigned char*>(mem));
77 }
78 
79 // To print jvmtiError. Does not rely on GetErrorName, so is an approximation.
80 std::ostream& operator<<(std::ostream& os, const jvmtiError& rhs);
81 
Dealloc(jvmtiEnv * env,T * t)82 template <typename T> void Dealloc(jvmtiEnv* env, T* t) {
83   env->Deallocate(reinterpret_cast<unsigned char*>(t));
84 }
85 
Dealloc(jvmtiEnv * env,T * t,Rest...rs)86 template <typename T, typename... Rest> void Dealloc(jvmtiEnv* env, T* t, Rest... rs) {
87   Dealloc(env, t);
88   Dealloc(env, rs...);
89 }
90 
91 void* GetExtensionFunctionVoid(JNIEnv* env, jvmtiEnv* jvmti, const std::string_view& name);
92 
GetExtensionFunction(JNIEnv * env,jvmtiEnv * jvmti,const std::string_view & name)93 template<typename T> T GetExtensionFunction(JNIEnv* env, jvmtiEnv* jvmti, const std::string_view& name) {
94   return reinterpret_cast<T>(GetExtensionFunctionVoid(env, jvmti, name));
95 }
96 
97 jint GetExtensionEventId(jvmtiEnv* jvmti, const std::string_view& name);
98 
99 }  // namespace art
100 
101 #endif  // ART_TEST_TI_AGENT_JVMTI_HELPER_H_
102