plugin.cc revision 185d134a3b43ab7529053e965917e0fa74bceba4
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> 20185d134a3b43ab7529053e965917e0fa74bceba4Alex Light#include "base/stringprintf.h" 21185d134a3b43ab7529053e965917e0fa74bceba4Alex Light#include "base/logging.h" 22185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 23185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightnamespace art { 24185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 25185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightconst char* PLUGIN_INITIALIZATION_FUNCTION_NAME = "ArtPlugin_Initialize"; 26185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightconst char* PLUGIN_DEINITIALIZATION_FUNCTION_NAME = "ArtPlugin_Deinitialize"; 27185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 28185d134a3b43ab7529053e965917e0fa74bceba4Alex LightPlugin::Plugin(const Plugin& other) : library_(other.library_), dlopen_handle_(nullptr) { 29185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (other.IsLoaded()) { 30185d134a3b43ab7529053e965917e0fa74bceba4Alex Light std::string err; 31185d134a3b43ab7529053e965917e0fa74bceba4Alex Light Load(&err); 32185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 33185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} 34185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 35185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightbool Plugin::Load(/*out*/std::string* error_msg) { 36185d134a3b43ab7529053e965917e0fa74bceba4Alex Light DCHECK(!IsLoaded()); 37185d134a3b43ab7529053e965917e0fa74bceba4Alex Light void* res = dlopen(library_.c_str(), RTLD_LAZY); 38185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (res == nullptr) { 39185d134a3b43ab7529053e965917e0fa74bceba4Alex Light *error_msg = StringPrintf("dlopen failed: %s", dlerror()); 40185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return false; 41185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 42185d134a3b43ab7529053e965917e0fa74bceba4Alex Light // Get the initializer function 43185d134a3b43ab7529053e965917e0fa74bceba4Alex Light PluginInitializationFunction init = reinterpret_cast<PluginInitializationFunction>( 44185d134a3b43ab7529053e965917e0fa74bceba4Alex Light dlsym(res, PLUGIN_INITIALIZATION_FUNCTION_NAME)); 45185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (init != nullptr) { 46185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (!init()) { 47185d134a3b43ab7529053e965917e0fa74bceba4Alex Light dlclose(res); 48185d134a3b43ab7529053e965917e0fa74bceba4Alex Light *error_msg = StringPrintf("Initialization of plugin failed"); 49185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return false; 50185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 51185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } else { 52185d134a3b43ab7529053e965917e0fa74bceba4Alex Light LOG(WARNING) << this << " does not include an initialization function"; 53185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 54185d134a3b43ab7529053e965917e0fa74bceba4Alex Light dlopen_handle_ = res; 55185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return true; 56185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} 57185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 58185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightbool Plugin::Unload() { 59185d134a3b43ab7529053e965917e0fa74bceba4Alex Light DCHECK(IsLoaded()); 60185d134a3b43ab7529053e965917e0fa74bceba4Alex Light bool ret = true; 61185d134a3b43ab7529053e965917e0fa74bceba4Alex Light void* handle = dlopen_handle_; 62185d134a3b43ab7529053e965917e0fa74bceba4Alex Light PluginDeinitializationFunction deinit = reinterpret_cast<PluginDeinitializationFunction>( 63185d134a3b43ab7529053e965917e0fa74bceba4Alex Light dlsym(handle, PLUGIN_DEINITIALIZATION_FUNCTION_NAME)); 64185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (deinit != nullptr) { 65185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (!deinit()) { 66185d134a3b43ab7529053e965917e0fa74bceba4Alex Light LOG(WARNING) << this << " failed deinitialization"; 67185d134a3b43ab7529053e965917e0fa74bceba4Alex Light ret = false; 68185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 69185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } else { 70185d134a3b43ab7529053e965917e0fa74bceba4Alex Light LOG(WARNING) << this << " does not include a deinitialization function"; 71185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 72185d134a3b43ab7529053e965917e0fa74bceba4Alex Light dlopen_handle_ = nullptr; 73185d134a3b43ab7529053e965917e0fa74bceba4Alex Light if (dlclose(handle) != 0) { 74185d134a3b43ab7529053e965917e0fa74bceba4Alex Light LOG(ERROR) << this << " failed to dlclose: " << dlerror(); 75185d134a3b43ab7529053e965917e0fa74bceba4Alex Light ret = false; 76185d134a3b43ab7529053e965917e0fa74bceba4Alex Light } 77185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return ret; 78185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} 79185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 80185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightstd::ostream& operator<<(std::ostream &os, const Plugin* m) { 81185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return os << *m; 82185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} 83185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 84185d134a3b43ab7529053e965917e0fa74bceba4Alex Lightstd::ostream& operator<<(std::ostream &os, Plugin const& m) { 85185d134a3b43ab7529053e965917e0fa74bceba4Alex Light return os << "Plugin { library=\"" << m.library_ << "\", handle=" << m.dlopen_handle_ << " }"; 86185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} 87185d134a3b43ab7529053e965917e0fa74bceba4Alex Light 88185d134a3b43ab7529053e965917e0fa74bceba4Alex Light} // namespace art 89