blob: 521e21e4e42c3ca1be5a8692b76d142bb8704203 [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
23#include "base/stringprintf.h"
24#include "runtime.h"
25#include "utils.h"
26
27namespace art {
28namespace ti {
29
30using AgentOnLoadFunction = jint (*)(JavaVM*, const char*, void*);
31using AgentOnAttachFunction = jint (*)(JavaVM*, const char*, void*);
32using AgentOnUnloadFunction = void (*)(JavaVM*);
33
34class Agent {
35 public:
36 enum LoadError {
37 kNoError, // No error occurred..
38 kAlreadyStarted, // The agent has already been loaded.
39 kLoadingError, // dlopen or dlsym returned an error.
40 kInitializationError, // The entrypoint did not return 0. This might require an abort.
41 };
42
43 bool IsStarted() const {
44 return dlopen_handle_ != nullptr;
45 }
46
47 const std::string& GetName() const {
48 return name_;
49 }
50
51 const std::string& GetArgs() const {
52 return args_;
53 }
54
55 bool HasArgs() const {
56 return !GetArgs().empty();
57 }
58
59 // TODO We need to acquire some locks probably.
60 LoadError Load(/*out*/jint* call_res, /*out*/std::string* error_msg);
61
62 // TODO We need to acquire some locks probably.
63 void Unload();
64
65 // Tries to attach the agent using its OnAttach method. Returns true on success.
66 // TODO We need to acquire some locks probably.
67 LoadError Attach(std::string* error_msg) {
68 // TODO
69 *error_msg = "Attach has not yet been implemented!";
70 return kLoadingError;
71 }
72
73 static Agent Create(std::string arg);
74
75 static Agent Create(std::string name, std::string args) {
76 return Agent(name, args);
77 }
78
79 ~Agent();
80
81 // We need move constructor and copy for vectors
82 Agent(const Agent& other);
83
84 Agent(Agent&& other)
85 : name_(other.name_),
86 args_(other.args_),
87 dlopen_handle_(nullptr),
88 onload_(nullptr),
89 onattach_(nullptr),
90 onunload_(nullptr) {
91 other.dlopen_handle_ = nullptr;
92 other.onload_ = nullptr;
93 other.onattach_ = nullptr;
94 other.onunload_ = nullptr;
95 }
96
97 // We don't need an operator=
98 void operator=(const Agent&) = delete;
99
100 private:
101 Agent(std::string name, std::string args)
102 : name_(name),
103 args_(args),
104 dlopen_handle_(nullptr),
105 onload_(nullptr),
106 onattach_(nullptr),
107 onunload_(nullptr) { }
108
109 LoadError DoDlOpen(/*out*/std::string* error_msg);
110
111 const std::string name_;
112 const std::string args_;
113 void* dlopen_handle_;
114
115 // The entrypoints.
116 AgentOnLoadFunction onload_;
117 AgentOnAttachFunction onattach_;
118 AgentOnUnloadFunction onunload_;
119
120 friend std::ostream& operator<<(std::ostream &os, Agent const& m);
121};
122
123std::ostream& operator<<(std::ostream &os, Agent const& m);
124std::ostream& operator<<(std::ostream &os, const Agent* m);
125
126} // namespace ti
127} // namespace art
128
129#endif // ART_RUNTIME_TI_AGENT_H_
130