summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Object/ELF.h42
-rw-r--r--llvm/include/llvm/Object/Error.h1
-rw-r--r--llvm/lib/Object/Error.cpp2
-rw-r--r--llvm/test/Object/corrupt.test2
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp29
5 files changed, 20 insertions, 56 deletions
diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h
index d01c3cfab16..6a100a55152 100644
--- a/llvm/include/llvm/Object/ELF.h
+++ b/llvm/include/llvm/Object/ELF.h
@@ -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 {
@@ -414,34 +404,6 @@ const typename ELFFile<ELFT>::Elf_Shdr *ELFFile<ELFT>::section_end() const {
}
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 {
ErrorOr<const Elf_Shdr *> Sec = getSection(Section);
diff --git a/llvm/include/llvm/Object/Error.h b/llvm/include/llvm/Object/Error.h
index 0f79a6ed0dd..aa320bb51a4 100644
--- a/llvm/include/llvm/Object/Error.h
+++ b/llvm/include/llvm/Object/Error.h
@@ -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,
diff --git a/llvm/lib/Object/Error.cpp b/llvm/lib/Object/Error.cpp
index 7ecc3a19af9..7ca2f12f092 100644
--- a/llvm/lib/Object/Error.cpp
+++ b/llvm/lib/Object/Error.cpp
@@ -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:
diff --git a/llvm/test/Object/corrupt.test b/llvm/test/Object/corrupt.test
index 7208566c25b..3ce7dc7f5e9 100644
--- a/llvm/test/Object/corrupt.test
+++ b/llvm/test/Object/corrupt.test
@@ -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 \
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 86b6ab635e0..e15a7eb9570 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -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;
OpenPOWER on IntegriCloud