mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-27 21:50:29 +00:00
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
This commit is contained in:
parent
b26327c7b7
commit
f90cf923f6
@ -62,6 +62,8 @@ public:
|
||||
return reinterpret_cast<const uint8_t *>(Buf.data());
|
||||
}
|
||||
|
||||
size_t getBufSize() const { return Buf.size(); }
|
||||
|
||||
private:
|
||||
|
||||
StringRef Buf;
|
||||
@ -104,18 +106,6 @@ public:
|
||||
Header->getDataEncoding() == ELF::ELFDATA2LSB;
|
||||
}
|
||||
|
||||
ErrorOr<const Elf_Dyn *> dynamic_table_begin(const Elf_Phdr *Phdr) const;
|
||||
ErrorOr<const Elf_Dyn *> dynamic_table_end(const Elf_Phdr *Phdr) const;
|
||||
ErrorOr<Elf_Dyn_Range> dynamic_table(const Elf_Phdr *Phdr) const {
|
||||
ErrorOr<const Elf_Dyn *> Begin = dynamic_table_begin(Phdr);
|
||||
if (std::error_code EC = Begin.getError())
|
||||
return EC;
|
||||
ErrorOr<const Elf_Dyn *> End = dynamic_table_end(Phdr);
|
||||
if (std::error_code EC = End.getError())
|
||||
return EC;
|
||||
return make_range(*Begin, *End);
|
||||
}
|
||||
|
||||
const Elf_Shdr *section_begin() const;
|
||||
const Elf_Shdr *section_end() const;
|
||||
Elf_Shdr_Range sections() const {
|
||||
@ -413,34 +403,6 @@ const typename ELFFile<ELFT>::Elf_Shdr *ELFFile<ELFT>::section_end() const {
|
||||
return section_begin() + getNumSections();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<const typename ELFFile<ELFT>::Elf_Dyn *>
|
||||
ELFFile<ELFT>::dynamic_table_begin(const Elf_Phdr *Phdr) const {
|
||||
if (!Phdr)
|
||||
return nullptr;
|
||||
assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header");
|
||||
uintX_t Offset = Phdr->p_offset;
|
||||
if (Offset > Buf.size())
|
||||
return object_error::parse_failed;
|
||||
return reinterpret_cast<const Elf_Dyn *>(base() + Offset);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<const typename ELFFile<ELFT>::Elf_Dyn *>
|
||||
ELFFile<ELFT>::dynamic_table_end(const Elf_Phdr *Phdr) const {
|
||||
if (!Phdr)
|
||||
return nullptr;
|
||||
assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header");
|
||||
uintX_t Size = Phdr->p_filesz;
|
||||
if (Size % sizeof(Elf_Dyn))
|
||||
return object_error::elf_invalid_dynamic_table_size;
|
||||
// FIKME: Check for overflow?
|
||||
uintX_t End = Phdr->p_offset + Size;
|
||||
if (End > Buf.size())
|
||||
return object_error::parse_failed;
|
||||
return reinterpret_cast<const Elf_Dyn *>(base() + End);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
template <typename T>
|
||||
const T *ELFFile<ELFT>::getEntry(uint32_t Section, uint32_t Entry) const {
|
||||
|
@ -30,7 +30,6 @@ enum class object_error {
|
||||
string_table_non_null_end,
|
||||
invalid_section_index,
|
||||
bitcode_section_not_found,
|
||||
elf_invalid_dynamic_table_size,
|
||||
macho_small_load_command,
|
||||
macho_load_segment_too_many_sections,
|
||||
macho_load_segment_too_small,
|
||||
|
@ -47,8 +47,6 @@ std::string _object_error_category::message(int EV) const {
|
||||
return "Invalid section index";
|
||||
case object_error::bitcode_section_not_found:
|
||||
return "Bitcode section not found in object file";
|
||||
case object_error::elf_invalid_dynamic_table_size:
|
||||
return "Invalid dynamic table size";
|
||||
case object_error::macho_small_load_command:
|
||||
return "Mach-O load command with size < 8 bytes";
|
||||
case object_error::macho_load_segment_too_many_sections:
|
||||
|
@ -55,7 +55,7 @@ RUN: not llvm-readobj -dyn-relocations \
|
||||
RUN: %p/Inputs/corrupt-invalid-dynamic-table-size.elf.x86-64 2>&1 | \
|
||||
RUN: FileCheck --check-prefix=DYN-TABLE-SIZE %s
|
||||
|
||||
DYN-TABLE-SIZE: Invalid dynamic table size
|
||||
DYN-TABLE-SIZE: Invalid entity size
|
||||
|
||||
|
||||
RUN: not llvm-readobj -dyn-relocations \
|
||||
|
@ -127,8 +127,19 @@ private:
|
||||
typedef typename ELFO::Elf_Verdef Elf_Verdef;
|
||||
typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
|
||||
|
||||
DynRegionInfo checkDRI(DynRegionInfo DRI) {
|
||||
if (DRI.Addr < Obj->base() ||
|
||||
(const uint8_t *)DRI.Addr + DRI.Size > Obj->base() + Obj->getBufSize())
|
||||
error(llvm::object::object_error::parse_failed);
|
||||
return DRI;
|
||||
}
|
||||
|
||||
DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) {
|
||||
return checkDRI({Obj->base() + P->p_offset, P->p_filesz, EntSize});
|
||||
}
|
||||
|
||||
DynRegionInfo createDRIFrom(const Elf_Shdr *S) {
|
||||
return {Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize};
|
||||
return checkDRI({Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize});
|
||||
}
|
||||
|
||||
void parseDynamicTable(ArrayRef<const Elf_Phdr *> LoadSegments);
|
||||
@ -145,12 +156,6 @@ private:
|
||||
Elf_Rel_Range dyn_rels() const;
|
||||
Elf_Rela_Range dyn_relas() const;
|
||||
StringRef getDynamicString(uint64_t Offset) const;
|
||||
const Elf_Dyn *dynamic_table_begin() const {
|
||||
return unwrapOrError(Obj->dynamic_table_begin(DynamicProgHeader));
|
||||
}
|
||||
const Elf_Dyn *dynamic_table_end() const {
|
||||
return unwrapOrError(Obj->dynamic_table_end(DynamicProgHeader));
|
||||
}
|
||||
StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
|
||||
bool &IsDefault);
|
||||
void LoadVersionMap();
|
||||
@ -162,7 +167,7 @@ private:
|
||||
DynRegionInfo DynRelaRegion;
|
||||
DynRegionInfo DynPLTRelRegion;
|
||||
DynRegionInfo DynSymRegion;
|
||||
const Elf_Phdr *DynamicProgHeader = nullptr;
|
||||
DynRegionInfo DynamicTable;
|
||||
StringRef DynamicStringTable;
|
||||
StringRef SOName;
|
||||
const Elf_Hash *HashTable = nullptr;
|
||||
@ -199,7 +204,7 @@ private:
|
||||
|
||||
public:
|
||||
Elf_Dyn_Range dynamic_table() const {
|
||||
return unwrapOrError(Obj->dynamic_table(DynamicProgHeader));
|
||||
return DynamicTable.getAsRange<Elf_Dyn>();
|
||||
}
|
||||
|
||||
Elf_Sym_Range dynamic_symbols() const {
|
||||
@ -991,7 +996,7 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer)
|
||||
SmallVector<const Elf_Phdr *, 4> LoadSegments;
|
||||
for (const Elf_Phdr &Phdr : Obj->program_headers()) {
|
||||
if (Phdr.p_type == ELF::PT_DYNAMIC) {
|
||||
DynamicProgHeader = &Phdr;
|
||||
DynamicTable = createDRIFrom(&Phdr, sizeof(Elf_Dyn));
|
||||
continue;
|
||||
}
|
||||
if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0)
|
||||
@ -1654,8 +1659,8 @@ template <> void ELFDumper<ELFType<support::little, false>>::printUnwindInfo() {
|
||||
|
||||
template<class ELFT>
|
||||
void ELFDumper<ELFT>::printDynamicTable() {
|
||||
auto I = dynamic_table_begin();
|
||||
auto E = dynamic_table_end();
|
||||
auto I = dynamic_table().begin();
|
||||
auto E = dynamic_table().end();
|
||||
|
||||
if (I == E)
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user