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: ELFSymbol_CRTP()58 ELFSymbol_CRTP() { my_addr = 0; } 59 ~ELFSymbol_CRTP()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: getIndex()71 size_t getIndex() const { 72 return index; 73 } 74 getNameIndex()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)) getType()85 byte_t getType() const { 86 return ELF_ST_TYPE(st_info); 87 } 88 getBindingAttribute()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) getVisibility()97 byte_t getVisibility() const { 98 return ELF_ST_VISIBILITY(st_other); 99 } 100 #undef ELF_ST_VISIBILITY 101 getSectionIndex()102 half_t getSectionIndex() const { 103 return st_shndx; 104 } 105 getValue()106 addr_t getValue() const { 107 return st_value; 108 } 109 getSize()110 symsize_t getSize() const { 111 return st_size; 112 } 113 114 void *getAddress(int machine, bool autoAlloc = true) const; 115 setAddress(void * addr)116 void setAddress(void *addr) { 117 my_addr = addr; 118 } 119 isValid()120 bool isValid() const { 121 // FIXME: Should check the correctness of the section header. 122 return true; 123 } 124 isConcreteFunc()125 bool isConcreteFunc() const { 126 return getType() == STT_FUNC; 127 } 128 isExternFunc()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: concrete()140 ELFSymbolTy *concrete() { 141 return static_cast<ELFSymbolTy *>(this); 142 } 143 concrete()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: ELFSymbol()154 ELFSymbol() { 155 } 156 157 template <typename Archiver> serialize(Archiver & AR)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: ELFSymbol()178 ELFSymbol() { 179 } 180 181 template <typename Archiver> serialize(Archiver & AR)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