1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_TI_AGENT_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_TI_AGENT_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <dlfcn.h> 21*795d594fSAndroid Build Coastguard Worker #include <jni.h> // for jint, JavaVM* etc declarations 22*795d594fSAndroid Build Coastguard Worker 23*795d594fSAndroid Build Coastguard Worker #include <memory> 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h> 26*795d594fSAndroid Build Coastguard Worker #include <android-base/macros.h> 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 31*795d594fSAndroid Build Coastguard Worker namespace ti { 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker class Agent; 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker enum LoadError { 36*795d594fSAndroid Build Coastguard Worker kNoError, // No error occurred.. 37*795d594fSAndroid Build Coastguard Worker kLoadingError, // dlopen or dlsym returned an error. 38*795d594fSAndroid Build Coastguard Worker kInitializationError, // The entrypoint did not return 0. This might require an abort. 39*795d594fSAndroid Build Coastguard Worker }; 40*795d594fSAndroid Build Coastguard Worker 41*795d594fSAndroid Build Coastguard Worker class AgentSpec { 42*795d594fSAndroid Build Coastguard Worker public: 43*795d594fSAndroid Build Coastguard Worker explicit AgentSpec(const std::string& arg); 44*795d594fSAndroid Build Coastguard Worker GetName()45*795d594fSAndroid Build Coastguard Worker const std::string& GetName() const { 46*795d594fSAndroid Build Coastguard Worker return name_; 47*795d594fSAndroid Build Coastguard Worker } 48*795d594fSAndroid Build Coastguard Worker GetArgs()49*795d594fSAndroid Build Coastguard Worker const std::string& GetArgs() const { 50*795d594fSAndroid Build Coastguard Worker return args_; 51*795d594fSAndroid Build Coastguard Worker } 52*795d594fSAndroid Build Coastguard Worker HasArgs()53*795d594fSAndroid Build Coastguard Worker bool HasArgs() const { 54*795d594fSAndroid Build Coastguard Worker return !GetArgs().empty(); 55*795d594fSAndroid Build Coastguard Worker } 56*795d594fSAndroid Build Coastguard Worker 57*795d594fSAndroid Build Coastguard Worker std::unique_ptr<Agent> Load(/*out*/jint* call_res, 58*795d594fSAndroid Build Coastguard Worker /*out*/LoadError* error, 59*795d594fSAndroid Build Coastguard Worker /*out*/std::string* error_msg); 60*795d594fSAndroid Build Coastguard Worker 61*795d594fSAndroid Build Coastguard Worker // Tries to attach the agent using its OnAttach method. Returns true on success. 62*795d594fSAndroid Build Coastguard Worker std::unique_ptr<Agent> Attach(JNIEnv* env, 63*795d594fSAndroid Build Coastguard Worker jobject class_loader, 64*795d594fSAndroid Build Coastguard Worker /*out*/jint* call_res, 65*795d594fSAndroid Build Coastguard Worker /*out*/LoadError* error, 66*795d594fSAndroid Build Coastguard Worker /*out*/std::string* error_msg); 67*795d594fSAndroid Build Coastguard Worker 68*795d594fSAndroid Build Coastguard Worker private: 69*795d594fSAndroid Build Coastguard Worker std::unique_ptr<Agent> DoDlOpen(JNIEnv* env, 70*795d594fSAndroid Build Coastguard Worker jobject class_loader, 71*795d594fSAndroid Build Coastguard Worker /*out*/LoadError* error, 72*795d594fSAndroid Build Coastguard Worker /*out*/std::string* error_msg); 73*795d594fSAndroid Build Coastguard Worker 74*795d594fSAndroid Build Coastguard Worker std::unique_ptr<Agent> DoLoadHelper(JNIEnv* env, 75*795d594fSAndroid Build Coastguard Worker bool attaching, 76*795d594fSAndroid Build Coastguard Worker jobject class_loader, 77*795d594fSAndroid Build Coastguard Worker /*out*/jint* call_res, 78*795d594fSAndroid Build Coastguard Worker /*out*/LoadError* error, 79*795d594fSAndroid Build Coastguard Worker /*out*/std::string* error_msg); 80*795d594fSAndroid Build Coastguard Worker 81*795d594fSAndroid Build Coastguard Worker std::string name_; 82*795d594fSAndroid Build Coastguard Worker std::string args_; 83*795d594fSAndroid Build Coastguard Worker 84*795d594fSAndroid Build Coastguard Worker friend std::ostream& operator<<(std::ostream &os, AgentSpec const& m); 85*795d594fSAndroid Build Coastguard Worker }; 86*795d594fSAndroid Build Coastguard Worker 87*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream &os, AgentSpec const& m); 88*795d594fSAndroid Build Coastguard Worker 89*795d594fSAndroid Build Coastguard Worker using AgentOnLoadFunction = jint (*)(JavaVM*, const char*, void*); 90*795d594fSAndroid Build Coastguard Worker using AgentOnUnloadFunction = void (*)(JavaVM*); 91*795d594fSAndroid Build Coastguard Worker 92*795d594fSAndroid Build Coastguard Worker // Agents are native libraries that will be loaded by the runtime for the purpose of 93*795d594fSAndroid Build Coastguard Worker // instrumentation. They will be entered by Agent_OnLoad or Agent_OnAttach depending on whether the 94*795d594fSAndroid Build Coastguard Worker // agent is being attached during runtime startup or later. 95*795d594fSAndroid Build Coastguard Worker // 96*795d594fSAndroid Build Coastguard Worker // The agent's Agent_OnUnload function will be called during runtime shutdown. 97*795d594fSAndroid Build Coastguard Worker // 98*795d594fSAndroid Build Coastguard Worker // TODO: consider splitting ti::Agent into command line, agent and shared library handler classes 99*795d594fSAndroid Build Coastguard Worker // TODO Support native-bridge. Currently agents can only be the actual runtime ISA of the device. 100*795d594fSAndroid Build Coastguard Worker class Agent { 101*795d594fSAndroid Build Coastguard Worker public: GetName()102*795d594fSAndroid Build Coastguard Worker const std::string& GetName() const { 103*795d594fSAndroid Build Coastguard Worker return name_; 104*795d594fSAndroid Build Coastguard Worker } 105*795d594fSAndroid Build Coastguard Worker 106*795d594fSAndroid Build Coastguard Worker void* FindSymbol(const std::string& name) const; 107*795d594fSAndroid Build Coastguard Worker 108*795d594fSAndroid Build Coastguard Worker // TODO We need to acquire some locks probably. 109*795d594fSAndroid Build Coastguard Worker void Unload(); 110*795d594fSAndroid Build Coastguard Worker 111*795d594fSAndroid Build Coastguard Worker Agent(Agent&& other) noexcept; 112*795d594fSAndroid Build Coastguard Worker Agent& operator=(Agent&& other) noexcept; 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker ~Agent(); 115*795d594fSAndroid Build Coastguard Worker 116*795d594fSAndroid Build Coastguard Worker private: Agent(const std::string & name,void * dlopen_handle)117*795d594fSAndroid Build Coastguard Worker Agent(const std::string& name, void* dlopen_handle) : name_(name), 118*795d594fSAndroid Build Coastguard Worker dlopen_handle_(dlopen_handle), 119*795d594fSAndroid Build Coastguard Worker onload_(nullptr), 120*795d594fSAndroid Build Coastguard Worker onattach_(nullptr), 121*795d594fSAndroid Build Coastguard Worker onunload_(nullptr) { 122*795d594fSAndroid Build Coastguard Worker DCHECK(dlopen_handle != nullptr); 123*795d594fSAndroid Build Coastguard Worker } 124*795d594fSAndroid Build Coastguard Worker 125*795d594fSAndroid Build Coastguard Worker void PopulateFunctions(); 126*795d594fSAndroid Build Coastguard Worker 127*795d594fSAndroid Build Coastguard Worker std::string name_; 128*795d594fSAndroid Build Coastguard Worker void* dlopen_handle_; 129*795d594fSAndroid Build Coastguard Worker 130*795d594fSAndroid Build Coastguard Worker // The entrypoints. 131*795d594fSAndroid Build Coastguard Worker AgentOnLoadFunction onload_; 132*795d594fSAndroid Build Coastguard Worker AgentOnLoadFunction onattach_; 133*795d594fSAndroid Build Coastguard Worker AgentOnUnloadFunction onunload_; 134*795d594fSAndroid Build Coastguard Worker 135*795d594fSAndroid Build Coastguard Worker friend class AgentSpec; 136*795d594fSAndroid Build Coastguard Worker friend std::ostream& operator<<(std::ostream &os, Agent const& m); 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Agent); 139*795d594fSAndroid Build Coastguard Worker }; 140*795d594fSAndroid Build Coastguard Worker 141*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream &os, Agent const& m); 142*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream &os, const Agent* m); 143*795d594fSAndroid Build Coastguard Worker 144*795d594fSAndroid Build Coastguard Worker } // namespace ti 145*795d594fSAndroid Build Coastguard Worker } // namespace art 146*795d594fSAndroid Build Coastguard Worker 147*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_TI_AGENT_H_ 148*795d594fSAndroid Build Coastguard Worker 149