1862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang/* 2862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * Copyright 2012, The Android Open Source Project 3862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * 4862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * you may not use this file except in compliance with the License. 6862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * You may obtain a copy of the License at 7862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * 8862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * 10862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * Unless required by applicable law or agreed to in writing, software 11862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * See the License for the specific language governing permissions and 14862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * limitations under the License. 15862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang */ 16862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 17c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/ExecutionEngine/SymbolResolvers.h" 18862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 1948cd745480738c026312931877ecb8ebecb1c64eStephen Hines#if !defined(_WIN32) /* TODO create a HAVE_DLFCN_H */ 20862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#include <dlfcn.h> 2148cd745480738c026312931877ecb8ebecb1c64eStephen Hines#else 2248cd745480738c026312931877ecb8ebecb1c64eStephen Hines/* TODO hack: definitions from bionic/libc/include/dlfcn.h */ 2348cd745480738c026312931877ecb8ebecb1c64eStephen Hinesvoid* dlopen(const char* filename, int flag) { 2448cd745480738c026312931877ecb8ebecb1c64eStephen Hines return NULL; 2548cd745480738c026312931877ecb8ebecb1c64eStephen Hines} 2648cd745480738c026312931877ecb8ebecb1c64eStephen Hines 2748cd745480738c026312931877ecb8ebecb1c64eStephen Hinesint dlclose(void* handle) { 2848cd745480738c026312931877ecb8ebecb1c64eStephen Hines return -1; 2948cd745480738c026312931877ecb8ebecb1c64eStephen Hines} 3048cd745480738c026312931877ecb8ebecb1c64eStephen Hines 3148cd745480738c026312931877ecb8ebecb1c64eStephen Hinesconst char* dlerror(void) { 3248cd745480738c026312931877ecb8ebecb1c64eStephen Hines return "Unspecified error!"; 3348cd745480738c026312931877ecb8ebecb1c64eStephen Hines} 3448cd745480738c026312931877ecb8ebecb1c64eStephen Hines 3548cd745480738c026312931877ecb8ebecb1c64eStephen Hinesvoid* dlsym(void* handle, const char* symbol) { 3648cd745480738c026312931877ecb8ebecb1c64eStephen Hines return NULL; 3748cd745480738c026312931877ecb8ebecb1c64eStephen Hines} 3848cd745480738c026312931877ecb8ebecb1c64eStephen Hines 3948cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define RTLD_NOW 0 4048cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define RTLD_LAZY 1 4148cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define RTLD_LOCAL 0 4248cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define RTLD_GLOBAL 2 4348cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define RTLD_DEFAULT ((void*) 0xffffffff) 4448cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define RTLD_NEXT ((void*) 0xfffffffe) 4548cd745480738c026312931877ecb8ebecb1c64eStephen Hines#endif 46862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 47862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#include <cassert> 48862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#include <cstdio> 49862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#include <new> 50862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 51862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changusing namespace bcc; 52862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 53862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang//===----------------------------------------------------------------------===// 54862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang// DyldSymbolResolver 55862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang//===----------------------------------------------------------------------===// 56862f3ba997e14b61dce9d341a75688951e67fd1bZonr ChangDyldSymbolResolver::DyldSymbolResolver(const char *pFileName, 57862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang bool pLazyBinding) : mError(NULL) { 58862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang int flags = (pLazyBinding) ? RTLD_LAZY : RTLD_NOW; 59862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 60862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang // Make the symbol within the given library to be local such that it won't 61862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang // be available for symbol resolution of subsequently loaded libraries. 62862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang flags |= RTLD_LOCAL; 63862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 64862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang mHandle = ::dlopen(pFileName, flags); 65862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang if (mHandle == NULL) { 66862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang const char *err = ::dlerror(); 67862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 68862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#define DYLD_ERROR_MSG_PATTERN "Failed to load %s! (%s)" 69862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang size_t error_length = ::strlen(DYLD_ERROR_MSG_PATTERN) + 70862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ::strlen(pFileName) + 1; 71862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang if (err != NULL) { 72862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang error_length += ::strlen(err); 73862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 74862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 75862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang mError = new (std::nothrow) char [error_length]; 76862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang if (mError != NULL) { 77862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ::snprintf(mError, error_length, DYLD_ERROR_MSG_PATTERN, pFileName, 78862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ((err != NULL) ? err : "")); 79862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 80862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 81862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#undef DYLD_ERROR_MSG_PATTERN 82862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang} 83862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 84862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changvoid *DyldSymbolResolver::getAddress(const char *pName) { 85862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang assert((mHandle != NULL) && "Invalid DyldSymbolResolver!"); 86862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang return ::dlsym(mHandle, pName); 87862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang} 88862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 89862f3ba997e14b61dce9d341a75688951e67fd1bZonr ChangDyldSymbolResolver::~DyldSymbolResolver() { 90bae0ae1794b07482c85211c3b4d8f5e8e4da8f69Stephen Hines if (mHandle != NULL) { 91bae0ae1794b07482c85211c3b4d8f5e8e4da8f69Stephen Hines ::dlclose(mHandle); 92bae0ae1794b07482c85211c3b4d8f5e8e4da8f69Stephen Hines mHandle = NULL; 93bae0ae1794b07482c85211c3b4d8f5e8e4da8f69Stephen Hines } 94862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang delete [] mError; 95862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang} 96