summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Henderson <jh7370@my.bristol.ac.uk>2019-06-14 12:02:01 +0000
committerJames Henderson <jh7370@my.bristol.ac.uk>2019-06-14 12:02:01 +0000
commitf7cfabb45d87121962be8a6e0d81009a2b8788a6 (patch)
treee6e1897818821e3875d2a9c3b79df2e1b131b3e4
parent78b2cf71f5f2cdcbcbea06f069022fa4818f42a4 (diff)
downloadbcm5719-llvm-f7cfabb45d87121962be8a6e0d81009a2b8788a6.tar.gz
bcm5719-llvm-f7cfabb45d87121962be8a6e0d81009a2b8788a6.zip
[llvm-readobj] Don't abort printing of dynamic table if string reference is invalid
If dynamic table is missing, output "dynamic strtab not found'. If the index is out of range, output "Invalid Offset<..>". https://bugs.llvm.org/show_bug.cgi?id=40807 Reviewed by: jhenderson, grimar, MaskRay Differential Revision: https://reviews.llvm.org/D63084 Patch by Yuanfang Chen. llvm-svn: 363374
-rwxr-xr-xllvm/test/Object/Inputs/corrupt-invalid-strtab.elf.x86-64bin1712 -> 0 bytes
-rw-r--r--llvm/test/Object/corrupt.test7
-rw-r--r--llvm/test/tools/llvm-readobj/elf-dynamic-malformed.test53
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp62
4 files changed, 81 insertions, 41 deletions
diff --git a/llvm/test/Object/Inputs/corrupt-invalid-strtab.elf.x86-64 b/llvm/test/Object/Inputs/corrupt-invalid-strtab.elf.x86-64
deleted file mode 100755
index ab9a63ea796..00000000000
--- a/llvm/test/Object/Inputs/corrupt-invalid-strtab.elf.x86-64
+++ /dev/null
Binary files differ
diff --git a/llvm/test/Object/corrupt.test b/llvm/test/Object/corrupt.test
index 49f973d43b1..6953768c47d 100644
--- a/llvm/test/Object/corrupt.test
+++ b/llvm/test/Object/corrupt.test
@@ -25,13 +25,6 @@ RUN: 2>&1 | FileCheck --check-prefix=VER %s
VER: error: Invalid version entry
-
-// The file is missing the dynamic string table but has references to it.
-RUN: not llvm-readobj --dynamic-table %p/Inputs/corrupt-invalid-strtab.elf.x86-64 \
-RUN: 2>&1 | FileCheck --check-prefix=STRTAB %s
-
-STRTAB: Invalid dynamic string table reference
-
RUN: not llvm-readobj -l \
RUN: %p/Inputs/corrupt-invalid-phentsize.elf.x86-64 2>&1 | \
RUN: FileCheck --check-prefix=PHENTSIZE %s
diff --git a/llvm/test/tools/llvm-readobj/elf-dynamic-malformed.test b/llvm/test/tools/llvm-readobj/elf-dynamic-malformed.test
index abc0f89310c..337fedec5a5 100644
--- a/llvm/test/tools/llvm-readobj/elf-dynamic-malformed.test
+++ b/llvm/test/tools/llvm-readobj/elf-dynamic-malformed.test
@@ -68,13 +68,28 @@ ProgramHeaders:
Sections:
- Section: .dynamic
-# Test handling of string references pointing past the end of the dynamic string table. In this case,
-# we have a DT_NEEDED tag pointing at offset 1 in a 1-byte string table.
+# Test handling of string references pointing past the end of the dynamic string table.
# RUN: yaml2obj %s --docnum=3 -o %t.bad-string
-# RUN: not llvm-readobj --dynamic-table %t.bad-string 2>&1 | FileCheck %s --check-prefix BAD-STRING
-# RUN: not llvm-readelf --dynamic-table %t.bad-string 2>&1 | FileCheck %s --check-prefix BAD-STRING
+# RUN: llvm-readobj --dynamic-table %t.bad-string | FileCheck %s --check-prefix BAD-STRING-LLVM
+# RUN: llvm-readelf --dynamic-table %t.bad-string | FileCheck %s --check-prefix BAD-STRING-GNU
-# BAD-STRING: Invalid dynamic string table reference
+# BAD-STRING-LLVM: 0x000000000000000A STRSZ 1 (bytes)
+# BAD-STRING-LLVM: 0x0000000000000001 NEEDED Shared library: <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000007FFFFFFF FILTER Filter library: <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000007FFFFFFD AUXILIARY Auxiliary library: <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000007FFFFFFE USED Not needed object: <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000000000000E SONAME Library soname: <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000000000000F RPATH <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000000000001D RUNPATH <Invalid offset 0x1>
+
+# BAD-STRING-GNU: 0x000000000000000a (STRSZ) 1 (bytes)
+# BAD-STRING-GNU: 0x0000000000000001 (NEEDED) Shared library: <Invalid offset 0x1>
+# BAD-STRING-GNU: 0x000000007fffffff (FILTER) Filter library: <Invalid offset 0x1>
+# BAD-STRING-GNU: 0x000000007ffffffd (AUXILIARY) Auxiliary library: <Invalid offset 0x1>
+# BAD-STRING-GNU: 0x000000007ffffffe (USED) Not needed object: <Invalid offset 0x1>
+# BAD-STRING-GNU: 0x000000000000000e (SONAME) Library soname: <Invalid offset 0x1>
+# BAD-STRING-GNU: 0x000000000000000f (RPATH) <Invalid offset 0x1>
+# BAD-STRING-GNU: 0x000000000000001d (RUNPATH) <Invalid offset 0x1>
--- !ELF
FileHeader:
@@ -96,6 +111,18 @@ Sections:
Value: 1
- Tag: DT_NEEDED
Value: 1
+ - Tag: DT_FILTER
+ Value: 1
+ - Tag: DT_AUXILIARY
+ Value: 1
+ - Tag: DT_USED
+ Value: 1
+ - Tag: DT_SONAME
+ Value: 1
+ - Tag: DT_RPATH
+ Value: 1
+ - Tag: DT_RUNPATH
+ Value: 1
- Tag: DT_NULL
Value: 0
ProgramHeaders:
@@ -111,11 +138,19 @@ ProgramHeaders:
# Test handling of DT_STRTAB pointing outside the file's address space.
# RUN: yaml2obj %s --docnum=4 -o %t.bad-strtab
-# RUN: not llvm-readobj --dynamic-table %t.bad-strtab 2>&1 | FileCheck %s --check-prefix BAD-STRTAB
-# RUN: not llvm-readelf --dynamic-table %t.bad-strtab 2>&1 | FileCheck %s --check-prefix BAD-STRTAB
-# BAD-STRTAB: warning: Unable to parse DT_STRTAB: Virtual address is not in any segment
-# BAD-STRTAB: error: Invalid dynamic string table reference
+# RUN: llvm-readobj --dynamic-table %t.bad-strtab 2>&1 >/dev/null | FileCheck %s --check-prefix BAD-STRTAB-ERR
+# RUN: llvm-readelf --dynamic-table %t.bad-strtab 2>&1 >/dev/null | FileCheck %s --check-prefix BAD-STRTAB-ERR
+# BAD-STRTAB-ERR: warning: Unable to parse DT_STRTAB: Virtual address is not in any segment
+
+# RUN: llvm-readobj --dynamic-table --needed-libs %t.bad-strtab | FileCheck %s --check-prefixes=BAD-STRTAB,BAD-STRTAB-LLVM
+# RUN: llvm-readelf --dynamic-table --needed-libs %t.bad-strtab | FileCheck %s --check-prefixes=BAD-STRTAB,BAD-STRTAB-GNU
+# BAD-STRTAB-LLVM: LoadName: <Not found>
+# BAD-STRTAB-LLVM: 0x0000000000000001 NEEDED Shared library: <String table is empty or was not found>
+# BAD-STRTAB-GNU: 0x0000000000000001 (NEEDED) Shared library: <String table is empty or was not found>
+# BAD-STRTAB: NeededLibraries [
+# BAD-STRTAB: <Library name index out of range>
+# BAD-STRTAB: ]
--- !ELF
FileHeader:
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index e751e6db9eb..4a5be0ba84f 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -206,7 +206,8 @@ private:
void loadDynamicTable(const ELFFile<ELFT> *Obj);
void parseDynamicTable();
- StringRef getDynamicString(uint64_t Offset) const;
+ void printDynamicString(uint64_t Offset, raw_ostream &OS,
+ bool WithBracket = true) const;
StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
bool &IsDefault) const;
void LoadVersionMap() const;
@@ -221,7 +222,7 @@ private:
DynRegionInfo DynSymRegion;
DynRegionInfo DynamicTable;
StringRef DynamicStringTable;
- StringRef SOName;
+ StringRef SOName = "<Not found>";
const Elf_Hash *HashTable = nullptr;
const Elf_GnuHash *GnuHashTable = nullptr;
const Elf_Shdr *DotSymtabSec = nullptr;
@@ -1626,8 +1627,8 @@ template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() {
}
if (StringTableBegin)
DynamicStringTable = StringRef(StringTableBegin, StringTableSize);
- if (SONameOffset)
- SOName = getDynamicString(SONameOffset);
+ if (SONameOffset && SONameOffset < DynamicStringTable.size())
+ SOName = DynamicStringTable.data() + SONameOffset;
}
template <typename ELFT>
@@ -1790,14 +1791,19 @@ void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
}
template <class ELFT>
-StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {
- if (Value >= DynamicStringTable.size())
- reportError("Invalid dynamic string table reference");
- return StringRef(DynamicStringTable.data() + Value);
-}
-
-static void printLibrary(raw_ostream &OS, const Twine &Tag, const Twine &Name) {
- OS << Tag << ": [" << Name << "]";
+void ELFDumper<ELFT>::printDynamicString(uint64_t Value,
+ raw_ostream &OS,
+ bool WithBracket) const {
+ if (DynamicStringTable.empty())
+ OS << "<String table is empty or was not found> ";
+ else if (Value < DynamicStringTable.size()) {
+ if (WithBracket)
+ OS << "[";
+ OS << StringRef(DynamicStringTable.data() + Value);
+ if (WithBracket)
+ OS << "]";
+ } else
+ OS << "<Invalid offset 0x" << utohexstr(Value) << ">";
}
template <class ELFT>
@@ -1943,23 +1949,24 @@ void ELFDumper<ELFT>::printDynamicEntry(raw_ostream &OS, uint64_t Type,
OS << Value << " (bytes)";
break;
case DT_NEEDED:
- printLibrary(OS, "Shared library", getDynamicString(Value));
- break;
case DT_SONAME:
- printLibrary(OS, "Library soname", getDynamicString(Value));
- break;
case DT_AUXILIARY:
- printLibrary(OS, "Auxiliary library", getDynamicString(Value));
- break;
case DT_USED:
- printLibrary(OS, "Not needed object", getDynamicString(Value));
- break;
- case DT_FILTER:
- printLibrary(OS, "Filter library", getDynamicString(Value));
+ case DT_FILTER: {
+ const std::map<uint64_t, const char*> TagNames = {
+ {DT_NEEDED, "Shared library"},
+ {DT_SONAME, "Library soname"},
+ {DT_AUXILIARY, "Auxiliary library"},
+ {DT_USED, "Not needed object"},
+ {DT_FILTER, "Filter library"},
+ };
+ OS << TagNames.at(Type) << ": ";
+ printDynamicString(Value, OS);
break;
+ }
case DT_RPATH:
case DT_RUNPATH:
- OS << getDynamicString(Value);
+ printDynamicString(Value, OS, false);
break;
case DT_FLAGS:
printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS);
@@ -2004,8 +2011,13 @@ template <class ELFT> void ELFDumper<ELFT>::printNeededLibraries() {
LibsTy Libs;
for (const auto &Entry : dynamic_table())
- if (Entry.d_tag == ELF::DT_NEEDED)
- Libs.push_back(getDynamicString(Entry.d_un.d_val));
+ if (Entry.d_tag == ELF::DT_NEEDED) {
+ uint64_t Value = Entry.d_un.d_val;
+ if (Value < DynamicStringTable.size())
+ Libs.push_back(StringRef(DynamicStringTable.data() + Value));
+ else
+ Libs.push_back("<Library name index out of range>");
+ }
llvm::stable_sort(Libs);
OpenPOWER on IntegriCloud