Skip to content

Commit 1007cb7

Browse files
MaskRaytstellar
authored andcommitted
[llvm-objdump] --private-headers: change errors to warnings for dynamic section dumping
Fix llvm#54456: `objcopy --only-keep-debug` produces a linked image with invalid empty dynamic section. llvm-objdump -p currently reports an error which seems excessive. ``` % llvm-readelf -l a.out llvm-readelf: warning: 'a.out': no valid dynamic table was found ... ``` Follow the spirit of llvm-readelf -l (D64472) and report a warning instead. This allows later files to be dumped despite warnings for an input file, and improves objdump compatibility in that the exit code is now 0 instead of 1. ``` % llvm-objdump -p a.out # new behavior ... Program Header: llvm-objdump: warning: 'a.out': invalid empty dynamic section % objdump -p a.out ... Dynamic Section: ``` Reviewed By: jhenderson, raj.khem Differential Revision: https://reviews.llvm.org/D122505 (cherry picked from commit 11a8fc6)
1 parent c9ec490 commit 1007cb7

File tree

5 files changed

+54
-12
lines changed

5 files changed

+54
-12
lines changed

llvm/lib/Object/ELF.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,11 +561,9 @@ Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {
561561
}
562562

563563
if (Dyn.empty())
564-
// TODO: this error is untested.
565564
return createError("invalid empty dynamic section");
566565

567566
if (Dyn.back().d_tag != ELF::DT_NULL)
568-
// TODO: this error is untested.
569567
return createError("dynamic sections must be DT_NULL terminated");
570568

571569
return Dyn;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## An empty dynamic section is invalid. Test we report a warning instead of an
2+
## error, so that dumping can continue with other objects.
3+
# RUN: yaml2obj %s --docnum=1 -o %t.empty
4+
# RUN: llvm-objdump -p %t.empty 2>&1 | FileCheck %s -DFILE=%t.empty --check-prefix=EMPTY
5+
6+
# EMPTY: Program Header:
7+
# EMPTY-NEXT: warning: '[[FILE]]': invalid empty dynamic section
8+
# EMPTY-EMPTY:
9+
10+
--- !ELF
11+
FileHeader:
12+
Class: ELFCLASS64
13+
Data: ELFDATA2LSB
14+
Type: ET_EXEC
15+
Machine: EM_X86_64
16+
Sections:
17+
- Name: .dynamic
18+
Type: SHT_DYNAMIC
19+
20+
# RUN: yaml2obj %s --docnum=2 -o %t.nonull
21+
# RUN: llvm-objdump -p %t.nonull 2>&1 | FileCheck %s -DFILE=%t.nonull --check-prefix=NONULL
22+
23+
# NONULL: Program Header:
24+
# NONULL-NEXT: warning: '[[FILE]]': dynamic sections must be DT_NULL terminated
25+
# NONULL-EMPTY:
26+
27+
--- !ELF
28+
FileHeader:
29+
Class: ELFCLASS64
30+
Data: ELFDATA2LSB
31+
Type: ET_EXEC
32+
Machine: EM_X86_64
33+
Sections:
34+
- Name: .dynamic
35+
Type: SHT_DYNAMIC
36+
Entries:
37+
- Tag: DT_SONAME
38+
Value: 1

llvm/test/tools/llvm-objdump/ELF/invalid-phdr.test

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
## Test how we handle the case when the e_phoff field is invalid.
22
# RUN: yaml2obj %s -o %t
3-
# RUN: not llvm-objdump --private-headers %t 2>&1 | \
3+
# RUN: llvm-objdump --private-headers %t 2>&1 | \
44
# RUN: FileCheck -DFILE=%t %s --check-prefix=INVALID-PHOFF
55

66
# INVALID-PHOFF: Program Header:
77
# INVALID-PHOFF-NEXT: warning: '[[FILE]]': unable to read program headers: program headers are longer than binary of size 280: e_phoff = 0xffffff, e_phnum = 0, e_phentsize = 0
8-
# INVALID-PHOFF-NEXT: error: '[[FILE]]': program headers are longer than binary of size 280: e_phoff = 0xffffff, e_phnum = 0, e_phentsize = 0
8+
# INVALID-PHOFF-NEXT: warning: '[[FILE]]': program headers are longer than binary of size 280: e_phoff = 0xffffff, e_phnum = 0, e_phentsize = 0
9+
# INVALID-PHOFF-EMPTY:
910

