1 //===- ELF.h - 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 declares the ELFFile template class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_OBJECT_ELF_H 15 #define LLVM_OBJECT_ELF_H 16 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/Object/ELFTypes.h" 19 #include "llvm/Support/MemoryBuffer.h" 20 21 namespace llvm { 22 namespace object { 23 24 StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type); 25 26 // Subclasses of ELFFile may need this for template instantiation 27 inline std::pair<unsigned char, unsigned char> 28 getElfArchType(StringRef Object) { 29 if (Object.size() < ELF::EI_NIDENT) 30 return std::make_pair((uint8_t)ELF::ELFCLASSNONE, 31 (uint8_t)ELF::ELFDATANONE); 32 return std::make_pair((uint8_t)Object[ELF::EI_CLASS], 33 (uint8_t)Object[ELF::EI_DATA]); 34 } 35 36 template <class ELFT> 37 class ELFFile { 38 public: 39 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 40 typedef typename std::conditional<ELFT::Is64Bits, 41 uint64_t, uint32_t>::type uintX_t; 42 43 typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr; 44 typedef Elf_Shdr_Impl<ELFT> Elf_Shdr; 45 typedef Elf_Sym_Impl<ELFT> Elf_Sym; 46 typedef Elf_Dyn_Impl<ELFT> Elf_Dyn; 47 typedef Elf_Phdr_Impl<ELFT> Elf_Phdr; 48 typedef Elf_Rel_Impl<ELFT, false> Elf_Rel; 49 typedef Elf_Rel_Impl<ELFT, true> Elf_Rela; 50 typedef Elf_Verdef_Impl<ELFT> Elf_Verdef; 51 typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux; 52 typedef Elf_Verneed_Impl<ELFT> Elf_Verneed; 53 typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux; 54 typedef Elf_Versym_Impl<ELFT> Elf_Versym; 55 typedef Elf_Hash_Impl<ELFT> Elf_Hash; 56 typedef Elf_GnuHash_Impl<ELFT> Elf_GnuHash; 57 typedef iterator_range<const Elf_Dyn *> Elf_Dyn_Range; 58 typedef iterator_range<const Elf_Shdr *> Elf_Shdr_Range; 59 typedef iterator_range<const Elf_Sym *> Elf_Sym_Range; 60 61 const uint8_t *base() const { 62 return reinterpret_cast<const uint8_t *>(Buf.data()); 63 } 64 65 private: 66 67 StringRef Buf; 68 69 const Elf_Ehdr *Header; 70 const Elf_Shdr *SectionHeaderTable = nullptr; 71 StringRef DotShstrtab; // Section header string table. 72 73 public: 74 template<typename T> 75 const T *getEntry(uint32_t Section, uint32_t Entry) const; 76 template <typename T> 77 const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const; 78 79 ErrorOr<StringRef> getStringTable(const Elf_Shdr *Section) const; 80 ErrorOr<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const; 81 82 ErrorOr<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const; 83 84 void VerifyStrTab(const Elf_Shdr *sh) const; 85 86 StringRef getRelocationTypeName(uint32_t Type) const; 87 void getRelocationTypeName(uint32_t Type, 88 SmallVectorImpl<char> &Result) const; 89 90 /// \brief Get the symbol for a given relocation. 91 const Elf_Sym *getRelocationSymbol(const Elf_Rel *Rel, 92 const Elf_Shdr *SymTab) const; 93 94 ELFFile(StringRef Object, std::error_code &EC); 95 96 bool isMipsELF64() const { 97 return Header->e_machine == ELF::EM_MIPS && 98 Header->getFileClass() == ELF::ELFCLASS64; 99 } 100 101 bool isMips64EL() const { 102 return Header->e_machine == ELF::EM_MIPS && 103 Header->getFileClass() == ELF::ELFCLASS64 && 104 Header->getDataEncoding() == ELF::ELFDATA2LSB; 105 } 106 107 ErrorOr<const Elf_Dyn *> dynamic_table_begin(const Elf_Phdr *Phdr) const; 108 ErrorOr<const Elf_Dyn *> dynamic_table_end(const Elf_Phdr *Phdr) const; 109 ErrorOr<Elf_Dyn_Range> dynamic_table(const Elf_Phdr *Phdr) const { 110 ErrorOr<const Elf_Dyn *> Begin = dynamic_table_begin(Phdr); 111 if (std::error_code EC = Begin.getError()) 112 return EC; 113 ErrorOr<const Elf_Dyn *> End = dynamic_table_end(Phdr); 114 if (std::error_code EC = End.getError()) 115 return EC; 116 return make_range(*Begin, *End); 117 } 118 119 const Elf_Shdr *section_begin() const; 120 const Elf_Shdr *section_end() const; 121 Elf_Shdr_Range sections() const { 122 return make_range(section_begin(), section_end()); 123 } 124 125 const Elf_Sym *symbol_begin(const Elf_Shdr *Sec) const { 126 if (!Sec) 127 return nullptr; 128 if (Sec->sh_entsize != sizeof(Elf_Sym)) 129 report_fatal_error("Invalid symbol size"); 130 return reinterpret_cast<const Elf_Sym *>(base() + Sec->sh_offset); 131 } 132 const Elf_Sym *symbol_end(const Elf_Shdr *Sec) const { 133 if (!Sec) 134 return nullptr; 135 uint64_t Size = Sec->sh_size; 136 if (Size % sizeof(Elf_Sym)) 137 report_fatal_error("Invalid symbol table size"); 138 return symbol_begin(Sec) + Size / sizeof(Elf_Sym); 139 } 140 Elf_Sym_Range symbols(const Elf_Shdr *Sec) const { 141 return make_range(symbol_begin(Sec), symbol_end(Sec)); 142 } 143 144 typedef iterator_range<const Elf_Rela *> Elf_Rela_Range; 145 146 const Elf_Rela *rela_begin(const Elf_Shdr *sec) const { 147 if (sec->sh_entsize != sizeof(Elf_Rela)) 148 report_fatal_error("Invalid relocation entry size"); 149 return reinterpret_cast<const Elf_Rela *>(base() + sec->sh_offset); 150 } 151 152 const Elf_Rela *rela_end(const Elf_Shdr *sec) const { 153 uint64_t Size = sec->sh_size; 154 if (Size % sizeof(Elf_Rela)) 155 report_fatal_error("Invalid relocation table size"); 156 return rela_begin(sec) + Size / sizeof(Elf_Rela); 157 } 158 159 Elf_Rela_Range relas(const Elf_Shdr *Sec) const { 160 return make_range(rela_begin(Sec), rela_end(Sec)); 161 } 162 163 const Elf_Rel *rel_begin(const Elf_Shdr *sec) const { 164 if (sec->sh_entsize != sizeof(Elf_Rel)) 165 report_fatal_error("Invalid relocation entry size"); 166 return reinterpret_cast<const Elf_Rel *>(base() + sec->sh_offset); 167 } 168 169 const Elf_Rel *rel_end(const Elf_Shdr *sec) const { 170 uint64_t Size = sec->sh_size; 171 if (Size % sizeof(Elf_Rel)) 172 report_fatal_error("Invalid relocation table size"); 173 return rel_begin(sec) + Size / sizeof(Elf_Rel); 174 } 175 176 typedef iterator_range<const Elf_Rel *> Elf_Rel_Range; 177 Elf_Rel_Range rels(const Elf_Shdr *Sec) const { 178 return make_range(rel_begin(Sec), rel_end(Sec)); 179 } 180 181 /// \brief Iterate over program header table. 182 const Elf_Phdr *program_header_begin() const { 183 if (Header->e_phnum && Header->e_phentsize != sizeof(Elf_Phdr)) 184 report_fatal_error("Invalid program header size"); 185 return reinterpret_cast<const Elf_Phdr *>(base() + Header->e_phoff); 186 } 187 188 const Elf_Phdr *program_header_end() const { 189 return program_header_begin() + Header->e_phnum; 190 } 191 192 typedef iterator_range<const Elf_Phdr *> Elf_Phdr_Range; 193 194 const Elf_Phdr_Range program_headers() const { 195 return make_range(program_header_begin(), program_header_end()); 196 } 197 198 uint64_t getNumSections() const; 199 uintX_t getStringTableIndex() const; 200 uint32_t getExtendedSymbolTableIndex(const Elf_Sym *Sym, 201 const Elf_Shdr *SymTab, 202 ArrayRef<Elf_Word> ShndxTable) const; 203 const Elf_Ehdr *getHeader() const { return Header; } 204 ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *Sym, 205 const Elf_Shdr *SymTab, 206 ArrayRef<Elf_Word> ShndxTable) const; 207 ErrorOr<const Elf_Shdr *> getSection(uint32_t Index) const; 208 209 const Elf_Sym *getSymbol(const Elf_Shdr *Sec, uint32_t Index) const { 210 return &*(symbol_begin(Sec) + Index); 211 } 212 213 ErrorOr<StringRef> getSectionName(const Elf_Shdr *Section) const; 214 template <typename T> 215 ErrorOr<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr *Sec) const; 216 ErrorOr<ArrayRef<uint8_t> > getSectionContents(const Elf_Shdr *Sec) const; 217 }; 218 219 typedef ELFFile<ELFType<support::little, false>> ELF32LEFile; 220 typedef ELFFile<ELFType<support::little, true>> ELF64LEFile; 221 typedef ELFFile<ELFType<support::big, false>> ELF32BEFile; 222 typedef ELFFile<ELFType<support::big, true>> ELF64BEFile; 223 224 template <class ELFT> 225 uint32_t ELFFile<ELFT>::getExtendedSymbolTableIndex( 226 const Elf_Sym *Sym, const Elf_Shdr *SymTab, 227 ArrayRef<Elf_Word> ShndxTable) const { 228 assert(Sym->st_shndx == ELF::SHN_XINDEX); 229 unsigned Index = Sym - symbol_begin(SymTab); 230 231 // The size of the table was checked in getSHNDXTable. 232 return ShndxTable[Index]; 233 } 234 235 template <class ELFT> 236 ErrorOr<const typename ELFFile<ELFT>::Elf_Shdr *> 237 ELFFile<ELFT>::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab, 238 ArrayRef<Elf_Word> ShndxTable) const { 239 uint32_t Index = Sym->st_shndx; 240 if (Index == ELF::SHN_XINDEX) 241 return getSection(getExtendedSymbolTableIndex(Sym, SymTab, ShndxTable)); 242 243 if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE) 244 return nullptr; 245 return getSection(Sym->st_shndx); 246 } 247 248 template <class ELFT> 249 template <typename T> 250 ErrorOr<ArrayRef<T>> 251 ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr *Sec) const { 252 uintX_t Offset = Sec->sh_offset; 253 uintX_t Size = Sec->sh_size; 254 255 if (Size % sizeof(T)) 256 return object_error::parse_failed; 257 if (Offset + Size > Buf.size()) 258 return object_error::parse_failed; 259 260 const T *Start = reinterpret_cast<const T *>(base() + Offset); 261 return makeArrayRef(Start, Size / sizeof(T)); 262 } 263 264 template <class ELFT> 265 ErrorOr<ArrayRef<uint8_t>> 266 ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const { 267 return getSectionContentsAsArray<uint8_t>(Sec); 268 } 269 270 template <class ELFT> 271 StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const { 272 return getELFRelocationTypeName(Header->e_machine, Type); 273 } 274 275 template <class ELFT> 276 void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type, 277 SmallVectorImpl<char> &Result) const { 278 if (!isMipsELF64()) { 279 StringRef Name = getRelocationTypeName(Type); 280 Result.append(Name.begin(), Name.end()); 281 } else { 282 // The Mips N64 ABI allows up to three operations to be specified per 283 // relocation record. Unfortunately there's no easy way to test for the 284 // presence of N64 ELFs as they have no special flag that identifies them 285 // as being N64. We can safely assume at the moment that all Mips 286 // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough 287 // information to disambiguate between old vs new ABIs. 288 uint8_t Type1 = (Type >> 0) & 0xFF; 289 uint8_t Type2 = (Type >> 8) & 0xFF; 290 uint8_t Type3 = (Type >> 16) & 0xFF; 291 292 // Concat all three relocation type names. 293 StringRef Name = getRelocationTypeName(Type1); 294 Result.append(Name.begin(), Name.end()); 295 296 Name = getRelocationTypeName(Type2); 297 Result.append(1, '/'); 298 Result.append(Name.begin(), Name.end()); 299 300 Name = getRelocationTypeName(Type3); 301 Result.append(1, '/'); 302 Result.append(Name.begin(), Name.end()); 303 } 304 } 305 306 template <class ELFT> 307 const typename ELFFile<ELFT>::Elf_Sym * 308 ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel, 309 const Elf_Shdr *SymTab) const { 310 uint32_t Index = Rel->getSymbol(isMips64EL()); 311 if (Index == 0) 312 return nullptr; 313 return getEntry<Elf_Sym>(SymTab, Index); 314 } 315 316 template <class ELFT> 317 uint64_t ELFFile<ELFT>::getNumSections() const { 318 assert(Header && "Header not initialized!"); 319 if (Header->e_shnum == ELF::SHN_UNDEF && Header->e_shoff > 0) { 320 assert(SectionHeaderTable && "SectionHeaderTable not initialized!"); 321 return SectionHeaderTable->sh_size; 322 } 323 return Header->e_shnum; 324 } 325 326 template <class ELFT> 327 typename ELFFile<ELFT>::uintX_t ELFFile<ELFT>::getStringTableIndex() const { 328 if (Header->e_shnum == ELF::SHN_UNDEF) { 329 if (Header->e_shstrndx == ELF::SHN_HIRESERVE) 330 return SectionHeaderTable->sh_link; 331 if (Header->e_shstrndx >= getNumSections()) 332 return 0; 333 } 334 return Header->e_shstrndx; 335 } 336 337 template <class ELFT> 338 ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) 339 : Buf(Object) { 340 const uint64_t FileSize = Buf.size(); 341 342 if (sizeof(Elf_Ehdr) > FileSize) { 343 // File too short! 344 EC = object_error::parse_failed; 345 return; 346 } 347 348 Header = reinterpret_cast<const Elf_Ehdr *>(base()); 349 350 if (Header->e_shoff == 0) 351 return; 352 353 const uint64_t SectionTableOffset = Header->e_shoff; 354 355 if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) { 356 // Section header table goes past end of file! 357 EC = object_error::parse_failed; 358 return; 359 } 360 361 // The getNumSections() call below depends on SectionHeaderTable being set. 362 SectionHeaderTable = 363 reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset); 364 const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize; 365 366 if (SectionTableOffset + SectionTableSize > FileSize) { 367 // Section table goes past end of file! 368 EC = object_error::parse_failed; 369 return; 370 } 371 372 // Get string table sections. 373 uintX_t StringTableIndex = getStringTableIndex(); 374 if (StringTableIndex) { 375 ErrorOr<const Elf_Shdr *> StrTabSecOrErr = getSection(StringTableIndex); 376 if ((EC = StrTabSecOrErr.getError())) 377 return; 378 379 ErrorOr<StringRef> StringTableOrErr = getStringTable(*StrTabSecOrErr); 380 if ((EC = StringTableOrErr.getError())) 381 return; 382 DotShstrtab = *StringTableOrErr; 383 } 384 385 EC = std::error_code(); 386 } 387 388 template <class ELFT> 389 static bool compareAddr(uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) { 390 return VAddr < Phdr->p_vaddr; 391 } 392 393 template <class ELFT> 394 const typename ELFFile<ELFT>::Elf_Shdr *ELFFile<ELFT>::section_begin() const { 395 if (Header->e_shentsize != sizeof(Elf_Shdr)) 396 report_fatal_error( 397 "Invalid section header entry size (e_shentsize) in ELF header"); 398 return reinterpret_cast<const Elf_Shdr *>(base() + Header->e_shoff); 399 } 400 401 template <class ELFT> 402 const typename ELFFile<ELFT>::Elf_Shdr *ELFFile<ELFT>::section_end() const { 403 return section_begin() + getNumSections(); 404 } 405 406 template <class ELFT> 407 ErrorOr<const typename ELFFile<ELFT>::Elf_Dyn *> 408 ELFFile<ELFT>::dynamic_table_begin(const Elf_Phdr *Phdr) const { 409 if (!Phdr) 410 return nullptr; 411 assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header"); 412 uintX_t Offset = Phdr->p_offset; 413 if (Offset > Buf.size()) 414 return object_error::parse_failed; 415 return reinterpret_cast<const Elf_Dyn *>(base() + Offset); 416 } 417 418 template <class ELFT> 419 ErrorOr<const typename ELFFile<ELFT>::Elf_Dyn *> 420 ELFFile<ELFT>::dynamic_table_end(const Elf_Phdr *Phdr) const { 421 if (!Phdr) 422 return nullptr; 423 assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header"); 424 uintX_t Size = Phdr->p_filesz; 425 if (Size % sizeof(Elf_Dyn)) 426 return object_error::elf_invalid_dynamic_table_size; 427 // FIKME: Check for overflow? 428 uintX_t End = Phdr->p_offset + Size; 429 if (End > Buf.size()) 430 return object_error::parse_failed; 431 return reinterpret_cast<const Elf_Dyn *>(base() + End); 432 } 433 434 template <class ELFT> 435 template <typename T> 436 const T *ELFFile<ELFT>::getEntry(uint32_t Section, uint32_t Entry) const { 437 ErrorOr<const Elf_Shdr *> Sec = getSection(Section); 438 if (std::error_code EC = Sec.getError()) 439 report_fatal_error(EC.message()); 440 return getEntry<T>(*Sec, Entry); 441 } 442 443 template <class ELFT> 444 template <typename T> 445 const T *ELFFile<ELFT>::getEntry(const Elf_Shdr *Section, 446 uint32_t Entry) const { 447 return reinterpret_cast<const T *>(base() + Section->sh_offset + 448 (Entry * Section->sh_entsize)); 449 } 450 451 template <class ELFT> 452 ErrorOr<const typename ELFFile<ELFT>::Elf_Shdr *> 453 ELFFile<ELFT>::getSection(uint32_t Index) const { 454 assert(SectionHeaderTable && "SectionHeaderTable not initialized!"); 455 if (Index >= getNumSections()) 456 return object_error::invalid_section_index; 457 458 return reinterpret_cast<const Elf_Shdr *>( 459 reinterpret_cast<const char *>(SectionHeaderTable) + 460 (Index * Header->e_shentsize)); 461 } 462 463 template <class ELFT> 464 ErrorOr<StringRef> 465 ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const { 466 if (Section->sh_type != ELF::SHT_STRTAB) 467 return object_error::parse_failed; 468 uint64_t Offset = Section->sh_offset; 469 uint64_t Size = Section->sh_size; 470 if (Offset + Size > Buf.size()) 471 return object_error::parse_failed; 472 StringRef Data((const char *)base() + Section->sh_offset, Size); 473 if (Data[Size - 1] != '\0') 474 return object_error::string_table_non_null_end; 475 return Data; 476 } 477 478 template <class ELFT> 479 ErrorOr<ArrayRef<typename ELFFile<ELFT>::Elf_Word>> 480 ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const { 481 assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX); 482 const Elf_Word *ShndxTableBegin = 483 reinterpret_cast<const Elf_Word *>(base() + Section.sh_offset); 484 uintX_t Size = Section.sh_size; 485 if (Size % sizeof(uint32_t)) 486 return object_error::parse_failed; 487 uintX_t NumSymbols = Size / sizeof(uint32_t); 488 const Elf_Word *ShndxTableEnd = ShndxTableBegin + NumSymbols; 489 if (reinterpret_cast<const char *>(ShndxTableEnd) > Buf.end()) 490 return object_error::parse_failed; 491 ErrorOr<const Elf_Shdr *> SymTableOrErr = getSection(Section.sh_link); 492 if (std::error_code EC = SymTableOrErr.getError()) 493 return EC; 494 const Elf_Shdr &SymTable = **SymTableOrErr; 495 if (SymTable.sh_type != ELF::SHT_SYMTAB && 496 SymTable.sh_type != ELF::SHT_DYNSYM) 497 return object_error::parse_failed; 498 if (NumSymbols != (SymTable.sh_size / sizeof(Elf_Sym))) 499 return object_error::parse_failed; 500 return makeArrayRef(ShndxTableBegin, ShndxTableEnd); 501 } 502 503 template <class ELFT> 504 ErrorOr<StringRef> 505 ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const { 506 if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM) 507 return object_error::parse_failed; 508 ErrorOr<const Elf_Shdr *> SectionOrErr = getSection(Sec.sh_link); 509 if (std::error_code EC = SectionOrErr.getError()) 510 return EC; 511 return getStringTable(*SectionOrErr); 512 } 513 514 template <class ELFT> 515 ErrorOr<StringRef> 516 ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const { 517 uint32_t Offset = Section->sh_name; 518 if (Offset == 0) 519 return StringRef(); 520 if (Offset >= DotShstrtab.size()) 521 return object_error::parse_failed; 522 return StringRef(DotShstrtab.data() + Offset); 523 } 524 525 /// This function returns the hash value for a symbol in the .dynsym section 526 /// Name of the API remains consistent as specified in the libelf 527 /// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash 528 static inline unsigned elf_hash(StringRef &symbolName) { 529 unsigned h = 0, g; 530 for (unsigned i = 0, j = symbolName.size(); i < j; i++) { 531 h = (h << 4) + symbolName[i]; 532 g = h & 0xf0000000L; 533 if (g != 0) 534 h ^= g >> 24; 535 h &= ~g; 536 } 537 return h; 538 } 539 } // end namespace object 540 } // end namespace llvm 541 542 #endif 543