Home | History | Annotate | Download | only in ExecutionEngine
      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