Skip to content

Commit 1594405

Browse files
authored
[LLD][COFF] Split native and EC .CRT chunks on ARM64X (#127203)
1 parent 0d2722c commit 1594405

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

lld/COFF/Writer.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,12 @@ void OutputSection::addContributingPartialSection(PartialSection *sec) {
403403
contribSections.push_back(sec);
404404
}
405405

406+
void OutputSection::splitECChunks() {
407+
llvm::stable_sort(chunks, [=](const Chunk *a, const Chunk *b) {
408+
return (a->getMachine() != ARM64) < (b->getMachine() != ARM64);
409+
});
410+
}
411+
406412
// Check whether the target address S is in range from a relocation
407413
// of type relType at address P.
408414
bool Writer::isInRange(uint16_t relType, uint64_t s, uint64_t p, int margin,
@@ -1156,6 +1162,11 @@ void Writer::createSections() {
11561162
sec->addContributingPartialSection(pSec);
11571163
}
11581164

1165+
if (ctx.hybridSymtab) {
1166+
if (OutputSection *sec = findSection(".CRT"))
1167+
sec->splitECChunks();
1168+
}
1169+
11591170
// Finally, move some output sections to the end.
11601171
auto sectionOrder = [&](const OutputSection *s) {
11611172
// Move DISCARDABLE (or non-memory-mapped) sections to the end of file

lld/COFF/Writer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ class OutputSection {
5050
void writeHeaderTo(uint8_t *buf, bool isDebug);
5151
void addContributingPartialSection(PartialSection *sec);
5252

53+
// Sort chunks to split native and EC sections on hybrid targets.
54+
void splitECChunks();
55+
5356
// Returns the size of this section in an executable memory image.
5457
// This may be smaller than the raw size (the raw size is multiple
5558
// of disk sector size, so there may be padding at end), or may be

lld/test/COFF/arm64x-crt-sec.s

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// REQUIRES: aarch64, x86
2+
// RUN: split-file %s %t.dir && cd %t.dir
3+
4+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows crt1-arm64.s -o crt1-arm64.obj
5+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows crt2-arm64.s -o crt2-arm64.obj
6+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows crt1-arm64ec.s -o crt1-arm64ec.obj
7+
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows crt2-amd64.s -o crt2-amd64.obj
8+
9+
// Check that .CRT chunks are correctly sorted and that EC and native chunks are split.
10+
11+
// RUN: lld-link -out:out.dll -machine:arm64x -dll -noentry crt1-arm64.obj crt2-arm64.obj crt1-arm64ec.obj crt2-amd64.obj
12+
// RUN: llvm-readobj --hex-dump=.CRT out.dll | FileCheck %s
13+
14+
// RUN: lld-link -out:out2.dll -machine:arm64x -dll -noentry crt1-arm64.obj crt1-arm64ec.obj crt2-arm64.obj crt2-amd64.obj
15+
// RUN: llvm-readobj --hex-dump=.CRT out2.dll | FileCheck %s
16+
17+
// RUN: lld-link -out:out3.dll -machine:arm64x -dll -noentry crt2-amd64.obj crt1-arm64ec.obj crt2-arm64.obj crt1-arm64.obj
18+
// RUN: llvm-readobj --hex-dump=.CRT out3.dll | FileCheck %s
19+
20+
// CHECK: 0x180002000 01000000 00000000 02000000 00000000
21+
// CHECK-NEXT: 0x180002010 03000000 00000000 11000000 00000000
22+
// CHECK-NEXT: 0x180002020 12000000 00000000 13000000 00000000
23+
24+
#--- crt1-arm64.s
25+
.section .CRT$A,"dr"
26+
.xword 1
27+
.section .CRT$Z,"dr"
28+
.xword 3
29+
30+
#--- crt2-arm64.s
31+
.section .CRT$B,"dr"
32+
.xword 2
33+
34+
#--- crt1-arm64ec.s
35+
.section .CRT$A,"dr"
36+
.xword 0x11
37+
.section .CRT$Z,"dr"
38+
.xword 0x13
39+
40+
#--- crt2-amd64.s
41+
.section .CRT$B,"dr"
42+
.quad 0x12

0 commit comments

Comments
 (0)