Home | History | Annotate | Download | only in impl
      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 #ifndef ELF_SYMBOL_HXX
     18 #define ELF_SYMBOL_HXX
     19 
     20 #include "ELFSectionHeaderTable.h"
     21 #include "ELFSection.h"
     22 #include "ELFSectionStrTab.h"
     23 
     24 #include "ELFObject.h"
     25 #include "ELFSectionHeaderTable.h"
     26 #include "ELFSectionProgBits.h"
     27 #include "ELFSectionNoBits.h"
     28 
     29 #include "utils/rsl_assert.h"
     30 #include "ELF.h"
     31 
     32 #ifdef __arm__
     33 #define LOG_TAG "bcc"
     34 #include "cutils/log.h"
     35 #endif
     36 
     37 template <unsigned Bitwidth>
     38 inline char const *ELFSymbol_CRTP<Bitwidth>::getName() const {
     39   ELFSectionHeaderTableTy const &shtab = *owner->getSectionHeaderTable();
     40   size_t const index = shtab.getByName(std::string(".strtab"))->getIndex();
     41   ELFSectionTy const *section = owner->getSectionByIndex(index);
     42   ELFSectionStrTabTy const &strtab =
     43     *static_cast<ELFSectionStrTabTy const *>(section);
     44   return strtab[getNameIndex()];
     45 }
     46 
     47 template <unsigned Bitwidth>
     48 template <typename Archiver>
     49 inline ELFSymbol<Bitwidth> *
     50 ELFSymbol_CRTP<Bitwidth>::read(Archiver &AR,
     51                                ELFObjectTy const *owner,
     52                                size_t index) {
     53   if (!AR) {
     54     // Archiver is in bad state before calling read function.
     55     // Return NULL and do nothing.
     56     return 0;
     57   }
     58 
     59   llvm::OwningPtr<ELFSymbolTy> sh(new ELFSymbolTy());
     60 
     61   if (!sh->serialize(AR)) {
     62     // Unable to read the structure.  Return NULL.
     63     return 0;
     64   }
     65 
     66   if (!sh->isValid()) {
     67     // SymTabEntry read from archiver is not valid.  Return NULL.
     68     return 0;
     69   }
     70 
     71   // Set the section header index
     72   sh->index = index;
     73 
     74   // Set the owner elf object
     75   sh->owner = owner;
     76 
     77   return sh.take();
     78 }
     79 
     80 template <unsigned Bitwidth>
     81 inline void ELFSymbol_CRTP<Bitwidth>::print(bool shouldPrintHeader) const {
     82   using namespace llvm;
     83 
     84   if (shouldPrintHeader) {
     85     out() << '\n' << fillformat('=', 79) << '\n';
     86     out().changeColor(raw_ostream::WHITE, true);
     87     out() << "ELF Symbol Table Entry "
     88           << this->getIndex() << '\n';
     89     out().resetColor();
     90     out() << fillformat('-', 79) << '\n';
     91   } else {
     92     out() << fillformat('-', 79) << '\n';
     93     out().changeColor(raw_ostream::YELLOW, true);
     94     out() << "ELF Symbol Table Entry "
     95           << this->getIndex() << " : " << '\n';
     96     out().resetColor();
     97   }
     98 
     99 #define PRINT_LINT(title, value) \
    100   out() << format("  %-11s : ", (char const *)(title)) << (value) << '\n'
    101   PRINT_LINT("Name",        getName()                                    );
    102   PRINT_LINT("Type",        getTypeStr(getType())                        );
    103   PRINT_LINT("Bind",        getBindingAttributeStr(getBindingAttribute()));
    104   PRINT_LINT("Visibility",  getVisibilityStr(getVisibility())            );
    105   PRINT_LINT("Shtab Index", getSectionIndex()                            );
    106   PRINT_LINT("Value",       getValue()                                   );
    107   PRINT_LINT("Size",        getSize()                                    );
    108 #undef PRINT_LINT
    109 
    110 // TODO: Horizontal type or vertical type can use option to decide.
    111 #if 0
    112   using namespace term::color;
    113   using namespace std;
    114 
    115   cout << setw(20) << getName() <<
    116           setw(10) << getTypeStr(getType()) <<
    117           setw(10) << getBindingAttributeStr(getBindingAttribute()) <<
    118           setw(15) << getVisibilityStr(getVisibility()) <<
    119           setw(10) << getSectionIndex() <<
    120           setw(7) << getValue() <<
    121           setw(7) << getSize() <<
    122           endl;
    123 #endif
    124 }
    125 
    126 template <unsigned Bitwidth>
    127 void *ELFSymbol_CRTP<Bitwidth>::getAddress(bool autoAlloc) const {
    128   if (my_addr != 0) {
    129     return my_addr;
    130   }
    131   size_t idx = (size_t)getSectionIndex();
    132   switch (getType()) {
    133     default:
    134       break;
    135 
    136     case STT_OBJECT:
    137       switch (idx) {
    138         default:
    139           {
    140             ELFSectionHeaderTableTy const *header =
    141               owner->getSectionHeaderTable();
    142 
    143             unsigned section_type = (*header)[idx]->getType();
    144 
    145             rsl_assert((section_type == SHT_PROGBITS ||
    146                         section_type == SHT_NOBITS) &&
    147                        "STT_OBJECT with not BITS section.");
    148 
    149             if (section_type == SHT_NOBITS) {
    150               // FIXME(logan): This is a workaround for .lcomm directives
    151               // bug of LLVM ARM MC code generator.  Remove this when the
    152               // LLVM bug is fixed.
    153 
    154               size_t align = 16;
    155 
    156               my_addr = const_cast<ELFObjectTy *>(owner)->
    157                 allocateSHNCommonData((size_t)getSize(), align);
    158 
    159               if (!my_addr) {
    160                 rsl_assert(0 && "Unable to allocate memory for SHN_COMMON.");
    161                 abort();
    162               }
    163             } else {
    164               ELFSectionTy const *sec = owner->getSectionByIndex(idx);
    165               rsl_assert(sec != 0 && "STT_OBJECT with null section.");
    166 
    167               ELFSectionBitsTy const &st =
    168                 static_cast<ELFSectionBitsTy const &>(*sec);
    169               my_addr =const_cast<unsigned char *>(&st[0] + (off_t)getValue());
    170             }
    171 
    172 #if 0
    173 #ifdef __arm__
    174             LOGD("Symbol %s\n", getName());
    175             if (strcmp(getName(), "camera") == 0) {
    176               uint32_t *p = (uint32_t *)(&st[0] + (size_t)getValue());
    177               LOGD("     | %08x %08x %08x %08x\n", p[0], p[1], p[2], p[3]);
    178               LOGD("     | %08x %08x %08x %08x\n", p[4], p[5], p[6], p[7]);
    179               LOGD("     | %08x %08x %08x %08x\n", p[8], p[9], p[10], p[11]);
    180               LOGD("     | %08x %08x %08x %08x\n", p[12], p[13], p[14], p[15]);
    181             }
    182 #endif
    183 #endif
    184           }
    185           break;
    186 
    187         case SHN_COMMON:
    188           {
    189             if (!autoAlloc) {
    190               return NULL;
    191             }
    192 #if 0
    193 #if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
    194             if (posix_memalign(&my_addr,
    195                                std::max((size_t)getValue(), sizeof(void*)),
    196                                (size_t)getSize()) != 0) {
    197               rsl_assert(0 && "posix_memalign failed.");
    198             }
    199 #else
    200             my_addr = memalign(std::max((size_t)getValue(), sizeof(void *)),
    201                                (size_t)getSize());
    202 
    203             rsl_assert(my_addr != NULL && "memalign failed.");
    204 #endif
    205             if (my_addr) {
    206               memset(my_addr, '\0', getSize());
    207             }
    208 #else
    209             size_t align = (size_t)getValue();
    210             my_addr = const_cast<ELFObjectTy *>(owner)->
    211                           allocateSHNCommonData((size_t)getSize(), align);
    212             if (!my_addr) {
    213               rsl_assert(0 && "Unable to allocate memory for SHN_COMMON.");
    214               abort();
    215             }
    216 #endif
    217           }
    218           break;
    219 
    220         case SHN_ABS:
    221         case SHN_UNDEF:
    222         case SHN_XINDEX:
    223           rsl_assert(0 && "STT_OBJECT with special st_shndx.");
    224           break;
    225       }
    226       break;
    227 
    228 
    229     case STT_FUNC:
    230       switch (idx) {
    231         default:
    232           {
    233 #ifndef NDEBUG
    234             ELFSectionHeaderTableTy const *header =
    235               owner->getSectionHeaderTable();
    236             rsl_assert((*header)[idx]->getType() == SHT_PROGBITS &&
    237                    "STT_FUNC with not PROGBITS section.");
    238 #endif
    239             ELFSectionTy const *sec = owner->getSectionByIndex(idx);
    240             rsl_assert(sec != 0 && "STT_FUNC with null section.");
    241 
    242             ELFSectionProgBitsTy const &st =
    243               static_cast<ELFSectionProgBitsTy const &>(*sec);
    244             my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
    245           }
    246           break;
    247 
    248         case SHN_ABS:
    249         case SHN_COMMON:
    250         case SHN_UNDEF:
    251         case SHN_XINDEX:
    252           rsl_assert(0 && "STT_FUNC with special st_shndx.");
    253           break;
    254       }
    255       break;
    256 
    257 
    258     case STT_SECTION:
    259       switch (idx) {
    260         default:
    261           {
    262 #ifndef NDEBUG
    263             ELFSectionHeaderTableTy const *header =
    264               owner->getSectionHeaderTable();
    265             rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS ||
    266                     (*header)[idx]->getType() == SHT_NOBITS) &&
    267                    "STT_SECTION with not BITS section.");
    268 #endif
    269             ELFSectionTy const *sec = owner->getSectionByIndex(idx);
    270             rsl_assert(sec != 0 && "STT_SECTION with null section.");
    271 
    272             ELFSectionBitsTy const &st =
    273               static_cast<ELFSectionBitsTy const &>(*sec);
    274             my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
    275           }
    276           break;
    277 
    278         case SHN_ABS:
    279         case SHN_COMMON:
    280         case SHN_UNDEF:
    281         case SHN_XINDEX:
    282           rsl_assert(0 && "STT_SECTION with special st_shndx.");
    283           break;
    284       }
    285       break;
    286 
    287     case STT_NOTYPE:
    288       switch (idx) {
    289         default:
    290           {
    291 #ifndef NDEBUG
    292             ELFSectionHeaderTableTy const *header =
    293               owner->getSectionHeaderTable();
    294             rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS ||
    295                     (*header)[idx]->getType() == SHT_NOBITS) &&
    296                    "STT_SECTION with not BITS section.");
    297 #endif
    298             ELFSectionTy const *sec = owner->getSectionByIndex(idx);
    299             rsl_assert(sec != 0 && "STT_SECTION with null section.");
    300 
    301             ELFSectionBitsTy const &st =
    302               static_cast<ELFSectionBitsTy const &>(*sec);
    303             my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
    304           }
    305           break;
    306 
    307         case SHN_ABS:
    308         case SHN_COMMON:
    309         case SHN_XINDEX:
    310           rsl_assert(0 && "STT_SECTION with special st_shndx.");
    311           break;
    312         case SHN_UNDEF:
    313           return 0;
    314       }
    315       break;
    316       return 0;
    317 
    318     case STT_COMMON:
    319     case STT_FILE:
    320     case STT_TLS:
    321     case STT_LOOS:
    322     case STT_HIOS:
    323     case STT_LOPROC:
    324     case STT_HIPROC:
    325       rsl_assert(0 && "Not implement.");
    326       return 0;
    327   }
    328   return my_addr;
    329 }
    330 
    331 #endif // ELF_SYMBOL_HXX
    332