ELFSymbol.hxx revision 0a2be45c942a83bb70a7cf1b7355db73cd30f9b9
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_HXX 18#define ELF_SYMBOL_HXX 19 20#include "ELFSectionHeaderTable.h" 21#include "ELFSection.h" 22#include "ELFSectionStrTab.h" 23 24#include "ELFObject.h" 25#include "ELFSectionHeaderTable.h" 26#include "ELFSectionProgBits.h" 27#include "ELFSectionNoBits.h" 28 29#include "utils/rsl_assert.h" 30#include "ELF.h" 31 32template <unsigned Bitwidth> 33inline char const *ELFSymbol_CRTP<Bitwidth>::getName() const { 34 ELFSectionHeaderTableTy const &shtab = *owner->getSectionHeaderTable(); 35 size_t const index = shtab.getByName(std::string(".strtab"))->getIndex(); 36 ELFSectionTy const *section = owner->getSectionByIndex(index); 37 ELFSectionStrTabTy const &strtab = 38 *static_cast<ELFSectionStrTabTy const *>(section); 39 return strtab[getNameIndex()]; 40} 41 42template <unsigned Bitwidth> 43template <typename Archiver> 44inline ELFSymbol<Bitwidth> * 45ELFSymbol_CRTP<Bitwidth>::read(Archiver &AR, 46 ELFObjectTy const *owner, 47 size_t index) { 48 if (!AR) { 49 // Archiver is in bad state before calling read function. 50 // Return NULL and do nothing. 51 return 0; 52 } 53 54 llvm::OwningPtr<ELFSymbolTy> sh(new ELFSymbolTy()); 55 56 if (!sh->serialize(AR)) { 57 // Unable to read the structure. Return NULL. 58 return 0; 59 } 60 61 if (!sh->isValid()) { 62 // SymTabEntry read from archiver is not valid. Return NULL. 63 return 0; 64 } 65 66 // Set the section header index 67 sh->index = index; 68 69 // Set the owner elf object 70 sh->owner = owner; 71 72 return sh.take(); 73} 74 75template <unsigned Bitwidth> 76inline void ELFSymbol_CRTP<Bitwidth>::print(bool shouldPrintHeader) const { 77 using namespace llvm; 78 79 if (shouldPrintHeader) { 80 out() << '\n' << fillformat('=', 79) << '\n'; 81 out().changeColor(raw_ostream::WHITE, true); 82 out() << "ELF Symbol Table Entry " 83 << this->getIndex() << '\n'; 84 out().resetColor(); 85 out() << fillformat('-', 79) << '\n'; 86 } else { 87 out() << fillformat('-', 79) << '\n'; 88 out().changeColor(raw_ostream::YELLOW, true); 89 out() << "ELF Symbol Table Entry " 90 << this->getIndex() << " : " << '\n'; 91 out().resetColor(); 92 } 93 94#define PRINT_LINT(title, value) \ 95 out() << format(" %-11s : ", (char const *)(title)) << (value) << '\n' 96 PRINT_LINT("Name", getName() ); 97 PRINT_LINT("Type", getTypeStr(getType()) ); 98 PRINT_LINT("Bind", getBindingAttributeStr(getBindingAttribute())); 99 PRINT_LINT("Visibility", getVisibilityStr(getVisibility()) ); 100 PRINT_LINT("Shtab Index", getSectionIndex() ); 101 PRINT_LINT("Value", getValue() ); 102 PRINT_LINT("Size", getSize() ); 103#undef PRINT_LINT 104 105// TODO: Horizontal type or vertical type can use option to decide. 106#if 0 107 using namespace term::color; 108 using namespace std; 109 110 cout << setw(20) << getName() << 111 setw(10) << getTypeStr(getType()) << 112 setw(10) << getBindingAttributeStr(getBindingAttribute()) << 113 setw(15) << getVisibilityStr(getVisibility()) << 114 setw(10) << getSectionIndex() << 115 setw(7) << getValue() << 116 setw(7) << getSize() << 117 endl; 118#endif 119} 120 121template <unsigned Bitwidth> 122void *ELFSymbol_CRTP<Bitwidth>::getAddress(bool autoAlloc) const { 123 if (my_addr != 0) { 124 return my_addr; 125 } 126 size_t idx = (size_t)getSectionIndex(); 127 switch (getType()) { 128 default: 129 break; 130 131 case STT_OBJECT: 132 switch (idx) { 133 default: 134 { 135 ELFSectionHeaderTableTy const *header = 136 owner->getSectionHeaderTable(); 137 138 unsigned section_type = (*header)[idx]->getType(); 139 140 rsl_assert((section_type == SHT_PROGBITS || 141 section_type == SHT_NOBITS) && 142 "STT_OBJECT with not BITS section."); 143 144 if (section_type == SHT_NOBITS) { 145 // FIXME(logan): This is a workaround for .lcomm directives 146 // bug of LLVM ARM MC code generator. Remove this when the 147 // LLVM bug is fixed. 148 149 size_t align = 16; 150 151 my_addr = const_cast<ELFObjectTy *>(owner)-> 152 allocateSHNCommonData((size_t)getSize(), align); 153 154 if (!my_addr) { 155 rsl_assert(0 && "Unable to allocate memory for SHN_COMMON."); 156 abort(); 157 } 158 } else { 159 ELFSectionTy const *sec = owner->getSectionByIndex(idx); 160 rsl_assert(sec != 0 && "STT_OBJECT with null section."); 161 162 ELFSectionBitsTy const &st = 163 static_cast<ELFSectionBitsTy const &>(*sec); 164 my_addr =const_cast<unsigned char *>(&st[0] + (off_t)getValue()); 165 } 166 } 167 break; 168 169 case SHN_COMMON: 170 { 171 if (!autoAlloc) { 172 return NULL; 173 } 174#if 0 175#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 176 if (posix_memalign(&my_addr, 177 std::max((size_t)getValue(), sizeof(void*)), 178 (size_t)getSize()) != 0) { 179 rsl_assert(0 && "posix_memalign failed."); 180 } 181#else 182 my_addr = memalign(std::max((size_t)getValue(), sizeof(void *)), 183 (size_t)getSize()); 184 185 rsl_assert(my_addr != NULL && "memalign failed."); 186#endif 187 if (my_addr) { 188 memset(my_addr, '\0', getSize()); 189 } 190#else 191 size_t align = (size_t)getValue(); 192 my_addr = const_cast<ELFObjectTy *>(owner)-> 193 allocateSHNCommonData((size_t)getSize(), align); 194 if (!my_addr) { 195 rsl_assert(0 && "Unable to allocate memory for SHN_COMMON."); 196 abort(); 197 } 198#endif 199 } 200 break; 201 202 case SHN_UNDEF: 203#if defined(mips) || defined(__mips__) || defined(MIPS) || defined(_MIPS_) 204 if (strcmp(getName(), "_gp_disp") == 0) // OK for MIPS 205 break; 206#endif 207 case SHN_ABS: 208 case SHN_XINDEX: 209 rsl_assert(0 && "STT_OBJECT with special st_shndx."); 210 break; 211 } 212 break; 213 214 215 case STT_FUNC: 216 switch (idx) { 217 default: 218 { 219#ifndef NDEBUG 220 ELFSectionHeaderTableTy const *header = 221 owner->getSectionHeaderTable(); 222 rsl_assert((*header)[idx]->getType() == SHT_PROGBITS && 223 "STT_FUNC with not PROGBITS section."); 224#endif 225 ELFSectionTy const *sec = owner->getSectionByIndex(idx); 226 rsl_assert(sec != 0 && "STT_FUNC with null section."); 227 228 ELFSectionProgBitsTy const &st = 229 static_cast<ELFSectionProgBitsTy const &>(*sec); 230 my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue()); 231 } 232 break; 233 234 case SHN_ABS: 235 case SHN_COMMON: 236 case SHN_UNDEF: 237 case SHN_XINDEX: 238 rsl_assert(0 && "STT_FUNC with special st_shndx."); 239 break; 240 } 241 break; 242 243 244 case STT_SECTION: 245 switch (idx) { 246 default: 247 { 248#ifndef NDEBUG 249 ELFSectionHeaderTableTy const *header = 250 owner->getSectionHeaderTable(); 251 rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS || 252 (*header)[idx]->getType() == SHT_NOBITS) && 253 "STT_SECTION with not BITS section."); 254#endif 255 ELFSectionTy const *sec = owner->getSectionByIndex(idx); 256 rsl_assert(sec != 0 && "STT_SECTION with null section."); 257 258 ELFSectionBitsTy const &st = 259 static_cast<ELFSectionBitsTy const &>(*sec); 260 my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue()); 261 } 262 break; 263 264 case SHN_ABS: 265 case SHN_COMMON: 266 case SHN_UNDEF: 267 case SHN_XINDEX: 268 rsl_assert(0 && "STT_SECTION with special st_shndx."); 269 break; 270 } 271 break; 272 273 case STT_NOTYPE: 274 switch (idx) { 275 default: 276 { 277#ifndef NDEBUG 278 ELFSectionHeaderTableTy const *header = 279 owner->getSectionHeaderTable(); 280 rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS || 281 (*header)[idx]->getType() == SHT_NOBITS) && 282 "STT_SECTION with not BITS section."); 283#endif 284 ELFSectionTy const *sec = owner->getSectionByIndex(idx); 285 rsl_assert(sec != 0 && "STT_SECTION with null section."); 286 287 ELFSectionBitsTy const &st = 288 static_cast<ELFSectionBitsTy const &>(*sec); 289 my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue()); 290 } 291 break; 292 293 case SHN_ABS: 294 case SHN_COMMON: 295 case SHN_XINDEX: 296 rsl_assert(0 && "STT_SECTION with special st_shndx."); 297 break; 298 case SHN_UNDEF: 299 return 0; 300 } 301 break; 302 return 0; 303 304 case STT_COMMON: 305 case STT_FILE: 306 case STT_TLS: 307 case STT_LOOS: 308 case STT_HIOS: 309 case STT_LOPROC: 310 case STT_HIPROC: 311 rsl_assert(0 && "Not implement."); 312 return 0; 313 } 314 return my_addr; 315} 316 317#endif // ELF_SYMBOL_HXX 318