1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "runtime/include/loadable_agent.h"
17
18 #include "runtime/include/runtime.h"
19
20 namespace panda {
LibraryAgent(os::memory::Mutex & mutex,PandaString libraryPath,PandaString loadCallbackName,PandaString unloadCallbackName)21 LibraryAgent::LibraryAgent(os::memory::Mutex &mutex, PandaString libraryPath, PandaString loadCallbackName,
22 PandaString unloadCallbackName)
23 : lock_(mutex),
24 library_path_(std::move(libraryPath)),
25 load_callback_name_(std::move(loadCallbackName)),
26 unload_callback_name_(std::move(unloadCallbackName))
27 {
28 }
29
Load()30 bool LibraryAgent::Load()
31 {
32 ASSERT(!handle_.IsValid());
33
34 auto handle = os::library_loader::Load(library_path_);
35 if (!handle) {
36 LOG(ERROR, RUNTIME) << "Couldn't load library '" << library_path_ << "': " << handle.Error().ToString();
37 return false;
38 }
39
40 auto load_callback = os::library_loader::ResolveSymbol(handle.Value(), load_callback_name_);
41 if (!load_callback) {
42 LOG(ERROR, RUNTIME) << "Couldn't resolve '" << load_callback_name_ << "' in '" << library_path_
43 << "':" << load_callback.Error().ToString();
44 return false;
45 }
46
47 auto unload_callback = os::library_loader::ResolveSymbol(handle.Value(), unload_callback_name_);
48 if (!unload_callback) {
49 LOG(ERROR, RUNTIME) << "Couldn't resolve '" << unload_callback_name_ << "' in '" << library_path_
50 << "':" << unload_callback.Error().ToString();
51 return false;
52 }
53
54 if (!CallLoadCallback(load_callback.Value())) {
55 LOG(ERROR, RUNTIME) << "'" << load_callback_name_ << "' failed in '" << library_path_ << "'";
56 return false;
57 }
58
59 handle_ = std::move(handle.Value());
60 unload_callback_ = unload_callback.Value();
61
62 return true;
63 }
64
Unload()65 bool LibraryAgent::Unload()
66 {
67 ASSERT(handle_.IsValid());
68
69 if (!CallUnloadCallback(unload_callback_)) {
70 LOG(ERROR, RUNTIME) << "'" << unload_callback_name_ << "' failed in '" << library_path_ << "'";
71 return false;
72 }
73
74 return true;
75 }
76 } // namespace panda
77