diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -753,6 +753,11 @@ for (auto &YamlPhdr : Doc.ProgramHeaders) { Elf_Phdr &PHeader = PHeaders[PhdrIdx++]; std::vector Fragments = getPhdrFragments(YamlPhdr, SHeaders); + if (!llvm::is_sorted(Fragments, [](const Fragment &A, const Fragment &B) { + return A.Offset < B.Offset; + })) + reportError("sections in the program header with index " + + Twine(PhdrIdx) + " are not sorted by their file offset"); if (YamlPhdr.Offset) { PHeader.p_offset = *YamlPhdr.Offset; diff --git a/llvm/test/tools/llvm-gsymutil/X86/elf-dwarf.yaml b/llvm/test/tools/llvm-gsymutil/X86/elf-dwarf.yaml --- a/llvm/test/tools/llvm-gsymutil/X86/elf-dwarf.yaml +++ b/llvm/test/tools/llvm-gsymutil/X86/elf-dwarf.yaml @@ -395,8 +395,6 @@ - Section: .note.ABI-tag - Section: .note.gnu.build-id - Section: .gnu.hash - - Section: .dynsym - - Section: .dynstr - Section: .gnu.version - Section: .gnu.version_r - Section: .rela.dyn @@ -409,6 +407,8 @@ - Section: .rodata - Section: .eh_frame_hdr - Section: .eh_frame + - Section: .dynsym + - Section: .dynstr Symbols: - Name: .interp Type: STT_SECTION diff --git a/llvm/test/tools/llvm-readobj/ELF/demangle.test b/llvm/test/tools/llvm-readobj/ELF/demangle.test --- a/llvm/test/tools/llvm-readobj/ELF/demangle.test +++ b/llvm/test/tools/llvm-readobj/ELF/demangle.test @@ -213,8 +213,8 @@ Flags: [ PF_R, PF_X ] VAddr: 0x0 Sections: - - Section: .dynsym - Section: .dynstr + - Section: .dynsym - Section: .rela.dyn - Section: .dynamic - Section: .text.foo diff --git a/llvm/test/tools/llvm-readobj/ELF/hash-symbols.test b/llvm/test/tools/llvm-readobj/ELF/hash-symbols.test --- a/llvm/test/tools/llvm-readobj/ELF/hash-symbols.test +++ b/llvm/test/tools/llvm-readobj/ELF/hash-symbols.test @@ -298,8 +298,8 @@ Flags: [ PF_R, PF_X ] VAddr: 0x0 Sections: - - Section: .dynsym - Section: .dynstr + - Section: .dynsym - Section: .dynamic - Section: .text.foo - Type: PT_DYNAMIC diff --git a/llvm/test/tools/llvm-readobj/ELF/reloc-negative-addend-no-sym.test b/llvm/test/tools/llvm-readobj/ELF/reloc-negative-addend-no-sym.test --- a/llvm/test/tools/llvm-readobj/ELF/reloc-negative-addend-no-sym.test +++ b/llvm/test/tools/llvm-readobj/ELF/reloc-negative-addend-no-sym.test @@ -65,8 +65,8 @@ - Type: PT_LOAD VAddr: 0x1000 Sections: - - Section: .rela.dyn - Section: .dynamic + - Section: .rela.dyn - Type: PT_DYNAMIC VAddr: 0x1000 Sections: diff --git a/llvm/test/tools/llvm-readobj/ELF/reloc-zero-name-or-value.test b/llvm/test/tools/llvm-readobj/ELF/reloc-zero-name-or-value.test --- a/llvm/test/tools/llvm-readobj/ELF/reloc-zero-name-or-value.test +++ b/llvm/test/tools/llvm-readobj/ELF/reloc-zero-name-or-value.test @@ -101,8 +101,8 @@ - Type: PT_LOAD VAddr: 0x1000 Sections: - - Section: .rela.dyn - Section: .dynamic + - Section: .rela.dyn - Type: PT_DYNAMIC VAddr: 0x1000 Sections: diff --git a/llvm/test/tools/obj2yaml/program-headers.yaml b/llvm/test/tools/obj2yaml/program-headers.yaml --- a/llvm/test/tools/obj2yaml/program-headers.yaml +++ b/llvm/test/tools/obj2yaml/program-headers.yaml @@ -517,3 +517,60 @@ ## Use an arbitrary size that is different to the size of ## the previous section. Size: 0x20 + +## Check that we require sections in a program header +## declaration to be sorted by their offsets. +# RUN: not yaml2obj --docnum=6 %s -o %t6 2>&1 | \ +# RUN: FileCheck %s --check-prefix=UNSORTED --implicit-check-not="error:" + +# UNSORTED: error: sections in the program header with index 1 are not sorted by their file offset +# UNSORTED-NEXT: error: sections in the program header with index 3 are not sorted by their file offset + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +ProgramHeaders: +## Case 1: the .bar section is placed after the .foo section in the file. +## Check we report an error about the violation of the order. + - Type: PT_LOAD + Flags: [ PF_R ] + Sections: + - Section: .bar + - Section: .foo + VAddr: 0x1000 +## There is nothing wrong with this segment. We have it to show that +## we report correct program header indices in error messages. + - Type: PT_LOAD + Flags: [ PF_R ] + Sections: + - Section: .foo + - Section: .bar + VAddr: 0x1000 +## Case 2: the .bar section is placed before the .zed section in the file, +## but the sh_offset of .zed is less than the sh_offset of +## the .bar section because of the "ShOffset" property. +## Document we report an error for such a case. + - Type: PT_LOAD + Flags: [ PF_R ] + Sections: + - Section: .bar + - Section: .zed + VAddr: 0x1001 +Sections: + - Name: .foo + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Size: 0x1 + Address: 0x1000 + - Name: .bar + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Size: 0x1 + - Name: .zed + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Size: 0x1 + ShOffset: 0x0