Home | History | Annotate | Download | only in component_loader
      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