Skip to content

Commit 0e8b61f

Browse files
authored
llvm-objdump/ELF: fix crash when reading dyn str table (#87519)
When reading the dynamic string table, llvm-objdump used to crash if the ELF was malformed, due to an erroneous consumption of error status. Instead, propogate the error status to the caller, fixing the crash, and printing a warning.
1 parent d288444 commit 0e8b61f

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

llvm/test/tools/llvm-objdump/ELF/dynamic-malformed.test

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ FileHeader:
1212
Class: ELFCLASS64
1313
Data: ELFDATA2LSB
1414
Type: ET_EXEC
15-
Machine: EM_X86_64
1615
Sections:
1716
- Name: .dynamic
1817
Type: SHT_DYNAMIC
@@ -29,10 +28,35 @@ FileHeader:
2928
Class: ELFCLASS64
3029
Data: ELFDATA2LSB
3130
Type: ET_EXEC
32-
Machine: EM_X86_64
3331
Sections:
3432
- Name: .dynamic
3533
Type: SHT_DYNAMIC
3634
Entries:
3735
- Tag: DT_SONAME
3836
Value: 1
37+
38+
# RUN: yaml2obj %s --docnum=3 -o %t.invalidaddr
39+
# RUN: llvm-objdump -p %t.invalidaddr 2>&1 | \
40+
# RUN: FileCheck %s -DFILE=%t.invalidaddr --implicit-check-not=warning: --check-prefix=ADDR
41+
42+
# ADDR: Dynamic Section:
43+
# ADDR-NEXT: warning: '[[FILE]]': virtual address is not in any segment: 0x474
44+
# ADDR-NEXT: NEEDED 0xffffffffbe5a0b5f
45+
# ADDR-NEXT: STRTAB 0x0000000000000474
46+
47+
---
48+
!ELF
49+
FileHeader:
50+
Class: ELFCLASS64
51+
Data: ELFDATA2LSB
52+
Type: ET_DYN
53+
Sections:
54+
- Name: .dynamic
55+
Type: SHT_DYNAMIC
56+
Entries:
57+
- Tag: DT_NEEDED
58+
Value: 0xFFFFFFFFBE5A0B5F
59+
- Tag: DT_STRTAB
60+
Value: 0x474
61+
- Tag: DT_NULL
62+
Value: 0x0

llvm/tools/llvm-objdump/ELFDump.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static Expected<StringRef> getDynamicStrTab(const ELFFile<ELFT> &Elf) {
6868
if (Dyn.d_tag == ELF::DT_STRTAB) {
6969
auto MappedAddrOrError = Elf.toMappedAddr(Dyn.getPtr());
7070
if (!MappedAddrOrError)
71-
consumeError(MappedAddrOrError.takeError());
71+
return MappedAddrOrError.takeError();
7272
return StringRef(reinterpret_cast<const char *>(*MappedAddrOrError));
7373
}
7474
}
@@ -223,7 +223,6 @@ template <class ELFT> void ELFDumper<ELFT>::printDynamicSection() {
223223
continue;
224224

225225
std::string Str = Elf.getDynamicTagAsString(Dyn.d_tag);
226-
outs() << format(TagFmt.c_str(), Str.c_str());
227226

228227
const char *Fmt =
229228
ELFT::Is64Bits ? "0x%016" PRIx64 "\n" : "0x%08" PRIx64 "\n";
@@ -232,14 +231,16 @@ template <class ELFT> void ELFDumper<ELFT>::printDynamicSection() {
232231
Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER) {
233232
Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf);
234233
if (StrTabOrErr) {
235-
const char *Data = StrTabOrErr.get().data();
236-
outs() << (Data + Dyn.d_un.d_val) << "\n";
234+
const char *Data = StrTabOrErr->data();
235+
outs() << format(TagFmt.c_str(), Str.c_str()) << Data + Dyn.getVal()
236+
<< "\n";
237237
continue;
238238
}
239239
reportWarning(toString(StrTabOrErr.takeError()), Obj.getFileName());
240240
consumeError(StrTabOrErr.takeError());
241241
}
242-
outs() << format(Fmt, (uint64_t)Dyn.d_un.d_val);
242+
outs() << format(TagFmt.c_str(), Str.c_str())
243+
<< format(Fmt, (uint64_t)Dyn.getVal());
243244
}
244245
}
245246

0 commit comments

Comments
 (0)