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