Index: lld/ELF/Writer.cpp =================================================================== --- lld/ELF/Writer.cpp +++ lld/ELF/Writer.cpp @@ -1596,7 +1596,7 @@ OutputSection *bOut = lb->getParent(); if (aOut != bOut) - return aOut->sectionIndex < bOut->sectionIndex; + return aOut->addr < bOut->addr; return la->outSecOff < lb->outSecOff; } @@ -1666,11 +1666,13 @@ AArch64Err843419Patcher a64p; ARMErr657417Patcher a32p; script->assignAddresses(); - // .ARM.exidx does not require precise addresses, but it does require the - // relative addresses of OutputSections because linker scripts can assign - // Virtual Addresses to OutputSections that are not monotonically increasing. + // .ARM.exidx and SHF_LINK_ORDER do not require precise addresses, but they + // do require the relative addresses of OutputSections because linker scripts + // can assign Virtual Addresses to OutputSections that are not monotonically + // increasing. for (Partition &part : partitions) finalizeSynthetic(part.armExidx); + resolveShfLinkOrder(); // Converts call x@GDPLT to call __tls_get_addr if (config->emachine == EM_HEXAGON) @@ -2104,12 +2106,6 @@ if (!script->hasSectionsCommand && !config->relocatable) fixSectionAlignments(); - // SHFLinkOrder processing must be processed after relative section placements are - // known but before addresses are allocated. - resolveShfLinkOrder(); - if (errorCount()) - return; - // This is used to: // 1) Create "thunks": // Jump instructions in many ISAs have small displacements, and therefore @@ -2132,8 +2128,11 @@ // sometimes using forward symbol declarations. We want to set the correct // values. They also might change after adding the thunks. finalizeAddressDependentContent(); + if (errorCount()) + return; - // finalizeAddressDependentContent may have added local symbols to the static symbol table. + // finalizeAddressDependentContent may have added local symbols to the static + // symbol table. finalizeSynthetic(in.symTab); finalizeSynthetic(in.ppc64LongBranchTarget); Index: lld/test/ELF/linkorder-script.s =================================================================== --- /dev/null +++ lld/test/ELF/linkorder-script.s @@ -0,0 +1,32 @@ +// REQUIRES: x86 +// RUN: llvm-mc --triple=x86_64 -filetype=obj %s -o %t.o +// RUN: echo "SECTIONS { \ +// RUN: . = 0x80000000; \ +// RUN: .linkorder : { *(.linkorder.*) } \ +// RUN: .text : { *(.text) } \ +// RUN: .text.1 0x80000200 : AT(0x1000) { *(.text.1) } \ +// RUN: .text.2 0x80000100 : AT(0x2000) { *(.text.2) } \ +// RUN: } " > %t.script +// RUN: ld.lld --script %t.script %t.o -o %t +// RUN: llvm-readobj -x .linkorder %t | FileCheck %s + +/// When a linker script does not have monotonically increasing addresses +/// the SHF_LINK_ORDER sections should still be in monotonically increasing +/// order. + +// CHECK: Hex dump of section '.linkorder': +// CHECK-NEXT: 0x80000000 02000000 00000000 01000000 00000000 + +.section .text.1, "ax", %progbits +.global _start +_start: +.quad 0 + +.section .text.2, "ax", %progbits +.quad 0 + +.section .linkorder.1, "ao", %progbits, .text.1 +.quad 1 + +.section .linkorder.2, "ao", %progbits, .text.2 +.quad 2