llvm.org GIT mirror llvm / 6a44556
Don't error in the ELFFile constructor. All error checking now happens when the information is needed. The only thing left is the minimum size of the buffer and that can be just a precondition. I will add an ErrorOr create method in a followup commit. Also don't store a pointer to the Header, since it is just a trivial cast. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285961 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 3 years ago
2 changed file(s) with 22 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
6868
6969 StringRef Buf;
7070
71 const Elf_Ehdr *Header;
72
7371 public:
72 const Elf_Ehdr *getHeader() const {
73 return reinterpret_cast(base());
74 }
75
7476 template
7577 ErrorOr getEntry(uint32_t Section, uint32_t Entry) const;
7678 template
9597 ErrorOr getRelocationSymbol(const Elf_Rel *Rel,
9698 const Elf_Shdr *SymTab) const;
9799
98 ELFFile(StringRef Object, std::error_code &EC);
100 ELFFile(StringRef Object);
99101
100102 bool isMipsELF64() const {
101 return Header->e_machine == ELF::EM_MIPS &&
102 Header->getFileClass() == ELF::ELFCLASS64;
103 return getHeader()->e_machine == ELF::EM_MIPS &&
104 getHeader()->getFileClass() == ELF::ELFCLASS64;
103105 }
104106
105107 bool isMips64EL() const {
106 return Header->e_machine == ELF::EM_MIPS &&
107 Header->getFileClass() == ELF::ELFCLASS64 &&
108 Header->getDataEncoding() == ELF::ELFDATA2LSB;
108 return getHeader()->e_machine == ELF::EM_MIPS &&
109 getHeader()->getFileClass() == ELF::ELFCLASS64 &&
110 getHeader()->getDataEncoding() == ELF::ELFDATA2LSB;
109111 }
110112
111113 ErrorOr sections() const;
126128
127129 /// \brief Iterate over program header table.
128130 ErrorOr program_headers() const {
129 if (Header->e_phnum && Header->e_phentsize != sizeof(Elf_Phdr))
131 if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr))
130132 return object_error::parse_failed;
131 auto *Begin = reinterpret_cast(base() + Header->e_phoff);
132 return makeArrayRef(Begin, Begin+Header->e_phnum);
133 auto *Begin =
134 reinterpret_cast(base() + getHeader()->e_phoff);
135 return makeArrayRef(Begin, Begin + getHeader()->e_phnum);
133136 }
134137
135138 ErrorOr getSectionStringTable(Elf_Shdr_Range Sections) const;
136 const Elf_Ehdr *getHeader() const { return Header; }
137139 ErrorOr getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
138140 ArrayRef ShndxTable) const;
139141 ErrorOr getSection(const Elf_Sym *Sym,
268270
269271 template
270272 StringRef ELFFile::getRelocationTypeName(uint32_t Type) const {
271 return getELFRelocationTypeName(Header->e_machine, Type);
273 return getELFRelocationTypeName(getHeader()->e_machine, Type);
272274 }
273275
274276 template
315317 template
316318 ErrorOr
317319 ELFFile::getSectionStringTable(Elf_Shdr_Range Sections) const {
318 uint32_t Index = Header->e_shstrndx;
320 uint32_t Index = getHeader()->e_shstrndx;
319321 if (Index == ELF::SHN_XINDEX)
320322 Index = Sections[0].sh_link;
321323
327329 }
328330
329331 template
330 ELFFile::ELFFile(StringRef Object, std::error_code &EC) : Buf(Object) {
331 const uint64_t FileSize = Buf.size();
332
333 if (sizeof(Elf_Ehdr) > FileSize) {
334 // File too short!
335 EC = object_error::parse_failed;
336 return;
337 }
338
339 Header = reinterpret_cast(base());
340
341 if (Header->e_shoff == 0) {
342 if (Header->e_shnum != 0) {
343 // e_shnum should be zero if a file has no section header table
344 EC = object_error::parse_failed;
345 }
346 return;
347 }
348
349 EC = std::error_code();
332 ELFFile::ELFFile(StringRef Object) : Buf(Object) {
333 assert(sizeof(Elf_Ehdr) <= Buf.size() && "Invalid buffer");
350334 }
351335
352336 template
356340
357341 template
358342 ErrorOr ELFFile::sections() const {
359 const uintX_t SectionTableOffset = Header->e_shoff;
343 const uintX_t SectionTableOffset = getHeader()->e_shoff;
360344 if (SectionTableOffset == 0)
361345 return ArrayRef();
362346
363347 // Invalid section header entry size (e_shentsize) in ELF header
364 if (Header->e_shentsize != sizeof(Elf_Shdr))
348 if (getHeader()->e_shentsize != sizeof(Elf_Shdr))
365349 return object_error::parse_failed;
366350
367351 const uint64_t FileSize = Buf.size();
377361 const Elf_Shdr *First =
378362 reinterpret_cast(base() + SectionTableOffset);
379363
380 uintX_t NumSections = Header->e_shnum;
364 uintX_t NumSections = getHeader()->e_shnum;
381365 if (NumSections == 0)
382366 NumSections = First->sh_size;
383367
772772 : ELFObjectFileBase(
773773 getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
774774 Object),
775 EF(Data.getBuffer(), EC) {
776 if (EC)
777 return;
775 EF(Data.getBuffer()) {
778776 auto SectionsOrErr = EF.sections();
779777 if ((EC = SectionsOrErr.getError()))
780778 return;