1 //===- ELFObjectFile.cpp - ELF object file implementation -------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the ELFObjectFile class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/ADT/SmallVector.h" 15 #include "llvm/ADT/StringSwitch.h" 16 #include "llvm/ADT/Triple.h" 17 #include "llvm/Object/ObjectFile.h" 18 #include "llvm/Support/ELF.h" 19 #include "llvm/Support/Endian.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/MemoryBuffer.h" 22 #include <limits> 23 #include <utility> 24 25 using namespace llvm; 26 using namespace object; 27 28 // Templates to choose Elf_Addr and Elf_Off depending on is64Bits. 29 namespace { 30 template<support::endianness target_endianness> 31 struct ELFDataTypeTypedefHelperCommon { 32 typedef support::detail::packed_endian_specific_integral 33 <uint16_t, target_endianness, support::aligned> Elf_Half; 34 typedef support::detail::packed_endian_specific_integral 35 <uint32_t, target_endianness, support::aligned> Elf_Word; 36 typedef support::detail::packed_endian_specific_integral 37 <int32_t, target_endianness, support::aligned> Elf_Sword; 38 typedef support::detail::packed_endian_specific_integral 39 <uint64_t, target_endianness, support::aligned> Elf_Xword; 40 typedef support::detail::packed_endian_specific_integral 41 <int64_t, target_endianness, support::aligned> Elf_Sxword; 42 }; 43 } 44 45 namespace { 46 template<support::endianness target_endianness, bool is64Bits> 47 struct ELFDataTypeTypedefHelper; 48 49 /// ELF 32bit types. 50 template<support::endianness target_endianness> 51 struct ELFDataTypeTypedefHelper<target_endianness, false> 52 : ELFDataTypeTypedefHelperCommon<target_endianness> { 53 typedef support::detail::packed_endian_specific_integral 54 <uint32_t, target_endianness, support::aligned> Elf_Addr; 55 typedef support::detail::packed_endian_specific_integral 56 <uint32_t, target_endianness, support::aligned> Elf_Off; 57 }; 58 59 /// ELF 64bit types. 60 template<support::endianness target_endianness> 61 struct ELFDataTypeTypedefHelper<target_endianness, true> 62 : ELFDataTypeTypedefHelperCommon<target_endianness>{ 63 typedef support::detail::packed_endian_specific_integral 64 <uint64_t, target_endianness, support::aligned> Elf_Addr; 65 typedef support::detail::packed_endian_specific_integral 66 <uint64_t, target_endianness, support::aligned> Elf_Off; 67 }; 68 } 69 70 // I really don't like doing this, but the alternative is copypasta. 71 #define LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) \ 72 typedef typename \ 73 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; \ 74 typedef typename \ 75 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \ 76 typedef typename \ 77 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; \ 78 typedef typename \ 79 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; \ 80 typedef typename \ 81 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Sword; \ 82 typedef typename \ 83 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xword; \ 84 typedef typename \ 85 ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxword; 86 87 // Section header. 88 namespace { 89 template<support::endianness target_endianness, bool is64Bits> 90 struct Elf_Shdr_Base; 91 92 template<support::endianness target_endianness> 93 struct Elf_Shdr_Base<target_endianness, false> { 94 LLVM_ELF_IMPORT_TYPES(target_endianness, false) 95 Elf_Word sh_name; // Section name (index into string table) 96 Elf_Word sh_type; // Section type (SHT_*) 97 Elf_Word sh_flags; // Section flags (SHF_*) 98 Elf_Addr sh_addr; // Address where section is to be loaded 99 Elf_Off sh_offset; // File offset of section data, in bytes 100 Elf_Word sh_size; // Size of section, in bytes 101 Elf_Word sh_link; // Section type-specific header table index link 102 Elf_Word sh_info; // Section type-specific extra information 103 Elf_Word sh_addralign;// Section address alignment 104 Elf_Word sh_entsize; // Size of records contained within the section 105 }; 106 107 template<support::endianness target_endianness> 108 struct Elf_Shdr_Base<target_endianness, true> { 109 LLVM_ELF_IMPORT_TYPES(target_endianness, true) 110 Elf_Word sh_name; // Section name (index into string table) 111 Elf_Word sh_type; // Section type (SHT_*) 112 Elf_Xword sh_flags; // Section flags (SHF_*) 113 Elf_Addr sh_addr; // Address where section is to be loaded 114 Elf_Off sh_offset; // File offset of section data, in bytes 115 Elf_Xword sh_size; // Size of section, in bytes 116 Elf_Word sh_link; // Section type-specific header table index link 117 Elf_Word sh_info; // Section type-specific extra information 118 Elf_Xword sh_addralign;// Section address alignment 119 Elf_Xword sh_entsize; // Size of records contained within the section 120 }; 121 122 template<support::endianness target_endianness, bool is64Bits> 123 struct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> { 124 using Elf_Shdr_Base<target_endianness, is64Bits>::sh_entsize; 125 using Elf_Shdr_Base<target_endianness, is64Bits>::sh_size; 126 127 /// @brief Get the number of entities this section contains if it has any. 128 unsigned getEntityCount() const { 129 if (sh_entsize == 0) 130 return 0; 131 else 132 return sh_size / sh_entsize; 133 } 134 }; 135 } 136 137 namespace { 138 template<support::endianness target_endianness, bool is64Bits> 139 struct Elf_Sym_Base; 140 141 template<support::endianness target_endianness> 142 struct Elf_Sym_Base<target_endianness, false> { 143 LLVM_ELF_IMPORT_TYPES(target_endianness, false) 144 Elf_Word st_name; // Symbol name (index into string table) 145 Elf_Addr st_value; // Value or address associated with the symbol 146 Elf_Word st_size; // Size of the symbol 147 unsigned char st_info; // Symbol's type and binding attributes 148 unsigned char st_other; // Must be zero; reserved 149 Elf_Half st_shndx; // Which section (header table index) it's defined in 150 }; 151 152 template<support::endianness target_endianness> 153 struct Elf_Sym_Base<target_endianness, true> { 154 LLVM_ELF_IMPORT_TYPES(target_endianness, true) 155 Elf_Word st_name; // Symbol name (index into string table) 156 unsigned char st_info; // Symbol's type and binding attributes 157 unsigned char st_other; // Must be zero; reserved 158 Elf_Half st_shndx; // Which section (header table index) it's defined in 159 Elf_Addr st_value; // Value or address associated with the symbol 160 Elf_Xword st_size; // Size of the symbol 161 }; 162 163 template<support::endianness target_endianness, bool is64Bits> 164 struct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> { 165 using Elf_Sym_Base<target_endianness, is64Bits>::st_info; 166 167 // These accessors and mutators correspond to the ELF32_ST_BIND, 168 // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification: 169 unsigned char getBinding() const { return st_info >> 4; } 170 unsigned char getType() const { return st_info & 0x0f; } 171 void setBinding(unsigned char b) { setBindingAndType(b, getType()); } 172 void setType(unsigned char t) { setBindingAndType(getBinding(), t); } 173 void setBindingAndType(unsigned char b, unsigned char t) { 174 st_info = (b << 4) + (t & 0x0f); 175 } 176 }; 177 } 178 179 namespace { 180 struct ELFDataRefImpl { 181 uint32_t SymbolIndex; 182 uint16_t SymbolTableSectionIndex; 183 uint16_t Unused; 184 }; 185 } 186 187 namespace { 188 template<support::endianness target_endianness, bool is64Bits> 189 class ELFObjectFile : public ObjectFile { 190 LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) 191 192 typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr; 193 typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym; 194 195 struct Elf_Ehdr { 196 unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes 197 Elf_Half e_type; // Type of file (see ET_*) 198 Elf_Half e_machine; // Required architecture for this file (see EM_*) 199 Elf_Word e_version; // Must be equal to 1 200 Elf_Addr e_entry; // Address to jump to in order to start program 201 Elf_Off e_phoff; // Program header table's file offset, in bytes 202 Elf_Off e_shoff; // Section header table's file offset, in bytes 203 Elf_Word e_flags; // Processor-specific flags 204 Elf_Half e_ehsize; // Size of ELF header, in bytes 205 Elf_Half e_phentsize;// Size of an entry in the program header table 206 Elf_Half e_phnum; // Number of entries in the program header table 207 Elf_Half e_shentsize;// Size of an entry in the section header table 208 Elf_Half e_shnum; // Number of entries in the section header table 209 Elf_Half e_shstrndx; // Section header table index of section name 210 // string table 211 bool checkMagic() const { 212 return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; 213 } 214 unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; } 215 unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } 216 }; 217 218 typedef SmallVector<const Elf_Shdr*, 1> SymbolTableSections_t; 219 220 const Elf_Ehdr *Header; 221 const Elf_Shdr *SectionHeaderTable; 222 const Elf_Shdr *dot_shstrtab_sec; // Section header string table. 223 const Elf_Shdr *dot_strtab_sec; // Symbol header string table. 224 SymbolTableSections_t SymbolTableSections; 225 226 void validateSymbol(DataRefImpl Symb) const; 227 const Elf_Sym *getSymbol(DataRefImpl Symb) const; 228 const Elf_Shdr *getSection(DataRefImpl index) const; 229 const Elf_Shdr *getSection(uint16_t index) const; 230 const char *getString(uint16_t section, uint32_t offset) const; 231 const char *getString(const Elf_Shdr *section, uint32_t offset) const; 232 233 protected: 234 virtual SymbolRef getSymbolNext(DataRefImpl Symb) const; 235 virtual StringRef getSymbolName(DataRefImpl Symb) const; 236 virtual uint64_t getSymbolAddress(DataRefImpl Symb) const; 237 virtual uint64_t getSymbolSize(DataRefImpl Symb) const; 238 virtual char getSymbolNMTypeChar(DataRefImpl Symb) const; 239 virtual bool isSymbolInternal(DataRefImpl Symb) const; 240 241 virtual SectionRef getSectionNext(DataRefImpl Sec) const; 242 virtual StringRef getSectionName(DataRefImpl Sec) const; 243 virtual uint64_t getSectionAddress(DataRefImpl Sec) const; 244 virtual uint64_t getSectionSize(DataRefImpl Sec) const; 245 virtual StringRef getSectionContents(DataRefImpl Sec) const; 246 virtual bool isSectionText(DataRefImpl Sec) const; 247 248 public: 249 ELFObjectFile(MemoryBuffer *Object); 250 virtual symbol_iterator begin_symbols() const; 251 virtual symbol_iterator end_symbols() const; 252 virtual section_iterator begin_sections() const; 253 virtual section_iterator end_sections() const; 254 255 virtual uint8_t getBytesInAddress() const; 256 virtual StringRef getFileFormatName() const; 257 virtual unsigned getArch() const; 258 }; 259 } // end namespace 260 261 template<support::endianness target_endianness, bool is64Bits> 262 void ELFObjectFile<target_endianness, is64Bits> 263 ::validateSymbol(DataRefImpl Symb) const { 264 const ELFDataRefImpl SymbolData = *reinterpret_cast<ELFDataRefImpl *>(&Symb); 265 const Elf_Sym *symb = getSymbol(Symb); 266 const Elf_Shdr *SymbolTableSection = 267 SymbolTableSections[SymbolData.SymbolTableSectionIndex]; 268 // FIXME: We really need to do proper error handling in the case of an invalid 269 // input file. Because we don't use exceptions, I think we'll just pass 270 // an error object around. 271 if (!( symb 272 && SymbolTableSection 273 && symb >= (const Elf_Sym*)(base 274 + SymbolTableSection->sh_offset) 275 && symb < (const Elf_Sym*)(base 276 + SymbolTableSection->sh_offset 277 + SymbolTableSection->sh_size))) 278 // FIXME: Proper error handling. 279 report_fatal_error("Symb must point to a valid symbol!"); 280 } 281 282 template<support::endianness target_endianness, bool is64Bits> 283 SymbolRef ELFObjectFile<target_endianness, is64Bits> 284 ::getSymbolNext(DataRefImpl Symb) const { 285 validateSymbol(Symb); 286 ELFDataRefImpl &SymbolData = *reinterpret_cast<ELFDataRefImpl *>(&Symb); 287 const Elf_Shdr *SymbolTableSection = 288 SymbolTableSections[SymbolData.SymbolTableSectionIndex]; 289 290 ++SymbolData.SymbolIndex; 291 // Check to see if we are at the end of this symbol table. 292 if (SymbolData.SymbolIndex >= SymbolTableSection->getEntityCount()) { 293 // We are at the end. If there are other symbol tables, jump to them. 294 ++SymbolData.SymbolTableSectionIndex; 295 SymbolData.SymbolIndex = 1; // The 0th symbol in ELF is fake. 296 // Otherwise return the terminator. 297 if (SymbolData.SymbolTableSectionIndex >= SymbolTableSections.size()) { 298 SymbolData.SymbolIndex = std::numeric_limits<uint32_t>::max(); 299 SymbolData.SymbolTableSectionIndex = std::numeric_limits<uint32_t>::max(); 300 } 301 } 302 303 return SymbolRef(Symb, this); 304 } 305 306 template<support::endianness target_endianness, bool is64Bits> 307 StringRef ELFObjectFile<target_endianness, is64Bits> 308 ::getSymbolName(DataRefImpl Symb) const { 309 validateSymbol(Symb); 310 const Elf_Sym *symb = getSymbol(Symb); 311 if (symb->st_name == 0) { 312 const Elf_Shdr *section = getSection(symb->st_shndx); 313 if (!section) 314 return ""; 315 return getString(dot_shstrtab_sec, section->sh_name); 316 } 317 318 // Use the default symbol table name section. 319 return getString(dot_strtab_sec, symb->st_name); 320 } 321 322 template<support::endianness target_endianness, bool is64Bits> 323 uint64_t ELFObjectFile<target_endianness, is64Bits> 324 ::getSymbolAddress(DataRefImpl Symb) const { 325 validateSymbol(Symb); 326 const Elf_Sym *symb = getSymbol(Symb); 327 const Elf_Shdr *Section; 328 switch (symb->st_shndx) { 329 case ELF::SHN_COMMON: 330 // Undefined symbols have no address yet. 331 case ELF::SHN_UNDEF: return UnknownAddressOrSize; 332 case ELF::SHN_ABS: return symb->st_value; 333 default: Section = getSection(symb->st_shndx); 334 } 335 336 switch (symb->getType()) { 337 case ELF::STT_SECTION: return Section ? Section->sh_addr 338 : UnknownAddressOrSize; 339 case ELF::STT_FUNC: 340 case ELF::STT_OBJECT: 341 case ELF::STT_NOTYPE: 342 return symb->st_value; 343 default: return UnknownAddressOrSize; 344 } 345 } 346 347 template<support::endianness target_endianness, bool is64Bits> 348 uint64_t ELFObjectFile<target_endianness, is64Bits> 349 ::getSymbolSize(DataRefImpl Symb) const { 350 validateSymbol(Symb); 351 const Elf_Sym *symb = getSymbol(Symb); 352 if (symb->st_size == 0) 353 return UnknownAddressOrSize; 354 return symb->st_size; 355 } 356 357 template<support::endianness target_endianness, bool is64Bits> 358 char ELFObjectFile<target_endianness, is64Bits> 359 ::getSymbolNMTypeChar(DataRefImpl Symb) const { 360 validateSymbol(Symb); 361 const Elf_Sym *symb = getSymbol(Symb); 362 const Elf_Shdr *Section = getSection(symb->st_shndx); 363 364 char ret = '?'; 365 366 if (Section) { 367 switch (Section->sh_type) { 368 case ELF::SHT_PROGBITS: 369 case ELF::SHT_DYNAMIC: 370 switch (Section->sh_flags) { 371 case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): 372 ret = 't'; break; 373 case (ELF::SHF_ALLOC | ELF::SHF_WRITE): 374 ret = 'd'; break; 375 case ELF::SHF_ALLOC: 376 case (ELF::SHF_ALLOC | ELF::SHF_MERGE): 377 case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): 378 ret = 'r'; break; 379 } 380 break; 381 case ELF::SHT_NOBITS: ret = 'b'; 382 } 383 } 384 385 switch (symb->st_shndx) { 386 case ELF::SHN_UNDEF: 387 if (ret == '?') 388 ret = 'U'; 389 break; 390 case ELF::SHN_ABS: ret = 'a'; break; 391 case ELF::SHN_COMMON: ret = 'c'; break; 392 } 393 394 switch (symb->getBinding()) { 395 case ELF::STB_GLOBAL: ret = ::toupper(ret); break; 396 case ELF::STB_WEAK: 397 if (symb->st_shndx == ELF::SHN_UNDEF) 398 ret = 'w'; 399 else 400 if (symb->getType() == ELF::STT_OBJECT) 401 ret = 'V'; 402 else 403 ret = 'W'; 404 } 405 406 if (ret == '?' && symb->getType() == ELF::STT_SECTION) 407 return StringSwitch<char>(getSymbolName(Symb)) 408 .StartsWith(".debug", 'N') 409 .StartsWith(".note", 'n'); 410 411 return ret; 412 } 413 414 template<support::endianness target_endianness, bool is64Bits> 415 bool ELFObjectFile<target_endianness, is64Bits> 416 ::isSymbolInternal(DataRefImpl Symb) const { 417 validateSymbol(Symb); 418 const Elf_Sym *symb = getSymbol(Symb); 419 420 if ( symb->getType() == ELF::STT_FILE 421 || symb->getType() == ELF::STT_SECTION) 422 return true; 423 return false; 424 } 425 426 template<support::endianness target_endianness, bool is64Bits> 427 SectionRef ELFObjectFile<target_endianness, is64Bits> 428 ::getSectionNext(DataRefImpl Sec) const { 429 const uint8_t *sec = *reinterpret_cast<const uint8_t **>(&Sec); 430 sec += Header->e_shentsize; 431 return SectionRef(DataRefImpl(sec), this); 432 } 433 434 template<support::endianness target_endianness, bool is64Bits> 435 StringRef ELFObjectFile<target_endianness, is64Bits> 436 ::getSectionName(DataRefImpl Sec) const { 437 const Elf_Shdr *sec = 438 *reinterpret_cast<const Elf_Shdr **>(&Sec); 439 return StringRef(getString(dot_shstrtab_sec, sec->sh_name)); 440 } 441 442 template<support::endianness target_endianness, bool is64Bits> 443 uint64_t ELFObjectFile<target_endianness, is64Bits> 444 ::getSectionAddress(DataRefImpl Sec) const { 445 const Elf_Shdr *sec = 446 *reinterpret_cast<const Elf_Shdr **>(&Sec); 447 return sec->sh_addr; 448 } 449 450 template<support::endianness target_endianness, bool is64Bits> 451 uint64_t ELFObjectFile<target_endianness, is64Bits> 452 ::getSectionSize(DataRefImpl Sec) const { 453 const Elf_Shdr *sec = 454 *reinterpret_cast<const Elf_Shdr **>(&Sec); 455 return sec->sh_size; 456 } 457 458 template<support::endianness target_endianness, bool is64Bits> 459 StringRef ELFObjectFile<target_endianness, is64Bits> 460 ::getSectionContents(DataRefImpl Sec) const { 461 const Elf_Shdr *sec = 462 *reinterpret_cast<const Elf_Shdr **>(&Sec); 463 const char *start = (char*)base + sec->sh_offset; 464 return StringRef(start, sec->sh_size); 465 } 466 467 template<support::endianness target_endianness, bool is64Bits> 468 bool ELFObjectFile<target_endianness, is64Bits> 469 ::isSectionText(DataRefImpl Sec) const { 470 const Elf_Shdr *sec = 471 *reinterpret_cast<const Elf_Shdr **>(&Sec); 472 if (sec->sh_flags & ELF::SHF_EXECINSTR) 473 return true; 474 return false; 475 } 476 477 template<support::endianness target_endianness, bool is64Bits> 478 ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object) 479 : ObjectFile(Object) 480 , SectionHeaderTable(0) 481 , dot_shstrtab_sec(0) 482 , dot_strtab_sec(0) { 483 Header = reinterpret_cast<const Elf_Ehdr *>(base); 484 485 if (Header->e_shoff == 0) 486 return; 487 488 SectionHeaderTable = 489 reinterpret_cast<const Elf_Shdr *>(base + Header->e_shoff); 490 uint32_t SectionTableSize = Header->e_shnum * Header->e_shentsize; 491 if (!( (const uint8_t *)SectionHeaderTable + SectionTableSize 492 <= base + MapFile->getBufferSize())) 493 // FIXME: Proper error handling. 494 report_fatal_error("Section table goes past end of file!"); 495 496 497 // To find the symbol tables we walk the section table to find SHT_STMTAB. 498 for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable), 499 *e = i + Header->e_shnum * Header->e_shentsize; 500 i != e; i += Header->e_shentsize) { 501 const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i); 502 if (sh->sh_type == ELF::SHT_SYMTAB) { 503 SymbolTableSections.push_back(sh); 504 } 505 } 506 507 // Get string table sections. 508 dot_shstrtab_sec = getSection(Header->e_shstrndx); 509 if (dot_shstrtab_sec) { 510 // Verify that the last byte in the string table in a null. 511 if (((const char*)base + dot_shstrtab_sec->sh_offset) 512 [dot_shstrtab_sec->sh_size - 1] != 0) 513 // FIXME: Proper error handling. 514 report_fatal_error("String table must end with a null terminator!"); 515 } 516 517 // Merge this into the above loop. 518 for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable), 519 *e = i + Header->e_shnum * Header->e_shentsize; 520 i != e; i += Header->e_shentsize) { 521 const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i); 522 if (sh->sh_type == ELF::SHT_STRTAB) { 523 StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name)); 524 if (SectionName == ".strtab") { 525 if (dot_strtab_sec != 0) 526 // FIXME: Proper error handling. 527 report_fatal_error("Already found section named .strtab!"); 528 dot_strtab_sec = sh; 529 const char *dot_strtab = (const char*)base + sh->sh_offset; 530 if (dot_strtab[sh->sh_size - 1] != 0) 531 // FIXME: Proper error handling. 532 report_fatal_error("String table must end with a null terminator!"); 533 } 534 } 535 } 536 } 537 538 template<support::endianness target_endianness, bool is64Bits> 539 ObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits> 540 ::begin_symbols() const { 541 ELFDataRefImpl SymbolData; 542 memset(&SymbolData, 0, sizeof(SymbolData)); 543 if (SymbolTableSections.size() == 0) { 544 SymbolData.SymbolIndex = std::numeric_limits<uint32_t>::max(); 545 SymbolData.SymbolTableSectionIndex = std::numeric_limits<uint32_t>::max(); 546 } else { 547 SymbolData.SymbolIndex = 1; // The 0th symbol in ELF is fake. 548 SymbolData.SymbolTableSectionIndex = 0; 549 } 550 return symbol_iterator( 551 SymbolRef(DataRefImpl(*reinterpret_cast<DataRefImpl*>(&SymbolData)), this)); 552 } 553 554 template<support::endianness target_endianness, bool is64Bits> 555 ObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits> 556 ::end_symbols() const { 557 ELFDataRefImpl SymbolData; 558 memset(&SymbolData, 0, sizeof(SymbolData)); 559 SymbolData.SymbolIndex = std::numeric_limits<uint32_t>::max(); 560 SymbolData.SymbolTableSectionIndex = std::numeric_limits<uint32_t>::max(); 561 return symbol_iterator( 562 SymbolRef(DataRefImpl(*reinterpret_cast<DataRefImpl*>(&SymbolData)), this)); 563 } 564 565 template<support::endianness target_endianness, bool is64Bits> 566 ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits> 567 ::begin_sections() const { 568 return section_iterator( 569 SectionRef(DataRefImpl(base + Header->e_shoff), this)); 570 } 571 572 template<support::endianness target_endianness, bool is64Bits> 573 ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits> 574 ::end_sections() const { 575 return section_iterator( 576 SectionRef(DataRefImpl(base 577 + Header->e_shoff 578 + (Header->e_shentsize * Header->e_shnum)), this)); 579 } 580 581 template<support::endianness target_endianness, bool is64Bits> 582 uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const { 583 return 4; 584 } 585 586 template<support::endianness target_endianness, bool is64Bits> 587 StringRef ELFObjectFile<target_endianness, is64Bits> 588 ::getFileFormatName() const { 589 switch(Header->e_ident[ELF::EI_CLASS]) { 590 case ELF::ELFCLASS32: 591 switch(Header->e_machine) { 592 case ELF::EM_386: 593 return "ELF32-i386"; 594 case ELF::EM_X86_64: 595 return "ELF32-x86-64"; 596 default: 597 return "ELF32-unknown"; 598 } 599 case ELF::ELFCLASS64: 600 switch(Header->e_machine) { 601 case ELF::EM_386: 602 return "ELF64-i386"; 603 case ELF::EM_X86_64: 604 return "ELF64-x86-64"; 605 default: 606 return "ELF64-unknown"; 607 } 608 default: 609 // FIXME: Proper error handling. 610 report_fatal_error("Invalid ELFCLASS!"); 611 } 612 } 613 614 template<support::endianness target_endianness, bool is64Bits> 615 unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const { 616 switch(Header->e_machine) { 617 case ELF::EM_386: 618 return Triple::x86; 619 case ELF::EM_X86_64: 620 return Triple::x86_64; 621 default: 622 return Triple::UnknownArch; 623 } 624 } 625 626 template<support::endianness target_endianness, bool is64Bits> 627 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym * 628 ELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const { 629 const ELFDataRefImpl SymbolData = *reinterpret_cast<ELFDataRefImpl *>(&Symb); 630 const Elf_Shdr *sec = 631 SymbolTableSections[SymbolData.SymbolTableSectionIndex]; 632 return reinterpret_cast<const Elf_Sym *>( 633 base 634 + sec->sh_offset 635 + (SymbolData.SymbolIndex * sec->sh_entsize)); 636 } 637 638 template<support::endianness target_endianness, bool is64Bits> 639 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * 640 ELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const { 641 const ELFDataRefImpl SymbolData = *reinterpret_cast<ELFDataRefImpl *>(&Symb); 642 const Elf_Shdr *sec = getSection(SymbolData.SymbolTableSectionIndex); 643 if (sec->sh_type != ELF::SHT_SYMTAB) 644 // FIXME: Proper error handling. 645 report_fatal_error("Invalid symbol table section!"); 646 return sec; 647 } 648 649 template<support::endianness target_endianness, bool is64Bits> 650 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * 651 ELFObjectFile<target_endianness, is64Bits>::getSection(uint16_t index) const { 652 if (index == 0 || index >= ELF::SHN_LORESERVE) 653 return 0; 654 if (!SectionHeaderTable || index >= Header->e_shnum) 655 // FIXME: Proper error handling. 656 report_fatal_error("Invalid section index!"); 657 658 return reinterpret_cast<const Elf_Shdr *>( 659 reinterpret_cast<const char *>(SectionHeaderTable) 660 + (index * Header->e_shentsize)); 661 } 662 663 template<support::endianness target_endianness, bool is64Bits> 664 const char *ELFObjectFile<target_endianness, is64Bits> 665 ::getString(uint16_t section, 666 ELF::Elf32_Word offset) const { 667 return getString(getSection(section), offset); 668 } 669 670 template<support::endianness target_endianness, bool is64Bits> 671 const char *ELFObjectFile<target_endianness, is64Bits> 672 ::getString(const Elf_Shdr *section, 673 ELF::Elf32_Word offset) const { 674 assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!"); 675 if (offset >= section->sh_size) 676 // FIXME: Proper error handling. 677 report_fatal_error("Sybol name offset outside of string table!"); 678 return (const char *)base + section->sh_offset + offset; 679 } 680 681 // EI_CLASS, EI_DATA. 682 static std::pair<unsigned char, unsigned char> 683 getElfArchType(MemoryBuffer *Object) { 684 if (Object->getBufferSize() < ELF::EI_NIDENT) 685 return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE); 686 return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS] 687 , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]); 688 } 689 690 namespace llvm { 691 692 ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) { 693 std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object); 694 if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) 695 return new ELFObjectFile<support::little, false>(Object); 696 else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) 697 return new ELFObjectFile<support::big, false>(Object); 698 else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) 699 return new ELFObjectFile<support::little, true>(Object); 700 else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) 701 return new ELFObjectFile<support::big, true>(Object); 702 // FIXME: Proper error handling. 703 report_fatal_error("Not an ELF object file!"); 704 } 705 706 } // end namespace llvm 707