diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index a5d08f4979dab..b55c19933a13b 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -1021,10 +1021,6 @@ void LinkerScript::addOrphanSections() { } }; - // For further --emit-reloc handling code we need target output section - // to be created before we create relocation output section, so we want - // to create target sections first. We do not want priority handling - // for synthetic sections because them are special. size_t n = 0; for (InputSectionBase *isec : ctx.inputSections) { // Process InputSection and MergeInputSection. @@ -1037,10 +1033,18 @@ void LinkerScript::addOrphanSections() { if (ctx.arg.relocatable && (isec->flags & SHF_LINK_ORDER)) continue; - if (auto *sec = dyn_cast(isec)) - if (InputSectionBase *rel = sec->getRelocatedSection()) - if (auto *relIS = dyn_cast_or_null(rel->parent)) - add(relIS); + if (auto *sec = dyn_cast(isec)) { + if (InputSectionBase *relocated = sec->getRelocatedSection()) { + // For --emit-relocs and -r, ensure the output section for .text.foo + // is created before the output section for .rela.text.foo. + add(relocated); + // EhInputSection sections are not added to ctx.inputSections. If we see + // .rela.eh_frame, ensure the output section for the synthetic + // EhFrameSection is created first. + if (auto *p = dyn_cast_or_null(relocated->parent)) + add(p); + } + } add(isec); if (ctx.arg.relocatable) for (InputSectionBase *depSec : isec->dependentSections) diff --git a/lld/test/ELF/linkerscript/orphan-relocation.s b/lld/test/ELF/linkerscript/orphan-relocation.s new file mode 100644 index 0000000000000..adf5cac6c3e82 --- /dev/null +++ b/lld/test/ELF/linkerscript/orphan-relocation.s @@ -0,0 +1,31 @@ +# REQUIRES: x86 +## Test that orphan section placement can handle a relocatable link where +## the relocation section is seen before the relocated section. + +# RUN: rm -rf %t && split-file %s %t && cd %t + +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o +## In a.ro, .rela.text precedes its relocated section. +# RUN: ld.lld -r a.o -T 1.lds -o a.ro +# RUN: llvm-readelf -S a.ro | FileCheck %s +# CHECK: .rela.text RELA +# CHECK-NEXT: .text PROGBITS + +# RUN: llvm-objcopy --rename-section .text=.com.text --rename-section .rela.text=.rela.com.text a.ro a1.o + +## Regression test for #156354 , where we added an orphan RELA section before its relocated section. +# RUN: ld.lld -r a1.o -o a1.ro +# RUN: llvm-readelf -S a1.ro | FileCheck %s --check-prefix=CHECK1 +# CHECK1: .com.text PROGBITS +# CHECK1-NEXT: .rela.com.text RELA + +#--- a.s +.globl foo +foo: + call foo + +#--- 1.lds +SECTIONS { + .rela.text 0 : { *(.rela.text) } + .text 0 : { *(.text) } +}