1185d134a3b43ab7529053e965917e0fa74bceba4Alex Light/* 2185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * Copyright (C) 2016 The Android Open Source Project 3185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * 4185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * Licensed under the Apache License, Version 2.0 (the "License"); 5185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * you may not use this file except in compliance with the License. 6185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * You may obtain a copy of the License at 7185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * 8185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * http://www.apache.org/licenses/LICENSE-2.0 9185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * 10185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * Unless required by applicable law or agreed to in writing, software 11185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * distributed under the License is distributed on an "AS IS" BASIS, 12185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * See the License for the specific language governing permissions and 14185d134a3b43ab7529053e965917e0fa74bceba4Alex Light * limitations under the License. 15185d134a3b43ab7529053e965917e0fa74bceba4Alex Light */ 16185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 17185d134a3b43ab7529053e965917e0fa74bceba4Alex Light#include "plugin.h" 18185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 19185d134a3b43ab7529053e965917e0fa74bceba4Alex Light#include <dlfcn.h> 2046ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 2146ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe#include "android-base/stringprintf.h" 2246ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 23185d134a3b43ab7529053e965917e0fa74bceba4Alex Light#include "base/logging.h" 24185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 25185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightnamespace art { 26185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 2746ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampeusing android::base::StringPrintf; 2846ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 29185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightconst char* PLUGIN_INITIALIZATION_FUNCTION_NAME = "ArtPlugin_Initialize"; 30185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightconst char* PLUGIN_DEINITIALIZATION_FUNCTION_NAME = "ArtPlugin_Deinitialize"; 31185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 32185d134a3b43ab7529053e965917e0fa74bceba4Alex LightPlugin::Plugin(const Plugin& other) : library_(other.library_), dlopen_handle_(nullptr) { 33185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (other.IsLoaded()) { 34185d134a3b43ab7529053e965917e0fa74bceba4Alex Light std::string err; 35185d134a3b43ab7529053e965917e0fa74bceba4Alex Light Load(&err); 36185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 37185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} 38185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 39185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightbool Plugin::Load(/*out*/std::string* error_msg) { 40185d134a3b43ab7529053e965917e0fa74bceba4Alex Light DCHECK(!IsLoaded()); 41185d134a3b43ab7529053e965917e0fa74bceba4Alex Light void* res = dlopen(library_.c_str(), RTLD_LAZY); 42185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (res == nullptr) { 43185d134a3b43ab7529053e965917e0fa74bceba4Alex Light *error_msg = StringPrintf("dlopen failed: %s", dlerror()); 44185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return false; 45185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 46185d134a3b43ab7529053e965917e0fa74bceba4Alex Light // Get the initializer function 47185d134a3b43ab7529053e965917e0fa74bceba4Alex Light PluginInitializationFunction init = reinterpret_cast<PluginInitializationFunction>( 48185d134a3b43ab7529053e965917e0fa74bceba4Alex Light dlsym(res, PLUGIN_INITIALIZATION_FUNCTION_NAME)); 49185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (init != nullptr) { 50185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (!init()) { 51185d134a3b43ab7529053e965917e0fa74bceba4Alex Light dlclose(res); 52185d134a3b43ab7529053e965917e0fa74bceba4Alex Light *error_msg = StringPrintf("Initialization of plugin failed"); 53185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return false; 54185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 55185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } else { 56185d134a3b43ab7529053e965917e0fa74bceba4Alex Light LOG(WARNING) << this << " does not include an initialization function"; 57185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 58185d134a3b43ab7529053e965917e0fa74bceba4Alex Light dlopen_handle_ = res; 59185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return true; 60185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} 61185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 62185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightbool Plugin::Unload() { 63185d134a3b43ab7529053e965917e0fa74bceba4Alex Light DCHECK(IsLoaded()); 64185d134a3b43ab7529053e965917e0fa74bceba4Alex Light bool ret = true; 65185d134a3b43ab7529053e965917e0fa74bceba4Alex Light void* handle = dlopen_handle_; 66185d134a3b43ab7529053e965917e0fa74bceba4Alex Light PluginDeinitializationFunction deinit = reinterpret_cast<PluginDeinitializationFunction>( 67185d134a3b43ab7529053e965917e0fa74bceba4Alex Light dlsym(handle, PLUGIN_DEINITIALIZATION_FUNCTION_NAME)); 68185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (deinit != nullptr) { 69185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (!deinit()) { 70185d134a3b43ab7529053e965917e0fa74bceba4Alex Light LOG(WARNING) << this << " failed deinitialization"; 71185d134a3b43ab7529053e965917e0fa74bceba4Alex Light ret = false; 72185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 73185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } else { 74185d134a3b43ab7529053e965917e0fa74bceba4Alex Light LOG(WARNING) << this << " does not include a deinitialization function"; 75185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 76185d134a3b43ab7529053e965917e0fa74bceba4Alex Light dlopen_handle_ = nullptr; 77185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (dlclose(handle) != 0) { 78185d134a3b43ab7529053e965917e0fa74bceba4Alex Light LOG(ERROR) << this << " failed to dlclose: " << dlerror(); 79185d134a3b43ab7529053e965917e0fa74bceba4Alex Light ret = false; 80185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 81185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return ret; 82185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} 83185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 84185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightstd::ostream& operator<<(std::ostream &os, const Plugin* m) { 85185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return os << *m; 86185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} 87185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 88185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightstd::ostream& operator<<(std::ostream &os, Plugin const& m) { 89185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return os << "Plugin { library=\"" << m.library_ << "\", handle=" << m.dlopen_handle_ << " }"; 90185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} 91185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 92185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} // namespace art 93