ELFSymbol.hxx revision 71884036ac3215a7cb9f6f95bd0902efbb344071
1#ifndef ELF_SYMBOL_HXX 2#define ELF_SYMBOL_HXX 3 4#include "ELFSectionHeaderTable.h" 5#include "ELFSection.h" 6#include "ELFSectionStrTab.h" 7 8#include "ELFObject.h" 9#include "ELFSectionHeaderTable.h" 10#include "ELFSectionProgBits.h" 11#include "ELFSectionNoBits.h" 12 13template <unsigned Bitwidth> 14inline char const *ELFSymbol_CRTP<Bitwidth>::getName() const { 15 ELFSectionHeaderTableTy const &shtab = *owner->getSectionHeaderTable(); 16 size_t const index = shtab.getByName(std::string(".strtab"))->getIndex(); 17 ELFSectionTy const *section = owner->getSectionByIndex(index); 18 ELFSectionStrTabTy const &strtab = 19 *static_cast<ELFSectionStrTabTy const *>(section); 20 return strtab[getNameIndex()]; 21} 22 23template <unsigned Bitwidth> 24template <typename Archiver> 25inline ELFSymbol<Bitwidth> * 26ELFSymbol_CRTP<Bitwidth>::read(Archiver &AR, 27 ELFObjectTy const *owner, 28 size_t index) { 29 if (!AR) { 30 // Archiver is in bad state before calling read function. 31 // Return NULL and do nothing. 32 return 0; 33 } 34 35 llvm::OwningPtr<ELFSymbolTy> sh(new ELFSymbolTy()); 36 37 if (!sh->serialize(AR)) { 38 // Unable to read the structure. Return NULL. 39 return 0; 40 } 41 42 if (!sh->isValid()) { 43 // SymTabEntry read from archiver is not valid. Return NULL. 44 return 0; 45 } 46 47 // Set the section header index 48 sh->index = index; 49 50 // Set the owner elf object 51 sh->owner = owner; 52 53 return sh.take(); 54} 55 56template <unsigned Bitwidth> 57inline void ELFSymbol_CRTP<Bitwidth>::print(bool shouldPrintHeader) const { 58 using namespace llvm; 59 60 if (shouldPrintHeader) { 61 out() << '\n' << fillformat('=', 79) << '\n'; 62 out().changeColor(raw_ostream::WHITE, true); 63 out() << "ELF Symbol Table Entry " 64 << this->getIndex() << '\n'; 65 out().resetColor(); 66 out() << fillformat('-', 79) << '\n'; 67 } else { 68 out() << fillformat('-', 79) << '\n'; 69 out().changeColor(raw_ostream::YELLOW, true); 70 out() << "ELF Symbol Table Entry " 71 << this->getIndex() << " : " << '\n'; 72 out().resetColor(); 73 } 74 75#define PRINT_LINT(title, value) \ 76 out() << format(" %-11s : ", (char const *)(title)) << (value) << '\n' 77 PRINT_LINT("Name", getName() ); 78 PRINT_LINT("Type", getTypeStr(getType()) ); 79 PRINT_LINT("Bind", getBindingAttributeStr(getBindingAttribute())); 80 PRINT_LINT("Visibility", getVisibilityStr(getVisibility()) ); 81 PRINT_LINT("Shtab Index", getSectionIndex() ); 82 PRINT_LINT("Value", getValue() ); 83 PRINT_LINT("Size", getSize() ); 84#undef PRINT_LINT 85 86// TODO: Horizontal type or vertical type can use option to decide. 87#if 0 88 using namespace term::color; 89 using namespace std; 90 91 cout << setw(20) << getName() << 92 setw(10) << getTypeStr(getType()) << 93 setw(10) << getBindingAttributeStr(getBindingAttribute()) << 94 setw(15) << getVisibilityStr(getVisibility()) << 95 setw(10) << getSectionIndex() << 96 setw(7) << getValue() << 97 setw(7) << getSize() << 98 endl; 99#endif 100} 101 102template <unsigned Bitwidth> 103void *ELFSymbol_CRTP<Bitwidth>::getAddress() const { 104 if (my_addr != 0) { 105 return my_addr; 106 } 107 size_t idx = (size_t)getSectionIndex(); 108 switch (getType()) { 109 default: 110 break; 111 112 case STT_OBJECT: 113 switch (idx) { 114 default: 115 { 116#ifndef NDEBUG 117 ELFSectionHeaderTableTy const *header = 118 owner->getSectionHeaderTable(); 119 assert(((*header)[idx]->getType() == SHT_PROGBITS || 120 (*header)[idx]->getType() == SHT_NOBITS) && 121 "STT_OBJECT with not BITS section."); 122#endif 123 ELFSectionTy const *sec = owner->getSectionByIndex(idx); 124 assert(sec != 0 && "STT_OBJECT with null section."); 125 126 ELFSectionBitsTy const &st = 127 static_cast<ELFSectionBitsTy const &>(*sec); 128 my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue()); 129 } 130 break; 131 132 case SHN_COMMON: 133 { 134#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 135 if (posix_memalign(&my_addr, 136 std::max((size_t)getValue(), sizeof(void*)), 137 (size_t)getSize()) != 0) { 138 assert(0 && "posix_memalign failed."); 139 } 140#else 141 my_addr = memalign(std::max((size_t)getValue(), sizeof(void *)), 142 (size_t)getSize()); 143 144 assert(my_addr != NULL && "memalign failed."); 145#endif 146 } 147 break; 148 149 case SHN_ABS: 150 case SHN_UNDEF: 151 case SHN_XINDEX: 152 assert(0 && "STT_OBJECT with special st_shndx."); 153 break; 154 } 155 break; 156 157 158 case STT_FUNC: 159 switch (idx) { 160 default: 161 { 162#ifndef NDEBUG 163 ELFSectionHeaderTableTy const *header = 164 owner->getSectionHeaderTable(); 165 assert((*header)[idx]->getType() == SHT_PROGBITS && 166 "STT_FUNC with not PROGBITS section."); 167#endif 168 ELFSectionTy const *sec = owner->getSectionByIndex(idx); 169 assert(sec != 0 && "STT_FUNC with null section."); 170 171 ELFSectionProgBitsTy const &st = 172 static_cast<ELFSectionProgBitsTy const &>(*sec); 173 my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue()); 174 } 175 break; 176 177 case SHN_ABS: 178 case SHN_COMMON: 179 case SHN_UNDEF: 180 case SHN_XINDEX: 181 assert(0 && "STT_FUNC with special st_shndx."); 182 break; 183 } 184 break; 185 186 187 case STT_SECTION: 188 switch (idx) { 189 default: 190 { 191#ifndef NDEBUG 192 ELFSectionHeaderTableTy const *header = 193 owner->getSectionHeaderTable(); 194 assert(((*header)[idx]->getType() == SHT_PROGBITS || 195 (*header)[idx]->getType() == SHT_NOBITS) && 196 "STT_SECTION with not BITS section."); 197#endif 198 ELFSectionTy const *sec = owner->getSectionByIndex(idx); 199 assert(sec != 0 && "STT_SECTION with null section."); 200 201 ELFSectionBitsTy const &st = 202 static_cast<ELFSectionBitsTy const &>(*sec); 203 my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue()); 204 } 205 break; 206 207 case SHN_ABS: 208 case SHN_COMMON: 209 case SHN_UNDEF: 210 case SHN_XINDEX: 211 assert(0 && "STT_SECTION with special st_shndx."); 212 break; 213 } 214 break; 215 216 case STT_NOTYPE: 217 return 0; 218 219 case STT_COMMON: 220 case STT_FILE: 221 case STT_TLS: 222 case STT_LOOS: 223 case STT_HIOS: 224 case STT_LOPROC: 225 case STT_HIPROC: 226 assert(0 && "Not implement."); 227 return 0; 228 } 229 return my_addr; 230} 231 232#endif // ELF_SYMBOL_HXX 233