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(&Phdr)); + if (!llvm::is_sorted(LoadSegments, [](const Elf_Phdr_Impl *A, + const Elf_Phdr_Impl *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 *Phdr) { 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