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 */ 23void* dlopen(const char* filename, int flag) { 24 return NULL; 25} 26 27int dlclose(void* handle) { 28 return -1; 29} 30 31const char* dlerror(void) { 32 return "Unspecified error!"; 33} 34 35void* 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 51using namespace bcc; 52 53//===----------------------------------------------------------------------===// 54// DyldSymbolResolver 55//===----------------------------------------------------------------------===// 56DyldSymbolResolver::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 84void *DyldSymbolResolver::getAddress(const char *pName) { 85 assert((mHandle != NULL) && "Invalid DyldSymbolResolver!"); 86 return ::dlsym(mHandle, pName); 87} 88 89DyldSymbolResolver::~DyldSymbolResolver() { 90 if (mHandle != NULL) { 91 ::dlclose(mHandle); 92 mHandle = NULL; 93 } 94 delete [] mError; 95} 96