1 /* 2 * Copyright 2012, 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 "bcc/ExecutionEngine/SymbolResolvers.h" 18 19 #if !defined(_WIN32) /* TODO create a HAVE_DLFCN_H */ 20 #include <dlfcn.h> 21 #else 22 /* TODO hack: definitions from bionic/libc/include/dlfcn.h */ 23 void* dlopen(const char* filename, int flag) { 24 return NULL; 25 } 26 27 int dlclose(void* handle) { 28 return -1; 29 } 30 31 const char* dlerror(void) { 32 return "Unspecified error!"; 33 } 34 35 void* dlsym(void* handle, const char* symbol) { 36 return NULL; 37 } 38 39 #define RTLD_NOW 0 40 #define RTLD_LAZY 1 41 #define RTLD_LOCAL 0 42 #define RTLD_GLOBAL 2 43 #define RTLD_DEFAULT ((void*) 0xffffffff) 44 #define RTLD_NEXT ((void*) 0xfffffffe) 45 #endif 46 47 #include <cassert> 48 #include <cstdio> 49 #include <new> 50 51 using namespace bcc; 52 53 //===----------------------------------------------------------------------===// 54 // DyldSymbolResolver 55 //===----------------------------------------------------------------------===// 56 DyldSymbolResolver::DyldSymbolResolver(const char *pFileName, 57 bool pLazyBinding) : mError(NULL) { 58 int flags = (pLazyBinding) ? RTLD_LAZY : RTLD_NOW; 59 60 // Make the symbol within the given library to be local such that it won't 61 // be available for symbol resolution of subsequently loaded libraries. 62 flags |= RTLD_LOCAL; 63 64 mHandle = ::dlopen(pFileName, flags); 65 if (mHandle == NULL) { 66 const char *err = ::dlerror(); 67 68 #define DYLD_ERROR_MSG_PATTERN "Failed to load %s! (%s)" 69 size_t error_length = ::strlen(DYLD_ERROR_MSG_PATTERN) + 70 ::strlen(pFileName) + 1; 71 if (err != NULL) { 72 error_length += ::strlen(err); 73 } 74 75 mError = new (std::nothrow) char [error_length]; 76 if (mError != NULL) { 77 ::snprintf(mError, error_length, DYLD_ERROR_MSG_PATTERN, pFileName, 78 ((err != NULL) ? err : "")); 79 } 80 } 81 #undef DYLD_ERROR_MSG_PATTERN 82 } 83 84 void *DyldSymbolResolver::getAddress(const char *pName) { 85 assert((mHandle != NULL) && "Invalid DyldSymbolResolver!"); 86 return ::dlsym(mHandle, pName); 87 } 88 89 DyldSymbolResolver::~DyldSymbolResolver() { 90 if (mHandle != NULL) { 91 ::dlclose(mHandle); 92 mHandle = NULL; 93 } 94 delete [] mError; 95 } 96