[llvm] r244320 - Add dynamic_table iterators back to ELF.h.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 7 08:25:20 PDT 2015
Author: rafael
Date: Fri Aug 7 10:25:20 2015
New Revision: 244320
URL: http://llvm.org/viewvc/llvm-project?rev=244320&view=rev
Log:
Add dynamic_table iterators back to ELF.h.
In tree they are only used by llvm-readobj, but it is also used by
https://github.com/mono/CppSharp.
While at it, add some missing error checking.
Added:
llvm/trunk/test/Object/Inputs/corrupt-invalid-dynamic-table-offset.elf.x86-64 (with props)
Modified:
llvm/trunk/include/llvm/Object/ELF.h
llvm/trunk/include/llvm/Object/Error.h
llvm/trunk/lib/Object/Error.cpp
llvm/trunk/test/Object/corrupt.test
llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
Modified: llvm/trunk/include/llvm/Object/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELF.h?rev=244320&r1=244319&r2=244320&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELF.h (original)
+++ llvm/trunk/include/llvm/Object/ELF.h Fri Aug 7 10:25:20 2015
@@ -141,6 +141,18 @@ 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 {
@@ -466,6 +478,34 @@ const typename ELFFile<ELFT>::Elf_Shdr *
}
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);
Modified: llvm/trunk/include/llvm/Object/Error.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Error.h?rev=244320&r1=244319&r2=244320&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Error.h (original)
+++ llvm/trunk/include/llvm/Object/Error.h Fri Aug 7 10:25:20 2015
@@ -30,6 +30,7 @@ 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,
Modified: llvm/trunk/lib/Object/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/Error.cpp?rev=244320&r1=244319&r2=244320&view=diff
==============================================================================
--- llvm/trunk/lib/Object/Error.cpp (original)
+++ llvm/trunk/lib/Object/Error.cpp Fri Aug 7 10:25:20 2015
@@ -47,6 +47,8 @@ std::string _object_error_category::mess
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:
Added: llvm/trunk/test/Object/Inputs/corrupt-invalid-dynamic-table-offset.elf.x86-64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/corrupt-invalid-dynamic-table-offset.elf.x86-64?rev=244320&view=auto
==============================================================================
Binary files llvm/trunk/test/Object/Inputs/corrupt-invalid-dynamic-table-offset.elf.x86-64 (added) and llvm/trunk/test/Object/Inputs/corrupt-invalid-dynamic-table-offset.elf.x86-64 Fri Aug 7 10:25:20 2015 differ
Propchange: llvm/trunk/test/Object/Inputs/corrupt-invalid-dynamic-table-offset.elf.x86-64
------------------------------------------------------------------------------
svn:executable = *
Modified: llvm/trunk/test/Object/corrupt.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/corrupt.test?rev=244320&r1=244319&r2=244320&view=diff
==============================================================================
--- llvm/trunk/test/Object/corrupt.test (original)
+++ llvm/trunk/test/Object/corrupt.test Fri Aug 7 10:25:20 2015
@@ -56,3 +56,17 @@ RUN: %p/Inputs/corrupt-invalid-dynamic
RUN: FileCheck --check-prefix=DYN-TABLE-SIZE %s
DYN-TABLE-SIZE: Invalid dynamic table size
+
+
+RUN: not llvm-readobj -dyn-relocations \
+RUN: %p/Inputs/corrupt-invalid-dynamic-table-offset.elf.x86-64 2>&1 | \
+RUN: FileCheck --check-prefix=DYN-TABLE-OFFSET %s
+
+DYN-TABLE-OFFSET: Invalid data was encountered while parsing the file.
+
+
+RUN: not llvm-readobj -dyn-relocations \
+RUN: %p/Inputs/corrupt-invalid-dynamic-table-too-large.elf.x86-64 2>&1 | \
+RUN: FileCheck --check-prefix=DYN-TABLE-TOO-LARGE %s
+
+DYN-TABLE-TOO-LARGE: Invalid data was encountered while parsing the file.
Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=244320&r1=244319&r2=244320&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Fri Aug 7 10:25:20 2015
@@ -104,10 +104,20 @@ private:
const Elf_Rela *dyn_rela_end() const;
Elf_Rela_Range dyn_relas() const;
StringRef getDynamicString(uint64_t Offset) const;
- const Elf_Dyn *dynamic_table_begin() const;
- const Elf_Dyn *dynamic_table_end() const;
+ const Elf_Dyn *dynamic_table_begin() const {
+ ErrorOr<const Elf_Dyn *> Ret = Obj->dynamic_table_begin(DynamicProgHeader);
+ error(Ret.getError());
+ return *Ret;
+ }
+ const Elf_Dyn *dynamic_table_end() const {
+ ErrorOr<const Elf_Dyn *> Ret = Obj->dynamic_table_end(DynamicProgHeader);
+ error(Ret.getError());
+ return *Ret;
+ }
Elf_Dyn_Range dynamic_table() const {
- return make_range(dynamic_table_begin(), dynamic_table_end());
+ ErrorOr<Elf_Dyn_Range> Ret = Obj->dynamic_table(DynamicProgHeader);
+ error(Ret.getError());
+ return *Ret;
}
StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
@@ -118,7 +128,7 @@ private:
const ELFO *Obj;
DynRegionInfo DynRelaRegion;
- DynRegionInfo DynamicRegion;
+ const Elf_Phdr *DynamicProgHeader = nullptr;
StringRef DynamicStringTable;
const Elf_Sym *DynSymStart = nullptr;
StringRef SOName;
@@ -798,11 +808,7 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile
SmallVector<const Elf_Phdr *, 4> LoadSegments;
for (const Elf_Phdr &Phdr : Obj->program_headers()) {
if (Phdr.p_type == ELF::PT_DYNAMIC) {
- DynamicRegion.Addr = Obj->base() + Phdr.p_offset;
- uint64_t Size = Phdr.p_filesz;
- if (Size % sizeof(Elf_Dyn))
- report_fatal_error("Invalid dynamic table size");
- DynamicRegion.Size = Phdr.p_filesz;
+ DynamicProgHeader = &Phdr;
continue;
}
if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0)
@@ -904,19 +910,6 @@ typename ELFDumper<ELFT>::Elf_Rela_Range
return make_range(dyn_rela_begin(), dyn_rela_end());
}
-template <typename ELFT>
-const typename ELFDumper<ELFT>::Elf_Dyn *
-ELFDumper<ELFT>::dynamic_table_begin() const {
- return reinterpret_cast<const Elf_Dyn *>(DynamicRegion.Addr);
-}
-
-template <typename ELFT>
-const typename ELFDumper<ELFT>::Elf_Dyn *
-ELFDumper<ELFT>::dynamic_table_end() const {
- uint64_t Size = DynamicRegion.Size;
- return dynamic_table_begin() + Size / sizeof(Elf_Dyn);
-}
-
template<class ELFT>
void ELFDumper<ELFT>::printFileHeaders() {
const Elf_Ehdr *Header = Obj->getHeader();
More information about the llvm-commits
mailing list