[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
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index e751e6d..4a5be0b 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -206,7 +206,8 @@
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 @@
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 @@
}
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 @@
}
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 @@
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));
+ 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_FILTER:
- printLibrary(OS, "Filter library", getDynamicString(Value));
- 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 @@
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);