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