llvm.org GIT mirror llvm / 5d4f1c4
Compute the section table lazily. As a consequence this move a bunch of error checking out of the constructor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285815 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 3 years ago
1 changed file(s) with 54 addition(s) and 57 deletion(s). Raw diff Collapse all Expand all
7070 StringRef Buf;
7171
7272 const Elf_Ehdr *Header;
73 const Elf_Shdr *SectionHeaderTable = nullptr;
7473
7574 public:
7675 template
146145 return makeArrayRef(program_header_begin(), program_header_end());
147146 }
148147
149 uintX_t getNumSections() const;
150148 ErrorOr getSectionStringTable() const;
149 ErrorOr getSectionStringTable(Elf_Shdr_Range Sections) const;
151150 uint32_t getExtendedSymbolTableIndex(const Elf_Sym *Sym,
152151 const Elf_Shdr *SymTab,
153152 ArrayRef ShndxTable) const;
285284 }
286285
287286 template
288 typename ELFT::uint ELFFile::getNumSections() const {
289 assert(Header && "Header not initialized!");
290 if (Header->e_shnum == ELF::SHN_UNDEF && Header->e_shoff > 0) {
291 assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
292 return SectionHeaderTable->sh_size;
293 }
294 return Header->e_shnum;
295 }
296
297 template
298287 ErrorOr ELFFile::getSectionStringTable() const {
288 auto SectionsOrErr = sections();
289 if (std::error_code EC = SectionsOrErr.getError())
290 return EC;
291 return getSectionStringTable(*SectionsOrErr);
292 }
293
294 template
295 ErrorOr
296 ELFFile::getSectionStringTable(Elf_Shdr_Range Sections) const {
299297 uint32_t Index = Header->e_shstrndx;
300298 if (Index == ELF::SHN_XINDEX)
301 Index = SectionHeaderTable->sh_link;
299 Index = Sections[0].sh_link;
300
302301 if (!Index) // no section string table.
303302 return "";
304 ErrorOr StrTabSecOrErr = getSection(Index);
305 if (std::error_code EC = StrTabSecOrErr.getError())
306 return EC;
307 return getStringTable(*StrTabSecOrErr);
303 if (Index >= Sections.size())
304 return object_error::parse_failed;
305 return getStringTable(&Sections[Index]);
308306 }
309307
310308 template
327325 return;
328326 }
329327
330 const uint64_t SectionTableOffset = Header->e_shoff;
331
332 if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) {
333 // Section header table goes past end of file!
334 EC = object_error::parse_failed;
335 return;
336 }
337
338 if (SectionTableOffset & (alignof(Elf_Shdr) - 1)) {
339 // Invalid address alignment of section headers
340 EC = object_error::parse_failed;
341 return;
342 }
343
344 // The getNumSections() call below depends on SectionHeaderTable being set.
345 SectionHeaderTable =
346 reinterpret_cast(base() + SectionTableOffset);
347 if (getNumSections() > UINT64_MAX / Header->e_shentsize) {
348 // Section table goes past end of file!
349 EC = object_error::parse_failed;
350 return;
351 }
352
353 const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
354
355 if (SectionTableOffset + SectionTableSize > FileSize) {
356 // Section table goes past end of file!
357 EC = object_error::parse_failed;
358 return;
359 }
360
361328 EC = std::error_code();
362329 }
363330
368335
369336 template
370337 ErrorOr ELFFile::sections() const {
338 const uintX_t SectionTableOffset = Header->e_shoff;
339 if (SectionTableOffset == 0)
340 return ArrayRef();
341
371342 // Invalid section header entry size (e_shentsize) in ELF header
372343 if (Header->e_shentsize != sizeof(Elf_Shdr))
373344 return object_error::parse_failed;
374 auto *Begin = reinterpret_cast(base() + Header->e_shoff);
375 return makeArrayRef(Begin, Begin + getNumSections());
345
346 const uint64_t FileSize = Buf.size();
347
348 // Section header table goes past end of file!
349 if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
350 return object_error::parse_failed;
351
352 // Invalid address alignment of section headers
353 if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
354 return object_error::parse_failed;
355
356 const Elf_Shdr *First =
357 reinterpret_cast(base() + SectionTableOffset);
358
359 uintX_t NumSections = Header->e_shnum;
360 if (NumSections == 0)
361 NumSections = First->sh_size;
362
363 // Section table goes past end of file!
364 if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
365 return object_error::parse_failed;
366
367 const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
368
369 // Section table goes past end of file!
370 if (SectionTableOffset + SectionTableSize > FileSize)
371 return object_error::parse_failed;
372
373 return makeArrayRef(First, NumSections);
376374 }
377375
378376 template
395393 template
396394 ErrorOr::Elf_Shdr *>
397395 ELFFile::getSection(uint32_t Index) const {
398 assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
399 if (Index >= getNumSections())
396 auto TableOrErr = sections();
397 if (std::error_code EC = TableOrErr.getError())
398 return EC;
399 ArrayRef Table = *TableOrErr;
400 if (Index >= Table.size())
400401 return object_error::invalid_section_index;
401
402 const Elf_Shdr *Addr = SectionHeaderTable + Index;
403 if (reinterpret_cast(Addr) >= base() + getBufSize())
404 return object_error::invalid_section_index;
405 return Addr;
402 return &Table[Index];
406403 }
407404
408405 template