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