[PATCH] D92641: [llvm-readelf/obj] - Handle out-of-order PT_LOADs better.
George Rimar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 4 01:02:24 PST 2020
grimar created this revision.
grimar added reviewers: jhenderson, MaskRay.
Herald added subscribers: rupprecht, hiraditya, emaste.
Herald added a reviewer: espindola.
grimar requested review of this revision.
Herald added a project: LLVM.
This is https://bugs.llvm.org/show_bug.cgi?id=45698.
Specification says that
"Loadable segment entries in the program header table appear
in ascending order, sorted on the p_vaddr member."
Out `toMappedAddr()` relies on this condition. This patch
adds a warning when the sorting order of loadable segments is wrong.
https://reviews.llvm.org/D92641
Files:
llvm/lib/Object/ELF.cpp
llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test
Index: llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test
===================================================================
--- llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test
+++ llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test
@@ -414,3 +414,57 @@
# PAST-THE-EOF-NEXT: {{[(]?}}RPATH{{[)]?}} Library rpath: [<?>]
# PAST-THE-EOF-NEXT: {{[(]?}}RUNPATH{{[)]?}} Library runpath: [<?>]
# PAST-THE-EOF-NEXT: {{[(]?}}NULL{{[)]?}} 0x0
+
+## Check that we report a warning when we try to map an address, but loadable
+## segments appear unsorted on the p_vaddr member.
+
+# RUN: yaml2obj %s --docnum=7 -o %t10
+# RUN: llvm-readobj --dynamic-table %t10 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t10 --implicit-check-not=warning: --check-prefixes=OUT-OF-ORDER,OUT-OF-ORDER-LLVM
+# RUN: llvm-readelf --dynamic-table %t10 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t10 --implicit-check-not=warning: --check-prefixes=OUT-OF-ORDER,OUT-OF-ORDER-GNU
+
+# OUT-OF-ORDER: warning: '[[FILE]]': unable to parse DT_STRTAB: unable to map address 0x1000 to a segment: loadable segments must be in ascending address order
+
+# OUT-OF-ORDER-LLVM: DynamicSection [ (2 entries)
+# OUT-OF-ORDER-LLVM-NEXT: Tag Type Name/Value
+# OUT-OF-ORDER-LLVM-NEXT: 0x0000000000000005 STRTAB 0x1000
+# OUT-OF-ORDER-LLVM-NEXT: 0x0000000000000000 NULL 0x0
+# OUT-OF-ORDER-LLVM-NEXT: ]
+
+# OUT-OF-ORDER-GNU: Dynamic section at offset 0xe9 contains 2 entries:
+# OUT-OF-ORDER-GNU-NEXT: Tag Type Name/Value
+# OUT-OF-ORDER-GNU-NEXT: 0x0000000000000005 (STRTAB) 0x1000
+# OUT-OF-ORDER-GNU-NEXT: 0x0000000000000000 (NULL) 0x0
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+Sections:
+ - Name: .dynstr
+ Type: SHT_STRTAB
+ Address: 0x1000
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Address: 0x1010
+ Entries:
+ - Tag: DT_STRTAB
+ Value: 0x1000
+ - Tag: DT_NULL
+ Value: 0
+Symbols: []
+ProgramHeaders:
+ - Type: PT_LOAD
+ VAddr: 0x1010
+ FirstSec: .dynamic
+ LastSec: .dynamic
+ - Type: PT_LOAD
+ VAddr: 0x1000
+ FirstSec: .dynstr
+ LastSec: .dynstr
+ - Type: PT_DYNAMIC
+ VAddr: 0x1010
+ FirstSec: .dynamic
+ LastSec: .dynamic
Index: llvm/lib/Object/ELF.cpp
===================================================================
--- llvm/lib/Object/ELF.cpp
+++ llvm/lib/Object/ELF.cpp
@@ -577,6 +577,14 @@
if (Phdr.p_type == ELF::PT_LOAD)
LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr));
+ if (!llvm::is_sorted(LoadSegments, [](const Elf_Phdr_Impl<ELFT> *A,
+ const Elf_Phdr_Impl<ELFT> *B) {
+ return A->p_vaddr < B->p_vaddr;
+ }))
+ return createError(
+ "unable to map address 0x" + Twine::utohexstr(VAddr) +
+ " to a segment: loadable segments must be in ascending address order");
+
const Elf_Phdr *const *I =
std::upper_bound(LoadSegments.begin(), LoadSegments.end(), VAddr,
[](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D92641.309478.patch
Type: text/x-patch
Size: 3159 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201204/57ed7d1b/attachment.bin>
More information about the llvm-commits
mailing list