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 #ifndef BCC_EXECUTION_ENGINE_SYMBOL_RESOLVERS_H 18 #define BCC_EXECUTION_ENGINE_SYMBOL_RESOLVERS_H 19 20 #include <cstdlib> 21 #include <cstring> 22 23 #include "SymbolResolverInterface.h" 24 25 namespace bcc { 26 27 /* 28 * Symbol lookup via dlopen()/dlsym(). 29 */ 30 class DyldSymbolResolver : public SymbolResolverInterface { 31 public: 32 typedef void *HandleTy; 33 34 private: 35 HandleTy mHandle; 36 char *mError; 37 38 public: 39 // If pFileName is NULL, it will search symbol in the current process image. 40 DyldSymbolResolver(const char *pFileName, bool pLazyBinding = true); 41 42 virtual void *getAddress(const char *pName); 43 44 inline bool hasError() const 45 { return (mError != NULL); } 46 inline const char *getError() const 47 { return mError; } 48 49 ~DyldSymbolResolver(); 50 }; 51 52 /* 53 * Symbol lookup by searching through an array of SymbolMap. 54 */ 55 template<typename Subclass> 56 class ArraySymbolResolver : public SymbolResolverInterface { 57 public: 58 typedef struct { 59 // Symbol name 60 const char *mName; 61 // Symbol address 62 void *mAddr; 63 } SymbolMap; 64 65 private: 66 // True if the symbol name is sorted in the array. 67 bool mSorted; 68 69 static int CompareSymbolName(const void *pA, const void *pB) { 70 return ::strcmp(reinterpret_cast<const SymbolMap *>(pA)->mName, 71 reinterpret_cast<const SymbolMap *>(pB)->mName); 72 } 73 74 public: 75 ArraySymbolResolver(bool pSorted = false) : mSorted(pSorted) { } 76 77 virtual void *getAddress(const char *pName) { 78 const SymbolMap *result = NULL; 79 80 if (mSorted) { 81 // Use binary search. 82 const SymbolMap key = { pName, NULL }; 83 84 result = reinterpret_cast<SymbolMap *>( 85 ::bsearch(&key, Subclass::SymbolArray, 86 Subclass::NumSymbols, 87 sizeof(SymbolMap), 88 CompareSymbolName)); 89 } else { 90 // Use linear search. 91 for (size_t i = 0; i < Subclass::NumSymbols; i++) { 92 if (::strcmp(Subclass::SymbolArray[i].mName, pName) == 0) { 93 result = &Subclass::SymbolArray[i]; 94 break; 95 } 96 } 97 } 98 99 return ((result != NULL) ? result->mAddr : NULL); 100 } 101 }; 102 103 template<typename ContextTy = void *> 104 class LookupFunctionSymbolResolver : public SymbolResolverInterface { 105 public: 106 typedef void *(*LookupFunctionTy)(ContextTy pContext, const char *pName); 107 108 private: 109 LookupFunctionTy mLookupFunc; 110 ContextTy mContext; 111 112 public: 113 LookupFunctionSymbolResolver(LookupFunctionTy pLookupFunc = NULL, 114 ContextTy pContext = NULL) 115 : mLookupFunc(pLookupFunc), mContext(pContext) { } 116 117 virtual void *getAddress(const char *pName) { 118 return ((mLookupFunc != NULL) ? mLookupFunc(mContext, pName) : NULL); 119 } 120 121 inline LookupFunctionTy getLookupFunction() const 122 { return mLookupFunc; } 123 inline ContextTy getContext() const 124 { return mContext; } 125 126 inline void setLookupFunction(LookupFunctionTy pLookupFunc) 127 { mLookupFunc = pLookupFunc; } 128 inline void setContext(ContextTy pContext) 129 { mContext = pContext; } 130 }; 131 132 } // end namespace bcc 133 134 #endif // BCC_EXECUTION_ENGINE_SYMBOL_RESOLVERS_H 135