Home | History | Annotate | Download | only in include
      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_H
     18 #define ELF_SYMBOL_H
     19 
     20 #include "ELFTypes.h"
     21 #include "ELF.h"
     22 
     23 #include <string>
     24 #include <algorithm>
     25 
     26 #include <stdint.h>
     27 #include <stdlib.h>
     28 
     29 class ELFSymbolHelperMixin {
     30 protected:
     31   static char const *getTypeStr(uint8_t);
     32   static char const *getBindingAttributeStr(uint8_t);
     33   static char const *getVisibilityStr(uint8_t);
     34 };
     35 
     36 template <unsigned Bitwidth>
     37 class ELFSymbol_CRTP : private ELFSymbolHelperMixin {
     38 public:
     39   ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
     40 
     41 protected:
     42   ELFObject<Bitwidth> const *owner;
     43 
     44   size_t index;
     45 
     46   word_t st_name;
     47   byte_t st_info;
     48   byte_t st_other;
     49   half_t st_shndx;
     50   addr_t st_value;
     51   symsize_t st_size;
     52 
     53   mutable void *my_addr;
     54 
     55 protected:
     56   ELFSymbol_CRTP() { my_addr = 0; }
     57 
     58   ~ELFSymbol_CRTP() {
     59 #if 0
     60     if (my_addr != 0 &&
     61         getType() == STT_OBJECT &&
     62         getSectionIndex() == SHN_COMMON) {
     63       std::free(my_addr);
     64     }
     65 #endif
     66   }
     67 
     68 public:
     69   size_t getIndex() const {
     70     return index;
     71   }
     72 
     73   word_t getNameIndex() const {
     74     return st_name;
     75   }
     76 
     77   char const *getName() const;
     78 
     79 // I don't want to include elf.h in .h file, so define those macro by ourself.
     80 #define ELF_ST_BIND(i)   ((i)>>4)
     81 #define ELF_ST_TYPE(i)   ((i)&0xf)
     82 #define ELF_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
     83   byte_t getType() const {
     84     return ELF_ST_TYPE(st_info);
     85   }
     86 
     87   byte_t getBindingAttribute() const {
     88     return ELF_ST_BIND(st_info);
     89   }
     90 #undef ELF_ST_BIND
     91 #undef ELF_ST_TYPE
     92 #undef ELF_ST_INFO
     93 
     94 #define ELF_ST_VISIBILITY(o) ((o)&0x3)
     95   byte_t getVisibility() const {
     96     return ELF_ST_VISIBILITY(st_other);
     97   }
     98 #undef ELF_ST_VISIBILITY
     99 
    100   half_t getSectionIndex() const {
    101     return st_shndx;
    102   }
    103 
    104   addr_t getValue() const {
    105     return st_value;
    106   }
    107 
    108   symsize_t getSize() const {
    109     return st_size;
    110   }
    111 
    112   void *getAddress(int machine, bool autoAlloc = true) const;
    113 
    114   void setAddress(void *addr) {
    115     my_addr = addr;
    116   }
    117 
    118   bool isValid() const {
    119     // FIXME: Should check the correctness of the section header.
    120     return true;
    121   }
    122 
    123   bool isConcreteFunc() const {
    124     return getType() == STT_FUNC;
    125   }
    126 
    127   bool isExternFunc() const {
    128     return getType() == STT_NOTYPE;
    129   }
    130 
    131   template <typename Archiver>
    132   static ELFSymbolTy *
    133   read(Archiver &AR, ELFObject<Bitwidth> const *owner, size_t index = 0);
    134 
    135   void print(bool shouldPrintHeader = false) const;
    136 
    137 private:
    138   ELFSymbolTy *concrete() {
    139     return static_cast<ELFSymbolTy *>(this);
    140   }
    141 
    142   ELFSymbolTy const *concrete() const {
    143     return static_cast<ELFSymbolTy const *>(this);
    144   }
    145 };
    146 
    147 template <>
    148 class ELFSymbol<32> : public ELFSymbol_CRTP<32> {
    149   friend class ELFSymbol_CRTP<32>;
    150 
    151 private:
    152   ELFSymbol() {
    153   }
    154 
    155   template <typename Archiver>
    156   bool serialize(Archiver &AR) {
    157     AR.prologue(TypeTraits<ELFSymbol>::size);
    158 
    159     AR & st_name;
    160     AR & st_value;
    161     AR & st_size;
    162     AR & st_info;
    163     AR & st_other;
    164     AR & st_shndx;
    165 
    166     AR.epilogue(TypeTraits<ELFSymbol>::size);
    167     return AR;
    168   }
    169 };
    170 
    171 template <>
    172 class ELFSymbol<64> : public ELFSymbol_CRTP<64> {
    173   friend class ELFSymbol_CRTP<64>;
    174 
    175 private:
    176   ELFSymbol() {
    177   }
    178 
    179   template <typename Archiver>
    180   bool serialize(Archiver &AR) {
    181     AR.prologue(TypeTraits<ELFSymbol>::size);
    182 
    183     AR & st_name;
    184     AR & st_info;
    185     AR & st_other;
    186     AR & st_shndx;
    187     AR & st_value;
    188     AR & st_size;
    189 
    190     AR.epilogue(TypeTraits<ELFSymbol>::size);
    191     return AR;
    192   }
    193 };
    194 
    195 #include "impl/ELFSymbol.hxx"
    196 
    197 #endif // ELF_SYMBOL_H
    198