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