ELFSymbol.hxx revision 58611fc8193e7386698178f167a2e0cbdd6a4f6f
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 int r = posix_memalign(&my_addr, 136 std::max((size_t)getValue(), sizeof(void*)), 137 (size_t)getSize()); 138 assert(r==0 && "posix_memalign failed."); 139#else 140 my_addr = memalign(std::max((size_t)getValue(), sizeof(void *)), 141 (size_t)getSize()); 142 143 assert(my_addr != NULL && "memalign failed."); 144#endif 145 } 146 break; 147 148 case SHN_ABS: 149 case SHN_UNDEF: 150 case SHN_XINDEX: 151 assert(0 && "STT_OBJECT with special st_shndx."); 152 break; 153 } 154 break; 155 156 157 case STT_FUNC: 158 switch (idx) { 159 default: 160 { 161#ifndef NDEBUG 162 ELFSectionHeaderTableTy const *header = 163 owner->getSectionHeaderTable(); 164 assert((*header)[idx]->getType() == SHT_PROGBITS && 165 "STT_FUNC with not PROGBITS section."); 166#endif 167 ELFSectionTy const *sec = owner->getSectionByIndex(idx); 168 assert(sec != 0 && "STT_FUNC with null section."); 169 170 ELFSectionProgBitsTy const &st = 171 static_cast<ELFSectionProgBitsTy const &>(*sec); 172 my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue()); 173 } 174 break; 175 176 case SHN_ABS: 177 case SHN_COMMON: 178 case SHN_UNDEF: 179 case SHN_XINDEX: 180 assert(0 && "STT_FUNC with special st_shndx."); 181 break; 182 } 183 break; 184 185 186 case STT_SECTION: 187 switch (idx) { 188 default: 189 { 190#ifndef NDEBUG 191 ELFSectionHeaderTableTy const *header = 192 owner->getSectionHeaderTable(); 193 assert(((*header)[idx]->getType() == SHT_PROGBITS || 194 (*header)[idx]->getType() == SHT_NOBITS) && 195 "STT_SECTION with not BITS section."); 196#endif 197 ELFSectionTy const *sec = owner->getSectionByIndex(idx); 198 assert(sec != 0 && "STT_SECTION with null section."); 199 200 ELFSectionBitsTy const &st = 201 static_cast<ELFSectionBitsTy const &>(*sec); 202 my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue()); 203 } 204 break; 205 206 case SHN_ABS: 207 case SHN_COMMON: 208 case SHN_UNDEF: 209 case SHN_XINDEX: 210 assert(0 && "STT_SECTION with special st_shndx."); 211 break; 212 } 213 break; 214 215 case STT_NOTYPE: 216 return 0; 217 218 case STT_COMMON: 219 case STT_FILE: 220 case STT_TLS: 221 case STT_LOOS: 222 case STT_HIOS: 223 case STT_LOPROC: 224 case STT_HIPROC: 225 assert(0 && "Not implement."); 226 return 0; 227 } 228 return my_addr; 229} 230 231#endif // ELF_SYMBOL_HXX 232