1337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland/* 2337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * Copyright (C) 2016 The Android Open Source Project 3337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * 4337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * Licensed under the Apache License, Version 2.0 (the "License"); 5337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * you may not use this file except in compliance with the License. 6337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * You may obtain a copy of the License at 7337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * 8337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * http://www.apache.org/licenses/LICENSE-2.0 9337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * 10337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * Unless required by applicable law or agreed to in writing, software 11337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * distributed under the License is distributed on an "AS IS" BASIS, 12337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * See the License for the specific language governing permissions and 14337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland * limitations under the License. 15337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland */ 16337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland 17337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland#define LOG_TAG "HidlInternal" 18337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland 19337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland#include <hidl/HidlInternal.h> 20337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland 21337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland#include <android-base/logging.h> 227a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang#include <cutils/properties.h> 237a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang 247a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang#ifdef LIBHIDL_TARGET_DEBUGGABLE 257a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang#include <dirent.h> 267a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang#include <dlfcn.h> 277a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang#include <regex> 287a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang#endif 29337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland 30337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Morelandnamespace android { 31337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Morelandnamespace hardware { 32337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Morelandnamespace details { 33337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland 34b7370304cbf33a6ff53ec3955cda0bf18920df48Hridya Valsarajuvoid logAlwaysFatal(const char *message) { 35337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland LOG(FATAL) << message; 36337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland} 37337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland 387a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang// ---------------------------------------------------------------------- 397a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang// HidlInstrumentor implementation. 40384792b1ed77d03d7a76f1de6880a812a0073802Steven MorelandHidlInstrumentor::HidlInstrumentor(const std::string& package, const std::string& interface) 41384792b1ed77d03d7a76f1de6880a812a0073802Steven Moreland : mEnableInstrumentation(false), 42384792b1ed77d03d7a76f1de6880a812a0073802Steven Moreland mInstrumentationLibPackage(package), 43384792b1ed77d03d7a76f1de6880a812a0073802Steven Moreland mInterfaceName(interface) { 447a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang configureInstrumentation(false); 457a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang} 467a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang 477a57de61a2017790b61ac211729a3b275f29c9baZhuoyao ZhangHidlInstrumentor:: ~HidlInstrumentor() {} 487a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang 497a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhangvoid HidlInstrumentor::configureInstrumentation(bool log) { 50384792b1ed77d03d7a76f1de6880a812a0073802Steven Moreland bool enableInstrumentation = property_get_bool( 517a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang "hal.instrumentation.enable", 527a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang false); 53384792b1ed77d03d7a76f1de6880a812a0073802Steven Moreland if (enableInstrumentation != mEnableInstrumentation) { 54384792b1ed77d03d7a76f1de6880a812a0073802Steven Moreland mEnableInstrumentation = enableInstrumentation; 557a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang if (mEnableInstrumentation) { 567a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang if (log) { 577a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang LOG(INFO) << "Enable instrumentation."; 587a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } 597a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang registerInstrumentationCallbacks (&mInstrumentationCallbacks); 607a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } else { 617a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang if (log) { 627a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang LOG(INFO) << "Disable instrumentation."; 637a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } 647a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang mInstrumentationCallbacks.clear(); 657a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } 667a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } 677a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang} 687a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang 697a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhangvoid HidlInstrumentor::registerInstrumentationCallbacks( 707a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang std::vector<InstrumentationCallback> *instrumentationCallbacks) { 717a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang#ifdef LIBHIDL_TARGET_DEBUGGABLE 727a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang std::vector<std::string> instrumentationLibPaths; 73384792b1ed77d03d7a76f1de6880a812a0073802Steven Moreland char instrumentationLibPath[PROPERTY_VALUE_MAX]; 747a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang if (property_get("hal.instrumentation.lib.path", 75384792b1ed77d03d7a76f1de6880a812a0073802Steven Moreland instrumentationLibPath, 767a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang "") > 0) { 77384792b1ed77d03d7a76f1de6880a812a0073802Steven Moreland instrumentationLibPaths.push_back(instrumentationLibPath); 787a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } else { 797a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM); 807a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR); 817a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM); 827a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } 837a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang 847a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang for (auto path : instrumentationLibPaths) { 857a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang DIR *dir = opendir(path.c_str()); 867a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang if (dir == 0) { 877a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang LOG(WARNING) << path << " does not exist. "; 887a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang return; 897a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } 907a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang 917a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang struct dirent *file; 927a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang while ((file = readdir(dir)) != NULL) { 937a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang if (!isInstrumentationLib(file)) 947a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang continue; 957a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang 967a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW); 977a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang char *error; 987a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang if (handle == nullptr) { 997a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang LOG(WARNING) << "couldn't load file: " << file->d_name 1007a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang << " error: " << dlerror(); 1017a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang continue; 1027a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } 1037a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang 1047a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang dlerror(); /* Clear any existing error */ 1057a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang 106384792b1ed77d03d7a76f1de6880a812a0073802Steven Moreland using cbFun = void (*)( 1077a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang const InstrumentationEvent, 1087a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang const char *, 1097a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang const char *, 1107a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang const char *, 1117a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang const char *, 1127a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang std::vector<void *> *); 113819c05d28de72983177620902990dff360e80e73Steven Moreland std::string package = mInstrumentationLibPackage; 114819c05d28de72983177620902990dff360e80e73Steven Moreland for (size_t i = 0; i < package.size(); i++) { 115819c05d28de72983177620902990dff360e80e73Steven Moreland if (package[i] == '.') { 116819c05d28de72983177620902990dff360e80e73Steven Moreland package[i] = '_'; 117819c05d28de72983177620902990dff360e80e73Steven Moreland continue; 118819c05d28de72983177620902990dff360e80e73Steven Moreland } 119819c05d28de72983177620902990dff360e80e73Steven Moreland 120819c05d28de72983177620902990dff360e80e73Steven Moreland if (package[i] == '@') { 121819c05d28de72983177620902990dff360e80e73Steven Moreland package[i] = '_'; 122819c05d28de72983177620902990dff360e80e73Steven Moreland package.insert(i + 1, "V"); 123819c05d28de72983177620902990dff360e80e73Steven Moreland continue; 124819c05d28de72983177620902990dff360e80e73Steven Moreland } 125819c05d28de72983177620902990dff360e80e73Steven Moreland } 126384792b1ed77d03d7a76f1de6880a812a0073802Steven Moreland auto cb = (cbFun)dlsym(handle, ("HIDL_INSTRUMENTATION_FUNCTION_" 127819c05d28de72983177620902990dff360e80e73Steven Moreland + package + "_" + mInterfaceName).c_str()); 1287a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang if ((error = dlerror()) != NULL) { 1297a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang LOG(WARNING) 1307a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION_" 131819c05d28de72983177620902990dff360e80e73Steven Moreland << package << "_" << mInterfaceName << ", error: " << error; 1327a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang continue; 1337a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } 1347a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang instrumentationCallbacks->push_back(cb); 1357a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang LOG(INFO) << "Register instrumentation callback from " 1367a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang << file->d_name; 1377a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } 1387a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang closedir(dir); 1397a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang } 1407a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang#else 1417a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang // No-op for user builds. 142ead33e2b4cb281a1be53e44a6621d9ec959f4a33Steven Moreland (void) instrumentationCallbacks; 1437a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang return; 1447a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang#endif 1457a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang} 1467a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang 1477a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhangbool HidlInstrumentor::isInstrumentationLib(const dirent *file) { 1487a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang#ifdef LIBHIDL_TARGET_DEBUGGABLE 1497a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang if (file->d_type != DT_REG) return false; 1507a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang std::cmatch cm; 1517a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang std::regex e("^" + mInstrumentationLibPackage + "(.*).profiler.so$"); 1527a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang if (std::regex_match(file->d_name, cm, e)) return true; 153ead33e2b4cb281a1be53e44a6621d9ec959f4a33Steven Moreland#else 154ead33e2b4cb281a1be53e44a6621d9ec959f4a33Steven Moreland (void) file; 1557a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang#endif 1567a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang return false; 1577a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang} 1587a57de61a2017790b61ac211729a3b275f29c9baZhuoyao Zhang 159337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland} // namespace details 160337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland} // namespace hardware 161337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland} // namespace android 162