llvm.org GIT mirror llvm / c38aa92
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363374 91177308-0d34-0410-b5e6-96231b3b80d8 James Henderson a month ago
4 changed file(s) with 86 addition(s) and 46 deletion(s). Raw diff Collapse all Expand all
test/Object/Inputs/corrupt-invalid-strtab.elf.x86-64 less more
Binary diff not shown
2323 RUN: 2>&1 | FileCheck --check-prefix=VER %s
2424
2525 VER: error: Invalid version entry
26
27
28 // The file is missing the dynamic string table but has references to it.
29 RUN: not llvm-readobj --dynamic-table %p/Inputs/corrupt-invalid-strtab.elf.x86-64 \
30 RUN: 2>&1 | FileCheck --check-prefix=STRTAB %s
31
32 STRTAB: Invalid dynamic string table reference
3326
3427 RUN: not llvm-readobj -l \
3528 RUN: %p/Inputs/corrupt-invalid-phentsize.elf.x86-64 2>&1 | \
6767 Sections:
6868 - Section: .dynamic
6969
70 # Test handling of string references pointing past the end of the dynamic string table. In this case,
71 # we have a DT_NEEDED tag pointing at offset 1 in a 1-byte string table.
70 # Test handling of string references pointing past the end of the dynamic string table.
7271 # RUN: yaml2obj %s --docnum=3 -o %t.bad-string
73 # RUN: not llvm-readobj --dynamic-table %t.bad-string 2>&1 | FileCheck %s --check-prefix BAD-STRING
74 # RUN: not llvm-readelf --dynamic-table %t.bad-string 2>&1 | FileCheck %s --check-prefix BAD-STRING
75
76 # BAD-STRING: Invalid dynamic string table reference
72 # RUN: llvm-readobj --dynamic-table %t.bad-string | FileCheck %s --check-prefix BAD-STRING-LLVM
73 # RUN: llvm-readelf --dynamic-table %t.bad-string | FileCheck %s --check-prefix BAD-STRING-GNU
74
75 # BAD-STRING-LLVM: 0x000000000000000A STRSZ 1 (bytes)
76 # BAD-STRING-LLVM: 0x0000000000000001 NEEDED Shared library:
77 # BAD-STRING-LLVM: 0x000000007FFFFFFF FILTER Filter library:
78 # BAD-STRING-LLVM: 0x000000007FFFFFFD AUXILIARY Auxiliary library:
79 # BAD-STRING-LLVM: 0x000000007FFFFFFE USED Not needed object:
80 # BAD-STRING-LLVM: 0x000000000000000E SONAME Library soname:
81 # BAD-STRING-LLVM: 0x000000000000000F RPATH
82 # BAD-STRING-LLVM: 0x000000000000001D RUNPATH
83
84 # BAD-STRING-GNU: 0x000000000000000a (STRSZ) 1 (bytes)
85 # BAD-STRING-GNU: 0x0000000000000001 (NEEDED) Shared library:
86 # BAD-STRING-GNU: 0x000000007fffffff (FILTER) Filter library:
87 # BAD-STRING-GNU: 0x000000007ffffffd (AUXILIARY) Auxiliary library:
88 # BAD-STRING-GNU: 0x000000007ffffffe (USED) Not needed object:
89 # BAD-STRING-GNU: 0x000000000000000e (SONAME) Library soname:
90 # BAD-STRING-GNU: 0x000000000000000f (RPATH)
91 # BAD-STRING-GNU: 0x000000000000001d (RUNPATH)
7792
7893 --- !ELF
7994 FileHeader:
95110 Value: 1
96111 - Tag: DT_NEEDED
97112 Value: 1
113 - Tag: DT_FILTER
114 Value: 1
115 - Tag: DT_AUXILIARY
116 Value: 1
117 - Tag: DT_USED
118 Value: 1
119 - Tag: DT_SONAME
120 Value: 1
121 - Tag: DT_RPATH
122 Value: 1
123 - Tag: DT_RUNPATH
124 Value: 1
98125 - Tag: DT_NULL
99126 Value: 0
100127 ProgramHeaders:
110137
111138 # Test handling of DT_STRTAB pointing outside the file's address space.
112139 # RUN: yaml2obj %s --docnum=4 -o %t.bad-strtab
113 # RUN: not llvm-readobj --dynamic-table %t.bad-strtab 2>&1 | FileCheck %s --check-prefix BAD-STRTAB
114 # RUN: not llvm-readelf --dynamic-table %t.bad-strtab 2>&1 | FileCheck %s --check-prefix BAD-STRTAB
115
116 # BAD-STRTAB: warning: Unable to parse DT_STRTAB: Virtual address is not in any segment
117 # BAD-STRTAB: error: Invalid dynamic string table reference
140
141 # RUN: llvm-readobj --dynamic-table %t.bad-strtab 2>&1 >/dev/null | FileCheck %s --check-prefix BAD-STRTAB-ERR
142 # RUN: llvm-readelf --dynamic-table %t.bad-strtab 2>&1 >/dev/null | FileCheck %s --check-prefix BAD-STRTAB-ERR
143 # BAD-STRTAB-ERR: warning: Unable to parse DT_STRTAB: Virtual address is not in any segment
144
145 # RUN: llvm-readobj --dynamic-table --needed-libs %t.bad-strtab | FileCheck %s --check-prefixes=BAD-STRTAB,BAD-STRTAB-LLVM
146 # RUN: llvm-readelf --dynamic-table --needed-libs %t.bad-strtab | FileCheck %s --check-prefixes=BAD-STRTAB,BAD-STRTAB-GNU
147 # BAD-STRTAB-LLVM: LoadName:
148 # BAD-STRTAB-LLVM: 0x0000000000000001 NEEDED Shared library:
149 # BAD-STRTAB-GNU: 0x0000000000000001 (NEEDED) Shared library:
150 # BAD-STRTAB: NeededLibraries [
151 # BAD-STRTAB:
152 # BAD-STRTAB: ]
118153
119154 --- !ELF
120155 FileHeader:
205205 void loadDynamicTable(const ELFFile *Obj);
206206 void parseDynamicTable();
207207
208 StringRef getDynamicString(uint64_t Offset) const;
208 void printDynamicString(uint64_t Offset, raw_ostream &OS,
209 bool WithBracket = true) const;
209210 StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
210211 bool &IsDefault) const;
211212 void LoadVersionMap() const;
220221 DynRegionInfo DynSymRegion;
221222 DynRegionInfo DynamicTable;
222223 StringRef DynamicStringTable;
223 StringRef SOName;
224 StringRef SOName = "";
224225 const Elf_Hash *HashTable = nullptr;
225226 const Elf_GnuHash *GnuHashTable = nullptr;
226227 const Elf_Shdr *DotSymtabSec = nullptr;
16251626 }
16261627 if (StringTableBegin)
16271628 DynamicStringTable = StringRef(StringTableBegin, StringTableSize);
1628 if (SONameOffset)
1629 SOName = getDynamicString(SONameOffset);
1629 if (SONameOffset && SONameOffset < DynamicStringTable.size())
1630 SOName = DynamicStringTable.data() + SONameOffset;
16301631 }
16311632
16321633 template
17891790 }
17901791
17911792 template
1792 StringRef ELFDumper::getDynamicString(uint64_t Value) const {
1793 if (Value >= DynamicStringTable.size())
1794 reportError("Invalid dynamic string table reference");
1795 return StringRef(DynamicStringTable.data() + Value);
1796 }
1797
1798 static void printLibrary(raw_ostream &OS, const Twine &Tag, const Twine &Name) {
1799 OS << Tag << ": [" << Name << "]";
1793 void ELFDumper::printDynamicString(uint64_t Value,
1794 raw_ostream &OS,
1795 bool WithBracket) const {
1796 if (DynamicStringTable.empty())
1797 OS << " ";
1798 else if (Value < DynamicStringTable.size()) {
1799 if (WithBracket)
1800 OS << "[";
1801 OS << StringRef(DynamicStringTable.data() + Value);
1802 if (WithBracket)
1803 OS << "]";
1804 } else
1805 OS << "";
18001806 }
18011807
18021808 template
19421948 OS << Value << " (bytes)";
19431949 break;
19441950 case DT_NEEDED:
1945 printLibrary(OS, "Shared library", getDynamicString(Value));
1951 case DT_SONAME:
1952 case DT_AUXILIARY:
1953 case DT_USED:
1954 case DT_FILTER: {
1955 const std::map TagNames = {
1956 {DT_NEEDED, "Shared library"},
1957 {DT_SONAME, "Library soname"},
1958 {DT_AUXILIARY, "Auxiliary library"},
1959 {DT_USED, "Not needed object"},
1960 {DT_FILTER, "Filter library"},
1961 };
1962 OS << TagNames.at(Type) << ": ";
1963 printDynamicString(Value, OS);
19461964 break;
1947 case DT_SONAME:
1948 printLibrary(OS, "Library soname", getDynamicString(Value));
1949 break;
1950 case DT_AUXILIARY:
1951 printLibrary(OS, "Auxiliary library", getDynamicString(Value));
1952 break;
1953 case DT_USED:
1954 printLibrary(OS, "Not needed object", getDynamicString(Value));
1955 break;
1956 case DT_FILTER:
1957 printLibrary(OS, "Filter library", getDynamicString(Value));
1958 break;
1965 }
19591966 case DT_RPATH:
19601967 case DT_RUNPATH:
1961 OS << getDynamicString(Value);
1968 printDynamicString(Value, OS, false);
19621969 break;
19631970 case DT_FLAGS:
19641971 printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS);
20032010 LibsTy Libs;
20042011
20052012 for (const auto &Entry : dynamic_table())
2006 if (Entry.d_tag == ELF::DT_NEEDED)
2007 Libs.push_back(getDynamicString(Entry.d_un.d_val));
2013 if (Entry.d_tag == ELF::DT_NEEDED) {
2014 uint64_t Value = Entry.d_un.d_val;
2015 if (Value < DynamicStringTable.size())
2016 Libs.push_back(StringRef(DynamicStringTable.data() + Value));
2017 else
2018 Libs.push_back("");
2019 }
20082020
20092021 llvm::stable_sort(Libs);
20102022