Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -150,6 +150,19 @@ std::vector &V = InputSections; V.erase(std::remove(V.begin(), V.end(), nullptr), V.end()); + + // For futher --emit-reloc handling code we need target output section to be + // created before we create relocation output section, so we want target to be + // listed first. We do not support objects that break this order, but code + // above do that, because InX::EhFrame synthetic section is placed after + // all other regular sections. Here we want to sort sections list to restore + // this general ordering rule. We do not need or want to move synthetic + // sections because them are special. + if (Config->EmitRelocs) + std::stable_partition(V.begin(), V.end(), [](InputSectionBase *IS) { + return (IS->Type != SHT_REL && IS->Type != SHT_RELA) || + isa(IS); + }); } static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec, @@ -1378,11 +1391,9 @@ // All input synthetic sections that can be empty are placed after // all regular ones. We iterate over them all and exit at first // non-synthetic. - for (InputSectionBase *S : llvm::reverse(InputSections)) { + for (InputSectionBase *S : InputSections) { SyntheticSection *SS = dyn_cast(S); - if (!SS) - return; - OutputSection *OS = SS->getParent(); + OutputSection *OS = SS ? SS->getParent() : nullptr; if (!OS || !SS->empty()) continue; Index: test/ELF/emit-relocs-eh-frame.s =================================================================== --- test/ELF/emit-relocs-eh-frame.s +++ test/ELF/emit-relocs-eh-frame.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: ld.lld --emit-relocs %t1.o -o %t +# RUN: llvm-readobj -r %t | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section {{.*}} .rela.eh_frame { +# CHECK-NEXT: 0x{{.*}} R_X86_64_PC32 .text 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.text +.globl foo +foo: + .cfi_startproc + .Lfunc_end0: + .size foo, .Lfunc_end0-foo + .cfi_endproc Index: test/ELF/emit-relocs-shared.s =================================================================== --- test/ELF/emit-relocs-shared.s +++ test/ELF/emit-relocs-shared.s @@ -7,10 +7,10 @@ .quad foo # CHECK: Relocations [ -# CHECK-NEXT: Section (4) .rela.dyn { +# CHECK-NEXT: Section {{.*}} .rela.dyn { # CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0 # CHECK-NEXT: } -# CHECK-NEXT: Section (8) .rela.data { +# CHECK-NEXT: Section {{.*}} .rela.data { # CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0 # CHECK-NEXT: } # CHECK-NEXT: ] Index: test/ELF/emit-relocs.s =================================================================== --- test/ELF/emit-relocs.s +++ test/ELF/emit-relocs.s @@ -12,8 +12,8 @@ # RUN: llvm-readobj -t -r -s %t2 | FileCheck %s # CHECK: Section { -# CHECK: Index: 2 -# CHECK-NEXT: Name: .rela.text +# CHECK: Index: +# CHECK: Name: .rela.text # CHECK-NEXT: Type: SHT_RELA # CHECK-NEXT: Flags [ # CHECK-NEXT: SHF_INFO_LINK Index: test/ELF/invalid/emit-relocs-reordered.test =================================================================== --- test/ELF/invalid/emit-relocs-reordered.test +++ test/ELF/invalid/emit-relocs-reordered.test @@ -0,0 +1,30 @@ +# REQUIRES: x86 + +# RUN: yaml2obj %s -o %t.o +# RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s +# CHECK: unsupported relocation reference + +## YAML below lists .rela.text before .text, we do not support it. + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_FREEBSD + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Type: SHT_REL + Name: .rela.text + Link: .symtab + Info: .text + AddressAlign: 0x04 + Relocations: + - Offset: 0 + Symbol: .text + Type: R_X86_64_NONE + - Type: SHT_PROGBITS + Name: .text + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x04 + Content: "FFFFFFFFFFFFFFFF"