1 /* 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 #include "component_loader/DllLoader.h" 18 19 #include <dlfcn.h> 20 21 #include <iostream> 22 23 #include "hardware/hardware.h" 24 25 using namespace std; 26 27 namespace android { 28 namespace vts { 29 30 DllLoader::DllLoader() : handle_(NULL), hmi_(NULL), device_(NULL) {} 31 32 DllLoader::~DllLoader() { 33 if (!handle_) { 34 dlclose(handle_); 35 handle_ = NULL; 36 } 37 } 38 39 void* DllLoader::Load(const char* file_path, bool is_conventional_hal) { 40 if (!file_path) { 41 cerr << __func__ << ": file_path is NULL" << endl; 42 return NULL; 43 } 44 45 // consider using the load mechanism in hardware/libhardware/hardware.c 46 handle_ = dlopen(file_path, RTLD_LAZY); 47 if (!handle_) { 48 cerr << __func__ << ": " << dlerror() << endl; 49 cerr << __func__ << ": Can't load a shared library, " << file_path << "." 50 << endl; 51 return NULL; 52 } 53 cout << __func__ << ": DLL loaded " << file_path << endl; 54 if (is_conventional_hal) { 55 cout << __func__ << ": setting hmi" << endl; 56 hmi_ = (struct hw_module_t*)LoadSymbol(HAL_MODULE_INFO_SYM_AS_STR); 57 } 58 return handle_; 59 } 60 61 struct hw_module_t* DllLoader::InitConventionalHal() { 62 if (!handle_) { 63 cerr << __func__ << ": handle_ is NULL" << endl; 64 return NULL; 65 } 66 hmi_ = (struct hw_module_t*)LoadSymbol(HAL_MODULE_INFO_SYM_AS_STR); 67 if (!hmi_) { 68 return NULL; 69 } 70 cout << __func__ << ":" << __LINE__ << endl; 71 hmi_->dso = handle_; 72 device_ = NULL; 73 cout << __func__ << ": version " << hmi_->module_api_version << endl; 74 return hmi_; 75 } 76 77 struct hw_device_t* DllLoader::OpenConventionalHal(const char* module_name) { 78 cout << __func__ << endl; 79 if (!handle_) { 80 cerr << __func__ << ": handle_ is NULL" << endl; 81 return NULL; 82 } 83 if (!hmi_) { 84 cerr << __func__ << ": hmi_ is NULL" << endl; 85 return NULL; 86 } 87 88 device_ = NULL; 89 int ret; 90 if (module_name && strlen(module_name) > 0) { 91 cout << __func__ << ":" << __LINE__ << ": module_name |" << module_name 92 << "|" << endl; 93 ret = 94 hmi_->methods->open(hmi_, module_name, (struct hw_device_t**)&device_); 95 } else { 96 cout << __func__ << ":" << __LINE__ << ": (default) " << hmi_->name 97 << endl; 98 ret = hmi_->methods->open(hmi_, hmi_->name, (struct hw_device_t**)&device_); 99 } 100 if (ret != 0) { 101 cout << "returns " << ret << " " << strerror(errno) << endl; 102 } 103 cout << __func__ << ":" << __LINE__ << " device_ " << device_ << endl; 104 return device_; 105 } 106 107 loader_function DllLoader::GetLoaderFunction(const char* function_name) { 108 loader_function func = (loader_function)LoadSymbol(function_name); 109 return func; 110 } 111 112 bool DllLoader::SancovResetCoverage() { 113 void (*func)() = (void (*)())LoadSymbol("__sanitizer_reset_coverage"); 114 if (func == NULL) { 115 return false; 116 } 117 func(); 118 return true; 119 } 120 121 bool DllLoader::GcovInit(writeout_fn wfn, flush_fn ffn) { 122 void (*func)(writeout_fn, flush_fn) = 123 (void (*)(writeout_fn, flush_fn))LoadSymbol("llvm_gcov_init"); 124 if (func == NULL) { 125 return false; 126 } 127 func(wfn, ffn); 128 return true; 129 } 130 131 bool DllLoader::GcovFlush() { 132 void (*func)() = (void (*)()) LoadSymbol("__gcov_flush"); 133 if (func == NULL) { 134 return false; 135 } 136 func(); 137 return true; 138 } 139 140 void* DllLoader::LoadSymbol(const char* symbol_name) { 141 const char* error = dlerror(); 142 if (error != NULL) { 143 cerr << __func__ << ": existing error message before loading " 144 << symbol_name << endl; 145 cerr << __func__ << ": " << error << endl; 146 } 147 void* sym = dlsym(handle_, symbol_name); 148 if ((error = dlerror()) != NULL) { 149 cerr << __func__ << ": Can't find " << symbol_name << endl; 150 cerr << __func__ << ": " << error << endl; 151 return NULL; 152 } 153 return sym; 154 } 155 156 } // namespace vts 157 } // namespace android 158