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 17862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#ifndef BCC_EXECUTION_ENGINE_SYMBOL_RESOLVERS_H 18862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#define BCC_EXECUTION_ENGINE_SYMBOL_RESOLVERS_H 19862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 20862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#include <cstdlib> 21862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#include <cstring> 22862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 23862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#include "SymbolResolverInterface.h" 24862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 25862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changnamespace bcc { 26862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 27862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang/* 28862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * Symbol lookup via dlopen()/dlsym(). 29862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang */ 30862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changclass DyldSymbolResolver : public SymbolResolverInterface { 31862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changpublic: 32862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang typedef void *HandleTy; 33862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 34862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changprivate: 35862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang HandleTy mHandle; 36862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang char *mError; 37862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 38862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changpublic: 39862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang // If pFileName is NULL, it will search symbol in the current process image. 40862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang DyldSymbolResolver(const char *pFileName, bool pLazyBinding = true); 41862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 42862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang virtual void *getAddress(const char *pName); 43862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 44862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang inline bool hasError() const 45862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang { return (mError != NULL); } 46862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang inline const char *getError() const 47862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang { return mError; } 48862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 49862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ~DyldSymbolResolver(); 50862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang}; 51862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 52862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang/* 53862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang * Symbol lookup by searching through an array of SymbolMap. 54862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang */ 55862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changtemplate<typename Subclass> 56862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changclass ArraySymbolResolver : public SymbolResolverInterface { 57862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changpublic: 58862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang typedef struct { 59862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang // Symbol name 60862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang const char *mName; 61862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang // Symbol address 62862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang void *mAddr; 63862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } SymbolMap; 64862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 65862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changprivate: 66862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang // True if the symbol name is sorted in the array. 67862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang bool mSorted; 68862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 69862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang static int CompareSymbolName(const void *pA, const void *pB) { 70862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang return ::strcmp(reinterpret_cast<const SymbolMap *>(pA)->mName, 71862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang reinterpret_cast<const SymbolMap *>(pB)->mName); 72862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 73862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 74862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changpublic: 75862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ArraySymbolResolver(bool pSorted = false) : mSorted(pSorted) { } 76862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 77862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang virtual void *getAddress(const char *pName) { 78862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang const SymbolMap *result = NULL; 79862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 80862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang if (mSorted) { 81862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang // Use binary search. 82862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang const SymbolMap key = { pName, NULL }; 83862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 84862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang result = reinterpret_cast<SymbolMap *>( 85862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ::bsearch(&key, Subclass::SymbolArray, 86862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang Subclass::NumSymbols, 87862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang sizeof(SymbolMap), 88862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang CompareSymbolName)); 89862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } else { 90862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang // Use linear search. 91862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang for (size_t i = 0; i < Subclass::NumSymbols; i++) { 92862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang if (::strcmp(Subclass::SymbolArray[i].mName, pName) == 0) { 93862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang result = &Subclass::SymbolArray[i]; 94862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang break; 95862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 96862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 97862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 98862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 99862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang return ((result != NULL) ? result->mAddr : NULL); 100862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 101862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang}; 102862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 103862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changtemplate<typename ContextTy = void *> 104862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changclass LookupFunctionSymbolResolver : public SymbolResolverInterface { 105862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changpublic: 106862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang typedef void *(*LookupFunctionTy)(ContextTy pContext, const char *pName); 107862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 108862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changprivate: 109862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang LookupFunctionTy mLookupFunc; 110862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ContextTy mContext; 111862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 112862f3ba997e14b61dce9d341a75688951e67fd1bZonr Changpublic: 113862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang LookupFunctionSymbolResolver(LookupFunctionTy pLookupFunc = NULL, 114862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang ContextTy pContext = NULL) 115862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang : mLookupFunc(pLookupFunc), mContext(pContext) { } 116862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 117862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang virtual void *getAddress(const char *pName) { 118862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang return ((mLookupFunc != NULL) ? mLookupFunc(mContext, pName) : NULL); 119862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang } 120862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 121862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang inline LookupFunctionTy getLookupFunction() const 122862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang { return mLookupFunc; } 123862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang inline ContextTy getContext() const 124862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang { return mContext; } 125862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 126862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang inline void setLookupFunction(LookupFunctionTy pLookupFunc) 127862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang { mLookupFunc = pLookupFunc; } 128862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang inline void setContext(ContextTy pContext) 129862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang { mContext = pContext; } 130862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang}; 131862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 132862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang} // end namespace bcc 133862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang 134862f3ba997e14b61dce9d341a75688951e67fd1bZonr Chang#endif // BCC_EXECUTION_ENGINE_SYMBOL_RESOLVERS_H 135