[llvm-branch-commits] [llvm] 1007cb7 - [llvm-objdump] --private-headers: change errors to warnings for dynamic section dumping
Tom Stellard via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Apr 5 22:24:13 PDT 2022
Author: Fangrui Song
Date: 2022-04-05T22:23:09-07:00
New Revision: 1007cb795a3c82eab231b58569ea06a2b613636a
URL: https://github.com/llvm/llvm-project/commit/1007cb795a3c82eab231b58569ea06a2b613636a
DIFF: https://github.com/llvm/llvm-project/commit/1007cb795a3c82eab231b58569ea06a2b613636a.diff
LOG: [llvm-objdump] --private-headers: change errors to warnings for dynamic section dumping
Fix #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 11a8fc685692f56b011f851d974f0cac534f2cb8)
Added:
llvm/test/tools/llvm-objdump/ELF/dynamic-malformed.test
Modified:
llvm/lib/Object/ELF.cpp
llvm/test/tools/llvm-objdump/ELF/invalid-phdr.test
llvm/test/tools/llvm-objdump/ELF/program-headers.test
llvm/tools/llvm-objdump/ELFDump.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index 6e56da1a31f3e..56a4262117551 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -561,11 +561,9 @@ Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {
}
if (Dyn.empty())
- // TODO: this error is untested.
return createError("invalid empty dynamic section");
if (Dyn.back().d_tag != ELF::DT_NULL)
- // TODO: this error is untested.
return createError("dynamic sections must be DT_NULL terminated");
return Dyn;
diff --git a/llvm/test/tools/llvm-objdump/ELF/dynamic-malformed.test b/llvm/test/tools/llvm-objdump/ELF/dynamic-malformed.test
new file mode 100644
index 0000000000000..b10e4f5e44f18
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/dynamic-malformed.test
@@ -0,0 +1,38 @@
+## An empty dynamic section is invalid. Test we report a warning instead of an
+## error, so that dumping can continue with other objects.
+# RUN: yaml2obj %s --docnum=1 -o %t.empty
+# RUN: llvm-objdump -p %t.empty 2>&1 | FileCheck %s -DFILE=%t.empty --check-prefix=EMPTY
+
+# EMPTY: Program Header:
+# EMPTY-NEXT: warning: '[[FILE]]': invalid empty dynamic section
+# EMPTY-EMPTY:
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+
+# RUN: yaml2obj %s --docnum=2 -o %t.nonull
+# RUN: llvm-objdump -p %t.nonull 2>&1 | FileCheck %s -DFILE=%t.nonull --check-prefix=NONULL
+
+# NONULL: Program Header:
+# NONULL-NEXT: warning: '[[FILE]]': dynamic sections must be DT_NULL terminated
+# NONULL-EMPTY:
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Entries:
+ - Tag: DT_SONAME
+ Value: 1
diff --git a/llvm/test/tools/llvm-objdump/ELF/invalid-phdr.test b/llvm/test/tools/llvm-objdump/ELF/invalid-phdr.test
index 94de7eacc3eca..188c8eeeff491 100644
--- a/llvm/test/tools/llvm-objdump/ELF/invalid-phdr.test
+++ b/llvm/test/tools/llvm-objdump/ELF/invalid-phdr.test
@@ -1,11 +1,12 @@
## Test how we handle the case when the e_phoff field is invalid.
# RUN: yaml2obj %s -o %t
-# RUN: not llvm-objdump --private-headers %t 2>&1 | \
+# RUN: llvm-objdump --private-headers %t 2>&1 | \
# RUN: FileCheck -DFILE=%t %s --check-prefix=INVALID-PHOFF
# INVALID-PHOFF: Program Header:
# 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
-# INVALID-PHOFF-NEXT: error: '[[FILE]]': program headers are longer than binary of size 280: e_phoff = 0xffffff, e_phnum = 0, e_phentsize = 0
+# INVALID-PHOFF-NEXT: warning: '[[FILE]]': program headers are longer than binary of size 280: e_phoff = 0xffffff, e_phnum = 0, e_phentsize = 0
+# INVALID-PHOFF-EMPTY:
--- !ELF
FileHeader:
diff --git a/llvm/test/tools/llvm-objdump/ELF/program-headers.test b/llvm/test/tools/llvm-objdump/ELF/program-headers.test
index 1e11334d7172f..abd4894c45124 100644
--- a/llvm/test/tools/llvm-objdump/ELF/program-headers.test
+++ b/llvm/test/tools/llvm-objdump/ELF/program-headers.test
@@ -278,12 +278,13 @@ ProgramHeaders:
## Check we report an error / warning when we are unable to read program headers.
## Case A: the e_phentsize field is invalid.
# RUN: yaml2obj --docnum=2 -DPHENTSIZE=1 %s -o %t.phdr.err
-# RUN: not llvm-objdump --private-headers %t.phdr.err 2>&1 | \
+# RUN: llvm-objdump --private-headers %t.phdr.err 2>&1 | \
# RUN: FileCheck %s -DFILE=%t.phdr.err --check-prefix=PHENTSIZE
# PHENTSIZE: Program Header:
# PHENTSIZE-NEXT: warning: '[[FILE]]': unable to read program headers: invalid e_phentsize: 1
-# PHENTSIZE-NEXT: error: '[[FILE]]': invalid e_phentsize: 1
+# PHENTSIZE-NEXT: warning: '[[FILE]]': invalid e_phentsize: 1
+# PHENTSIZE-EMPTY:
--- !ELF
FileHeader:
@@ -309,16 +310,16 @@ ProgramHeaders:
## Check we report a warning / error when e_phoff goes 1 byte past the end of the file.
# RUN: yaml2obj --docnum=2 -DPHOFF=0x161 %s -o %t.phdr.err2
-# RUN: not llvm-objdump --private-headers %t.phdr.err2 2>&1 | \
+# RUN: llvm-objdump --private-headers %t.phdr.err2 2>&1 | \
# RUN: FileCheck %s -DFILE=%t.phdr.err2 --check-prefix=PHOFF -DOFF=0x161
# PHOFF: Program Header:
# 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
-# PHOFF-NEXT: error: '[[FILE]]': program headers are longer than binary of size 408: e_phoff = [[OFF]], e_phnum = 1, e_phentsize = 56
-
+# PHOFF-NEXT: warning: '[[FILE]]': program headers are longer than binary of size 408: e_phoff = [[OFF]], e_phnum = 1, e_phentsize = 56
+# PHOFF-EMPTY:
## Check we report a warning / error when the value of e_phoff is so large that
## e_phoff + e_phnum * e_phentsize > UINT64_MAX.
# RUN: yaml2obj --docnum=2 -DPHOFF=0xffffffffffffffff %s -o %t.phdr.err3
-# RUN: not llvm-objdump --private-headers %t.phdr.err3 2>&1 | \
+# RUN: llvm-objdump --private-headers %t.phdr.err3 2>&1 | \
# RUN: FileCheck %s -DFILE=%t.phdr.err3 --check-prefix=PHOFF -DOFF=0xffffffffffffffff
diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp
index 98e71497d022a..ca73dafe2b8ed 100644
--- a/llvm/tools/llvm-objdump/ELFDump.cpp
+++ b/llvm/tools/llvm-objdump/ELFDump.cpp
@@ -171,8 +171,12 @@ uint64_t objdump::getELFSectionLMA(const object::ELFSectionRef &Sec) {
template <class ELFT>
static void printDynamicSection(const ELFFile<ELFT> &Elf, StringRef Filename) {
- ArrayRef<typename ELFT::Dyn> DynamicEntries =
- unwrapOrError(Elf.dynamicEntries(), Filename);
+ auto DynamicEntriesOrErr = Elf.dynamicEntries();
+ if (!DynamicEntriesOrErr) {
+ reportWarning(toString(DynamicEntriesOrErr.takeError()), Filename);
+ return;
+ }
+ ArrayRef<typename ELFT::Dyn> DynamicEntries = *DynamicEntriesOrErr;
// Find the maximum tag name length to format the value column properly.
size_t MaxLen = 0;
More information about the llvm-branch-commits
mailing list