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