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