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 #ifndef ART_RUNTIME_TI_AGENT_H_ 18 #define ART_RUNTIME_TI_AGENT_H_ 19 20 #include <dlfcn.h> 21 #include <jni.h> // for jint, JavaVM* etc declarations 22 23 #include <memory> 24 25 #include <android-base/logging.h> 26 #include <android-base/macros.h> 27 28 #include "base/macros.h" 29 30 namespace art HIDDEN { 31 namespace ti { 32 33 class Agent; 34 35 enum LoadError { 36 kNoError, // No error occurred.. 37 kLoadingError, // dlopen or dlsym returned an error. 38 kInitializationError, // The entrypoint did not return 0. This might require an abort. 39 }; 40 41 class AgentSpec { 42 public: 43 explicit AgentSpec(const std::string& arg); 44 GetName()45 const std::string& GetName() const { 46 return name_; 47 } 48 GetArgs()49 const std::string& GetArgs() const { 50 return args_; 51 } 52 HasArgs()53 bool HasArgs() const { 54 return !GetArgs().empty(); 55 } 56 57 std::unique_ptr<Agent> Load(/*out*/jint* call_res, 58 /*out*/LoadError* error, 59 /*out*/std::string* error_msg); 60 61 // Tries to attach the agent using its OnAttach method. Returns true on success. 62 std::unique_ptr<Agent> Attach(JNIEnv* env, 63 jobject class_loader, 64 /*out*/jint* call_res, 65 /*out*/LoadError* error, 66 /*out*/std::string* error_msg); 67 68 private: 69 std::unique_ptr<Agent> DoDlOpen(JNIEnv* env, 70 jobject class_loader, 71 /*out*/LoadError* error, 72 /*out*/std::string* error_msg); 73 74 std::unique_ptr<Agent> DoLoadHelper(JNIEnv* env, 75 bool attaching, 76 jobject class_loader, 77 /*out*/jint* call_res, 78 /*out*/LoadError* error, 79 /*out*/std::string* error_msg); 80 81 std::string name_; 82 std::string args_; 83 84 friend std::ostream& operator<<(std::ostream &os, AgentSpec const& m); 85 }; 86 87 std::ostream& operator<<(std::ostream &os, AgentSpec const& m); 88 89 using AgentOnLoadFunction = jint (*)(JavaVM*, const char*, void*); 90 using AgentOnUnloadFunction = void (*)(JavaVM*); 91 92 // Agents are native libraries that will be loaded by the runtime for the purpose of 93 // instrumentation. They will be entered by Agent_OnLoad or Agent_OnAttach depending on whether the 94 // agent is being attached during runtime startup or later. 95 // 96 // The agent's Agent_OnUnload function will be called during runtime shutdown. 97 // 98 // TODO: consider splitting ti::Agent into command line, agent and shared library handler classes 99 // TODO Support native-bridge. Currently agents can only be the actual runtime ISA of the device. 100 class Agent { 101 public: GetName()102 const std::string& GetName() const { 103 return name_; 104 } 105 106 void* FindSymbol(const std::string& name) const; 107 108 // TODO We need to acquire some locks probably. 109 void Unload(); 110 111 Agent(Agent&& other) noexcept; 112 Agent& operator=(Agent&& other) noexcept; 113 114 ~Agent(); 115 116 private: Agent(const std::string & name,void * dlopen_handle)117 Agent(const std::string& name, void* dlopen_handle) : name_(name), 118 dlopen_handle_(dlopen_handle), 119 onload_(nullptr), 120 onattach_(nullptr), 121 onunload_(nullptr) { 122 DCHECK(dlopen_handle != nullptr); 123 } 124 125 void PopulateFunctions(); 126 127 std::string name_; 128 void* dlopen_handle_; 129 130 // The entrypoints. 131 AgentOnLoadFunction onload_; 132 AgentOnLoadFunction onattach_; 133 AgentOnUnloadFunction onunload_; 134 135 friend class AgentSpec; 136 friend std::ostream& operator<<(std::ostream &os, Agent const& m); 137 138 DISALLOW_COPY_AND_ASSIGN(Agent); 139 }; 140 141 std::ostream& operator<<(std::ostream &os, Agent const& m); 142 std::ostream& operator<<(std::ostream &os, const Agent* m); 143 144 } // namespace ti 145 } // namespace art 146 147 #endif // ART_RUNTIME_TI_AGENT_H_ 148 149