1011
--- !ELF
1112
FileHeader:

llvm/test/tools/llvm-objdump/ELF/program-headers.test

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -278,12 +278,13 @@ ProgramHeaders:
278278
## Check we report an error / warning when we are unable to read program headers.
279279
## Case A: the e_phentsize field is invalid.
280280
# RUN: yaml2obj --docnum=2 -DPHENTSIZE=1 %s -o %t.phdr.err
281-
# RUN: not llvm-objdump --private-headers %t.phdr.err 2>&1 | \
281+
# RUN: llvm-objdump --private-headers %t.phdr.err 2>&1 | \
282282
# RUN: FileCheck %s -DFILE=%t.phdr.err --check-prefix=PHENTSIZE
283283

284284
# PHENTSIZE: Program Header:
285285
# PHENTSIZE-NEXT: warning: '[[FILE]]': unable to read program headers: invalid e_phentsize: 1
286-
# PHENTSIZE-NEXT: error: '[[FILE]]': invalid e_phentsize: 1
286+
# PHENTSIZE-NEXT: warning: '[[FILE]]': invalid e_phentsize: 1
287+
# PHENTSIZE-EMPTY:
287288

288289
--- !ELF
289290
FileHeader:
@@ -309,16 +310,16 @@ ProgramHeaders:
309310

310311
## Check we report a warning / error when e_phoff goes 1 byte past the end of the file.
311312
# RUN: yaml2obj --docnum=2 -DPHOFF=0x161 %s -o %t.phdr.err2
312-
# RUN: not llvm-objdump --private-headers %t.phdr.err2 2>&1 | \
313+
# RUN: llvm-objdump --private-headers %t.phdr.err2 2>&1 | \
313314
# RUN: FileCheck %s -DFILE=%t.phdr.err2 --check-prefix=PHOFF -DOFF=0x161
314315

315316
# PHOFF: Program Header:
316317
# PHOFF-NEXT: warning: '[[FILE]]': unable to read program headers: program headers are longer than binary of size 408: e_phoff = [[OFF]], e_phnum = 1, e_phentsize = 56
317-
# PHOFF-NEXT: error: '[[FILE]]': program headers are longer than binary of size 408: e_phoff = [[OFF]], e_phnum = 1, e_phentsize = 56
318-
318+
# PHOFF-NEXT: warning: '[[FILE]]': program headers are longer than binary of size 408: e_phoff = [[OFF]], e_phnum = 1, e_phentsize = 56
319+
# PHOFF-EMPTY:
319320

320321
## Check we report a warning / error when the value of e_phoff is so large that
321322
## e_phoff + e_phnum * e_phentsize > UINT64_MAX.
322323
# RUN: yaml2obj --docnum=2 -DPHOFF=0xffffffffffffffff %s -o %t.phdr.err3
323-
# RUN: not llvm-objdump --private-headers %t.phdr.err3 2>&1 | \
324+
# RUN: llvm-objdump --private-headers %t.phdr.err3 2>&1 | \
324325
# RUN: FileCheck %s -DFILE=%t.phdr.err3 --check-prefix=PHOFF -DOFF=0xffffffffffffffff

llvm/tools/llvm-objdump/ELFDump.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,12 @@ uint64_t objdump::getELFSectionLMA(const object::ELFSectionRef &Sec) {
171171

172172
template <class ELFT>
173173
static void printDynamicSection(const ELFFile<ELFT> &Elf, StringRef Filename) {
174-
ArrayRef<typename ELFT::Dyn> DynamicEntries =
175-
unwrapOrError(Elf.dynamicEntries(), Filename);
174+
auto DynamicEntriesOrErr = Elf.dynamicEntries();
175+
if (!DynamicEntriesOrErr) {
176+
reportWarning(toString(DynamicEntriesOrErr.takeError()), Filename);
177+
return;
178+
}
179+
ArrayRef<typename ELFT::Dyn> DynamicEntries = *DynamicEntriesOrErr;
176180

177181
// Find the maximum tag name length to format the value column properly.
178182
size_t MaxLen = 0;

0 commit comments

Comments
 (0)