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