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