Index: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h =================================================================== --- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h +++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h @@ -346,6 +346,9 @@ int64_t type1 = sega->segmentType(); int64_t type2 = segb->segmentType(); + if (type1 == type2) + return sega->atomflags() < segb->atomflags(); + // The single PT_PHDR segment is required to precede any loadable // segment. We simply make it always first. if (type1 == llvm::ELF::PT_PHDR) @@ -361,30 +364,30 @@ return false; // We then put PT_LOAD segments before any other segments. - if (type1 == llvm::ELF::PT_LOAD && type2 != llvm::ELF::PT_LOAD) + if (type1 == llvm::ELF::PT_LOAD) return true; - if (type2 == llvm::ELF::PT_LOAD && type1 != llvm::ELF::PT_LOAD) + if (type2 == llvm::ELF::PT_LOAD) return false; - // We put the PT_TLS segment last except for the PT_GNU_RELRO - // segment, because that is where the dynamic linker expects to find - if (type1 == llvm::ELF::PT_TLS && type2 != llvm::ELF::PT_TLS && - type2 != llvm::ELF::PT_GNU_RELRO) + // We put the PT_GNU_RELRO segment last, because that is where the + // dynamic linker expects to find it + if (type1 == llvm::ELF::PT_GNU_RELRO) return false; - if (type2 == llvm::ELF::PT_TLS && type1 != llvm::ELF::PT_TLS && - type1 != llvm::ELF::PT_GNU_RELRO) + if (type2 == llvm::ELF::PT_GNU_RELRO) return true; - // We put the PT_GNU_RELRO segment last, because that is where the - // dynamic linker expects to find it - if (type1 == llvm::ELF::PT_GNU_RELRO && type2 != llvm::ELF::PT_GNU_RELRO) + // We put the PT_TLS segment last except for the PT_GNU_RELRO + // segment, because that is where the dynamic linker expects to find + if (type1 == llvm::ELF::PT_TLS) return false; - if (type2 == llvm::ELF::PT_GNU_RELRO && type1 != llvm::ELF::PT_GNU_RELRO) + if (type2 == llvm::ELF::PT_TLS) return true; - if (type1 == type2) - return sega->atomflags() < segb->atomflags(); - return false; + // Otherwise compare the types to establish an arbitrary ordering. + // FIXME: Should figure out if we should just make all other types compare + // equal, but if so, we should probably do the same for atom flags and change + // users of this to use stable_sort. + return type1 < type2; } template Index: lld/trunk/test/elf/phdr.test =================================================================== --- lld/trunk/test/elf/phdr.test +++ lld/trunk/test/elf/phdr.test @@ -71,18 +71,6 @@ I386-NEXT: Alignment: 16384 I386-NEXT: } I386-NEXT: ProgramHeader { -I386-NEXT: Type: PT_GNU_EH_FRAME (0x6474E550) -I386-NEXT: Offset: 0x1F4 -I386-NEXT: VirtualAddress: 0x1F4 -I386-NEXT: PhysicalAddress: 0x1F4 -I386-NEXT: FileSize: 8 -I386-NEXT: MemSize: 8 -I386-NEXT: Flags [ (0x4) -I386-NEXT: PF_R (0x4) -I386-NEXT: ] -I386-NEXT: Alignment: 4 -I386-NEXT: } -I386-NEXT: ProgramHeader { I386-NEXT: Type: PT_DYNAMIC (0x2) I386-NEXT: Offset: 0x1FC I386-NEXT: VirtualAddress: 0x1FC @@ -94,6 +82,18 @@ I386-NEXT: ] I386-NEXT: Alignment: 4 I386-NEXT: } +I386-NEXT: ProgramHeader { +I386-NEXT: Type: PT_GNU_EH_FRAME (0x6474E550) +I386-NEXT: Offset: 0x1F4 +I386-NEXT: VirtualAddress: 0x1F4 +I386-NEXT: PhysicalAddress: 0x1F4 +I386-NEXT: FileSize: 8 +I386-NEXT: MemSize: 8 +I386-NEXT: Flags [ (0x4) +I386-NEXT: PF_R (0x4) +I386-NEXT: ] +I386-NEXT: Alignment: 4 +I386-NEXT: } X86_64: LOAD off 0x0000000000000000 X86_64: LOAD off 0x0000000000001000 Index: lld/trunk/test/elf/rosegment.test =================================================================== --- lld/trunk/test/elf/rosegment.test +++ lld/trunk/test/elf/rosegment.test @@ -11,8 +11,8 @@ #NORO-SEGMENT: Type: PT_INTERP #NORO-SEGMENT: Type: PT_LOAD #NORO-SEGMENT: Type: PT_LOAD -#NORO-SEGMENT: Type: PT_GNU_EH_FRAME #NORO-SEGMENT: Type: PT_DYNAMIC +#NORO-SEGMENT: Type: PT_GNU_EH_FRAME #RO-SEGMENT: Type: PT_PHDR #RO-SEGMENT: Type: PT_INTERP @@ -22,5 +22,5 @@ #RO-SEGMENT: PF_R (0x4) #RO-SEGMENT: ] #RO-SEGMENT: Type: PT_LOAD -#RO-SEGMENT: Type: PT_GNU_EH_FRAME #RO-SEGMENT: Type: PT_DYNAMIC +#RO-SEGMENT: Type: PT_GNU_EH_FRAME