blob: 24a6f1ce6af43d6ff059cc77c4e9a522fffaaa5c [file] [log] [blame]
Alex Light7233c7e2016-07-28 10:07:45 -07001/*
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
Andreas Gampeaadcbc62017-12-28 14:05:42 -080023#include <memory>
24
Andreas Gamped482e732017-04-24 17:59:09 -070025#include "base/logging.h"
Alex Light7233c7e2016-07-28 10:07:45 -070026
27namespace art {
28namespace ti {
29
Andreas Gampeaadcbc62017-12-28 14:05:42 -080030class Agent;
31
32enum 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
38class AgentSpec {
39 public:
40 explicit AgentSpec(const std::string& arg);
41
42 const std::string& GetName() const {
43 return name_;
44 }
45
46 const std::string& GetArgs() const {
47 return args_;
48 }
49
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.
Andreas Gampe7b38e692017-12-28 19:18:28 -080059 std::unique_ptr<Agent> Attach(JNIEnv* env,
60 jobject class_loader,
61 /*out*/jint* call_res,
Andreas Gampeaadcbc62017-12-28 14:05:42 -080062 /*out*/LoadError* error,
63 /*out*/std::string* error_msg);
64
65 private:
Andreas Gampe7b38e692017-12-28 19:18:28 -080066 std::unique_ptr<Agent> DoDlOpen(JNIEnv* env,
67 jobject class_loader,
68 /*out*/LoadError* error,
69 /*out*/std::string* error_msg);
Andreas Gampeaadcbc62017-12-28 14:05:42 -080070
Andreas Gampe7b38e692017-12-28 19:18:28 -080071 std::unique_ptr<Agent> DoLoadHelper(JNIEnv* env,
72 bool attaching,
73 jobject class_loader,
Andreas Gampeaadcbc62017-12-28 14:05:42 -080074 /*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
84std::ostream& operator<<(std::ostream &os, AgentSpec const& m);
85
Alex Light7233c7e2016-07-28 10:07:45 -070086using AgentOnLoadFunction = jint (*)(JavaVM*, const char*, void*);
Alex Light7233c7e2016-07-28 10:07:45 -070087using AgentOnUnloadFunction = void (*)(JavaVM*);
88
Alex Light65af20b2017-04-20 09:15:08 -070089// 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//
Leonard Mosescueb842212016-10-06 17:26:36 -070095// TODO: consider splitting ti::Agent into command line, agent and shared library handler classes
Alex Light65af20b2017-04-20 09:15:08 -070096// TODO Support native-bridge. Currently agents can only be the actual runtime ISA of the device.
Alex Light7233c7e2016-07-28 10:07:45 -070097class Agent {
98 public:
Alex Light7233c7e2016-07-28 10:07:45 -070099 const std::string& GetName() const {
100 return name_;
101 }
102
Alex Light65af20b2017-04-20 09:15:08 -0700103 void* FindSymbol(const std::string& name) const;
104
Alex Light7233c7e2016-07-28 10:07:45 -0700105 // TODO We need to acquire some locks probably.
106 void Unload();
107
Leonard Mosescueb842212016-10-06 17:26:36 -0700108 Agent(Agent&& other);
109 Agent& operator=(Agent&& other);
Alex Light7233c7e2016-07-28 10:07:45 -0700110
111 ~Agent();
112
Alex Light7233c7e2016-07-28 10:07:45 -0700113 private:
Andreas Gampeaadcbc62017-12-28 14:05:42 -0800114 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 }
Alex Light7233c7e2016-07-28 10:07:45 -0700121
Andreas Gampeaadcbc62017-12-28 14:05:42 -0800122 void PopulateFunctions();
Leonard Mosescueb842212016-10-06 17:26:36 -0700123
124 std::string name_;
Alex Light7233c7e2016-07-28 10:07:45 -0700125 void* dlopen_handle_;
126
127 // The entrypoints.
128 AgentOnLoadFunction onload_;
Leonard Mosescueb842212016-10-06 17:26:36 -0700129 AgentOnLoadFunction onattach_;
Alex Light7233c7e2016-07-28 10:07:45 -0700130 AgentOnUnloadFunction onunload_;
131
Andreas Gampeaadcbc62017-12-28 14:05:42 -0800132 friend class AgentSpec;
Alex Light7233c7e2016-07-28 10:07:45 -0700133 friend std::ostream& operator<<(std::ostream &os, Agent const& m);
Andreas Gampeaadcbc62017-12-28 14:05:42 -0800134
135 DISALLOW_COPY_AND_ASSIGN(Agent);
Alex Light7233c7e2016-07-28 10:07:45 -0700136};
137
138std::ostream& operator<<(std::ostream &os, Agent const& m);
139std::ostream& operator<<(std::ostream &os, const Agent* m);
140
141} // namespace ti
142} // namespace art
143
144#endif // ART_RUNTIME_TI_AGENT_H_
145