Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright 2011, 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 #include "librsloader.h"
     18 
     19 #include "ELFObject.h"
     20 #include "ELFSectionSymTab.h"
     21 #include "ELFSymbol.h"
     22 
     23 #include "utils/serialize.h"
     24 
     25 #define LOG_TAG "bcc"
     26 #include "cutils/log.h"
     27 
     28 #include <llvm/ADT/OwningPtr.h>
     29 
     30 static inline RSExecRef wrap(ELFObject<32> *object) {
     31   return reinterpret_cast<RSExecRef>(object);
     32 }
     33 
     34 static inline ELFObject<32> *unwrap(RSExecRef object) {
     35   return reinterpret_cast<ELFObject<32> *>(object);
     36 }
     37 
     38 extern "C" RSExecRef
     39 rsloaderCreateExec(unsigned char const *buf,
     40                    size_t buf_size,
     41                    void *(*find_symbol)(void *, char const *),
     42                    void *find_symbol_context) {
     43 
     44   ArchiveReaderLE AR(buf, buf_size);
     45 
     46   llvm::OwningPtr<ELFObject<32> > object(ELFObject<32>::read(AR));
     47   if (!object) {
     48     LOGE("Unable to load the ELF object.");
     49     return NULL;
     50   }
     51 
     52   //object->print();
     53   object->relocate(find_symbol, find_symbol_context);
     54 
     55   return wrap(object.take());
     56 }
     57 
     58 extern "C" void rsloaderDisposeExec(RSExecRef object) {
     59   delete unwrap(object);
     60 }
     61 
     62 extern "C" void *rsloaderGetSymbolAddress(RSExecRef object_,
     63                                           char const *name) {
     64   ELFObject<32> *object = unwrap(object_);
     65 
     66   ELFSectionSymTab<32> *symtab =
     67     static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab"));
     68 
     69   if (!symtab) {
     70     return NULL;
     71   }
     72 
     73   ELFSymbol<32> *symbol = symtab->getByName(name);
     74 
     75   if (!symbol) {
     76     LOGE("Symbol not found: %s\n", name);
     77     return NULL;
     78   }
     79 
     80   return symbol->getAddress(false);
     81 }
     82 
     83 extern "C" size_t rsloaderGetSymbolSize(RSExecRef object_, char const *name) {
     84   ELFObject<32> *object = unwrap(object_);
     85 
     86   ELFSectionSymTab<32> *symtab =
     87     static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab"));
     88 
     89   if (!symtab) {
     90     return NULL;
     91   }
     92 
     93   ELFSymbol<32> *symbol = symtab->getByName(name);
     94 
     95   if (!symbol) {
     96     LOGE("Symbol not found: %s\n", name);
     97     return NULL;
     98   }
     99 
    100   return (size_t)symbol->getSize();
    101 }
    102 
    103 extern "C" size_t rsloaderGetFuncCount(RSExecRef object) {
    104   ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>(
    105     unwrap(object)->getSectionByName(".symtab"));
    106 
    107   if (!symtab) {
    108     return 0;
    109   }
    110 
    111   return symtab->getFuncCount();
    112 }
    113 
    114 extern "C" void rsloaderGetFuncNameList(RSExecRef object,
    115                                         size_t size,
    116                                         char const **list) {
    117   ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>(
    118     unwrap(object)->getSectionByName(".symtab"));
    119 
    120   if (symtab) {
    121     symtab->getFuncNameList(size, list);
    122   }
    123 }
    124