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