llvm.org GIT mirror llvm / f90cf92
Represent the dynamic table itself with a DynRegionInfo. The dynamic table is also an array of a fixed structure, so it can be represented with a DynReginoInfo. No major functionality change. The extra error checking is covered by existing tests with a broken dynamic program header. Idea extracted from r260488. I did the extra cleanups. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261107 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 4 years ago
5 changed file(s) with 20 addition(s) and 56 deletion(s). Raw diff Collapse all Expand all
6161 return reinterpret_cast(Buf.data());
6262 }
6363
64 size_t getBufSize() const { return Buf.size(); }
65
6466 private:
6567
6668 StringRef Buf;
101103 return Header->e_machine == ELF::EM_MIPS &&
102104 Header->getFileClass() == ELF::ELFCLASS64 &&
103105 Header->getDataEncoding() == ELF::ELFDATA2LSB;
104 }
105
106 ErrorOr dynamic_table_begin(const Elf_Phdr *Phdr) const;
107 ErrorOr dynamic_table_end(const Elf_Phdr *Phdr) const;
108 ErrorOr dynamic_table(const Elf_Phdr *Phdr) const {
109 ErrorOr Begin = dynamic_table_begin(Phdr);
110 if (std::error_code EC = Begin.getError())
111 return EC;
112 ErrorOr End = dynamic_table_end(Phdr);
113 if (std::error_code EC = End.getError())
114 return EC;
115 return make_range(*Begin, *End);
116106 }
117107
118108 const Elf_Shdr *section_begin() const;
413403 }
414404
415405 template
416 ErrorOr::Elf_Dyn *>
417 ELFFile::dynamic_table_begin(const Elf_Phdr *Phdr) const {
418 if (!Phdr)
419 return nullptr;
420 assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header");
421 uintX_t Offset = Phdr->p_offset;
422 if (Offset > Buf.size())
423 return object_error::parse_failed;
424 return reinterpret_cast(base() + Offset);
425 }
426
427 template
428 ErrorOr::Elf_Dyn *>
429 ELFFile::dynamic_table_end(const Elf_Phdr *Phdr) const {
430 if (!Phdr)
431 return nullptr;
432 assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header");
433 uintX_t Size = Phdr->p_filesz;
434 if (Size % sizeof(Elf_Dyn))
435 return object_error::elf_invalid_dynamic_table_size;
436 // FIKME: Check for overflow?
437 uintX_t End = Phdr->p_offset + Size;
438 if (End > Buf.size())
439 return object_error::parse_failed;
440 return reinterpret_cast(base() + End);
441 }
442
443 template
444406 template
445407 const T *ELFFile::getEntry(uint32_t Section, uint32_t Entry) const {
446408 ErrorOr Sec = getSection(Section);
2929 string_table_non_null_end,
3030 invalid_section_index,
3131 bitcode_section_not_found,
32 elf_invalid_dynamic_table_size,
3332 macho_small_load_command,
3433 macho_load_segment_too_many_sections,
3534 macho_load_segment_too_small,
4646 return "Invalid section index";
4747 case object_error::bitcode_section_not_found:
4848 return "Bitcode section not found in object file";
49 case object_error::elf_invalid_dynamic_table_size:
50 return "Invalid dynamic table size";
5149 case object_error::macho_small_load_command:
5250 return "Mach-O load command with size < 8 bytes";
5351 case object_error::macho_load_segment_too_many_sections:
5454 RUN: %p/Inputs/corrupt-invalid-dynamic-table-size.elf.x86-64 2>&1 | \
5555 RUN: FileCheck --check-prefix=DYN-TABLE-SIZE %s
5656
57 DYN-TABLE-SIZE: Invalid dynamic table size
57 DYN-TABLE-SIZE: Invalid entity size
5858
5959
6060 RUN: not llvm-readobj -dyn-relocations \
126126 typedef typename ELFO::Elf_Verdef Elf_Verdef;
127127 typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
128128
129 DynRegionInfo checkDRI(DynRegionInfo DRI) {
130 if (DRI.Addr < Obj->base() ||
131 (const uint8_t *)DRI.Addr + DRI.Size > Obj->base() + Obj->getBufSize())
132 error(llvm::object::object_error::parse_failed);
133 return DRI;
134 }
135
136 DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) {
137 return checkDRI({Obj->base() + P->p_offset, P->p_filesz, EntSize});
138 }
139
129140 DynRegionInfo createDRIFrom(const Elf_Shdr *S) {
130 return {Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize};
141 return checkDRI({Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize});
131142 }
132143
133144 void parseDynamicTable(ArrayRef LoadSegments);
144155 Elf_Rel_Range dyn_rels() const;
145156 Elf_Rela_Range dyn_relas() const;
146157 StringRef getDynamicString(uint64_t Offset) const;
147 const Elf_Dyn *dynamic_table_begin() const {
148 return unwrapOrError(Obj->dynamic_table_begin(DynamicProgHeader));
149 }
150 const Elf_Dyn *dynamic_table_end() const {
151 return unwrapOrError(Obj->dynamic_table_end(DynamicProgHeader));
152 }
153158 StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
154159 bool &IsDefault);
155160 void LoadVersionMap();
161166 DynRegionInfo DynRelaRegion;
162167 DynRegionInfo DynPLTRelRegion;
163168 DynRegionInfo DynSymRegion;
164 const Elf_Phdr *DynamicProgHeader = nullptr;
169 DynRegionInfo DynamicTable;
165170 StringRef DynamicStringTable;
166171 StringRef SOName;
167172 const Elf_Hash *HashTable = nullptr;
198203
199204 public:
200205 Elf_Dyn_Range dynamic_table() const {
201 return unwrapOrError(Obj->dynamic_table(DynamicProgHeader));
206 return DynamicTable.getAsRange();
202207 }
203208
204209 Elf_Sym_Range dynamic_symbols() const {
990995 SmallVector LoadSegments;
991996 for (const Elf_Phdr &Phdr : Obj->program_headers()) {
992997 if (Phdr.p_type == ELF::PT_DYNAMIC) {
993 DynamicProgHeader = &Phdr;
998 DynamicTable = createDRIFrom(&Phdr, sizeof(Elf_Dyn));
994999 continue;
9951000 }
9961001 if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0)
16531658
16541659 template
16551660 void ELFDumper::printDynamicTable() {
1656 auto I = dynamic_table_begin();
1657 auto E = dynamic_table_end();
1661 auto I = dynamic_table().begin();
1662 auto E = dynamic_table().end();
16581663
16591664 if (I == E)
16601665 return;