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 19862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#include <dlfcn.h> 20862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 21862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#include <cassert> 22862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#include <cstdio> 23862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#include <new> 24862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 25862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changusing namespace bcc; 26862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 27862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang//===----------------------------------------------------------------------===// 28862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang// DyldSymbolResolver 29862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang//===----------------------------------------------------------------------===// 30862f3ba997e14b61dce9d341a75688951e67fd1bZonr ChangDyldSymbolResolver::DyldSymbolResolver(const char *pFileName, 31862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang bool pLazyBinding) : mError(NULL) { 32862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang int flags = (pLazyBinding) ? RTLD_LAZY : RTLD_NOW; 33862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 34862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang // Make the symbol within the given library to be local such that it won't 35862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang // be available for symbol resolution of subsequently loaded libraries. 36862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang flags |= RTLD_LOCAL; 37862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 38862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang mHandle = ::dlopen(pFileName, flags); 39862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang if (mHandle == NULL) { 40862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang const char *err = ::dlerror(); 41862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 42862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#define DYLD_ERROR_MSG_PATTERN "Failed to load %s! (%s)" 43862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang size_t error_length = ::strlen(DYLD_ERROR_MSG_PATTERN) + 44862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ::strlen(pFileName) + 1; 45862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang if (err != NULL) { 46862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang error_length += ::strlen(err); 47862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 48862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 49862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang mError = new (std::nothrow) char [error_length]; 50862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang if (mError != NULL) { 51862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ::snprintf(mError, error_length, DYLD_ERROR_MSG_PATTERN, pFileName, 52862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ((err != NULL) ? err : "")); 53862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 54862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 55862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#undef DYLD_ERROR_MSG_PATTERN 56862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang} 57862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 58862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changvoid *DyldSymbolResolver::getAddress(const char *pName) { 59862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang assert((mHandle != NULL) && "Invalid DyldSymbolResolver!"); 60862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang return ::dlsym(mHandle, pName); 61862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang} 62862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 63862f3ba997e14b61dce9d341a75688951e67fd1bZonr ChangDyldSymbolResolver::~DyldSymbolResolver() { 64862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ::dlclose(mHandle); 65862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang delete [] mError; 66862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang} 67