Skip to content

Commit 3834385

Browse files
committed
[ELF] Move SHF_LINK_ORDER till OutputSection addresses are known
Sections with the SHF_LINK_ORDER flag must be ordered in the same relative order as the Sections they have a link to. When using a linker script an arbitrary expression may be used for the virtual address of the OutputSection. In some cases the virtual address does not monotonically increase as the OutputSection index increases, so if we base the ordering of the SHF_LINK_ORDER sections on the index then we can get the order wrong. We fix this by moving SHF_LINK_ORDER resolution till after we have created OutputSection virtual addresses. Differential Revision: https://reviews.llvm.org/D79286
1 parent ff4a3ee commit 3834385

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

lld/ELF/Writer.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,7 +1596,7 @@ static bool compareByFilePosition(InputSection *a, InputSection *b) {
15961596
OutputSection *bOut = lb->getParent();
15971597

15981598
if (aOut != bOut)
1599-
return aOut->sectionIndex < bOut->sectionIndex;
1599+
return aOut->addr < bOut->addr;
16001600
return la->outSecOff < lb->outSecOff;
16011601
}
16021602

@@ -1666,11 +1666,13 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
16661666
AArch64Err843419Patcher a64p;
16671667
ARMErr657417Patcher a32p;
16681668
script->assignAddresses();
1669-
// .ARM.exidx does not require precise addresses, but it does require the
1670-
// relative addresses of OutputSections because linker scripts can assign
1671-
// Virtual Addresses to OutputSections that are not monotonically increasing.
1669+
// .ARM.exidx and SHF_LINK_ORDER do not require precise addresses, but they
1670+
// do require the relative addresses of OutputSections because linker scripts
1671+
// can assign Virtual Addresses to OutputSections that are not monotonically
1672+
// increasing.
16721673
for (Partition &part : partitions)
16731674
finalizeSynthetic(part.armExidx);
1675+
resolveShfLinkOrder();
16741676

16751677
// Converts call x@GDPLT to call __tls_get_addr
16761678
if (config->emachine == EM_HEXAGON)
@@ -2104,12 +2106,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
21042106
if (!script->hasSectionsCommand && !config->relocatable)
21052107
fixSectionAlignments();
21062108

2107-
// SHFLinkOrder processing must be processed after relative section placements are
2108-
// known but before addresses are allocated.
2109-
resolveShfLinkOrder();
2110-
if (errorCount())
2111-
return;
2112-
21132109
// This is used to:
21142110
// 1) Create "thunks":
21152111
// Jump instructions in many ISAs have small displacements, and therefore
@@ -2132,6 +2128,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
21322128
// sometimes using forward symbol declarations. We want to set the correct
21332129
// values. They also might change after adding the thunks.
21342130
finalizeAddressDependentContent();
2131+
if (errorCount())
2132+
return;
21352133

21362134
// finalizeAddressDependentContent may have added local symbols to the static symbol table.
21372135
finalizeSynthetic(in.symTab);

lld/test/ELF/linkorder-script.s

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// REQUIRES: x86
2+
// RUN: llvm-mc --triple=x86_64 -filetype=obj %s -o %t.o
3+
// RUN: echo "SECTIONS { \
4+
// RUN: . = 0x80000000; \
5+
// RUN: .linkorder : { *(.linkorder.*) } \
6+
// RUN: .text : { *(.text) } \
7+
// RUN: .text.1 0x80000200 : AT(0x1000) { *(.text.1) } \
8+
// RUN: .text.2 0x80000100 : AT(0x2000) { *(.text.2) } \
9+
// RUN: } " > %t.script
10+
// RUN: ld.lld --script %t.script %t.o -o %t
11+
// RUN: llvm-readobj -x .linkorder %t | FileCheck %s
12+
13+
/// When a linker script does not have monotonically increasing addresses
14+
/// the SHF_LINK_ORDER sections should still be in monotonically increasing
15+
/// order.
16+
17+
// CHECK: Hex dump of section '.linkorder':
18+
// CHECK-NEXT: 0x80000000 0201
19+
20+
.section .text.1, "ax", %progbits
21+
.global _start
22+
_start:
23+
nop
24+
25+
.section .text.2, "ax", %progbits
26+
.byte 0
27+
28+
.section .linkorder.1, "ao", %progbits, .text.1
29+
.byte 1
30+
31+
.section .linkorder.2, "ao", %progbits, .text.2
32+
.byte 2

0 commit comments

Comments
 (0)