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