Skip to content

Commit ed0344c

Browse files
jeremyd2019GeorgeARM
authored andcommitted
[LLD][COFF] add __{data,bss}_{start,end}__ symbols for Cygwin support (llvm#136180)
Cygwin requires these symbols for its fork emulation to know what data to copy into the child. GNU ld defines these symbols for MinGW targets also, so do the same here. Cygwin also has the `.data_cygwin_nocopy` section, which is merged into `.data` outside the `__data_start__` to `__data_end__` range. This excludes it from fork's copying. AFAIK it's only used by the Cygwin DLL itself (which requires a custom linker script to link, that's not supported by LLD), but the section is included in GNU ld's default linker script so handle it here too. Signed-off-by: Jeremy Drake <[email protected]>
1 parent acad199 commit ed0344c

File tree

3 files changed

+135
-2
lines changed

3 files changed

+135
-2
lines changed

lld/COFF/Driver.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,6 +2028,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
20282028
parseMerge(".ctors=.rdata");
20292029
parseMerge(".dtors=.rdata");
20302030
parseMerge(".CRT=.rdata");
2031+
parseMerge(".data_cygwin_nocopy=.data");
20312032
}
20322033

20332034
// Handle /section
@@ -2484,6 +2485,10 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
24842485
if (config->mingw) {
24852486
symtab.addAbsolute(symtab.mangle("__CTOR_LIST__"), 0);
24862487
symtab.addAbsolute(symtab.mangle("__DTOR_LIST__"), 0);
2488+
symtab.addAbsolute("__data_start__", 0);
2489+
symtab.addAbsolute("__data_end__", 0);
2490+
symtab.addAbsolute("__bss_start__", 0);
2491+
symtab.addAbsolute("__bss_end__", 0);
24872492
}
24882493
if (config->debug || config->buildIDHash != BuildIDHash::None)
24892494
if (symtab.findUnderscore("__buildid"))

lld/COFF/Writer.cpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ class Writer {
240240
void createRuntimePseudoRelocs();
241241
void createECChunks();
242242
void insertCtorDtorSymbols();
243+
void insertBssDataStartEndSymbols();
243244
void markSymbolsWithRelocations(ObjFile *file, SymbolRVASet &usedSymbols);
244245
void createGuardCFTables();
245246
void markSymbolsForRVATable(ObjFile *file,
@@ -315,6 +316,7 @@ class Writer {
315316

316317
OutputSection *textSec;
317318
OutputSection *hexpthkSec;
319+
OutputSection *bssSec;
318320
OutputSection *rdataSec;
319321
OutputSection *buildidSec;
320322
OutputSection *dataSec;
@@ -1077,7 +1079,7 @@ void Writer::createSections() {
10771079
textSec = createSection(".text", code | r | x);
10781080
if (isArm64EC(ctx.config.machine))
10791081
hexpthkSec = createSection(".hexpthk", code | r | x);
1080-
createSection(".bss", bss | r | w);
1082+
bssSec = createSection(".bss", bss | r | w);
10811083
rdataSec = createSection(".rdata", data | r);
10821084
buildidSec = createSection(".buildid", data | r);
10831085
dataSec = createSection(".data", data | r | w);
@@ -1260,8 +1262,10 @@ void Writer::createMiscChunks() {
12601262
if (config->autoImport)
12611263
createRuntimePseudoRelocs();
12621264

1263-
if (config->mingw)
1265+
if (config->mingw) {
12641266
insertCtorDtorSymbols();
1267+
insertBssDataStartEndSymbols();
1268+
}
12651269
}
12661270

12671271
// Create .idata section for the DLL-imported symbol table.
@@ -2381,6 +2385,31 @@ void Writer::insertCtorDtorSymbols() {
23812385
}
23822386
}
23832387

2388+
// MinGW (really, Cygwin) specific.
2389+
// The Cygwin startup code uses __data_start__ __data_end__ __bss_start__
2390+
// and __bss_end__ to know what to copy during fork emulation.
2391+
void Writer::insertBssDataStartEndSymbols() {
2392+
if (!dataSec->chunks.empty()) {
2393+
Symbol *dataStartSym = ctx.symtab.find("__data_start__");
2394+
Symbol *dataEndSym = ctx.symtab.find("__data_end__");
2395+
Chunk *endChunk = dataSec->chunks.back();
2396+
replaceSymbol<DefinedSynthetic>(dataStartSym, dataStartSym->getName(),
2397+
dataSec->chunks.front());
2398+
replaceSymbol<DefinedSynthetic>(dataEndSym, dataEndSym->getName(), endChunk,
2399+
endChunk->getSize());
2400+
}
2401+
2402+
if (!bssSec->chunks.empty()) {
2403+
Symbol *bssStartSym = ctx.symtab.find("__bss_start__");
2404+
Symbol *bssEndSym = ctx.symtab.find("__bss_end__");
2405+
Chunk *endChunk = bssSec->chunks.back();
2406+
replaceSymbol<DefinedSynthetic>(bssStartSym, bssStartSym->getName(),
2407+
bssSec->chunks.front());
2408+
replaceSymbol<DefinedSynthetic>(bssEndSym, bssEndSym->getName(), endChunk,
2409+
endChunk->getSize());
2410+
}
2411+
}
2412+
23842413
// Handles /section options to allow users to overwrite
23852414
// section attributes.
23862415
void Writer::setSectionPermissions() {

lld/test/COFF/cygwin-symbols.s

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# REQUIRES: x86
2+
# RUN: split-file %s %t.dir && cd %t.dir
3+
4+
# RUN: llvm-mc -triple=x86_64-windows-cygnus -filetype=obj -o data-no-bss.obj data-no-bss.s
5+
# RUN: lld-link -lldmingw -entry:main data-no-bss.obj -out:data-no-bss.exe
6+
# RUN: llvm-objdump -s data-no-bss.exe | FileCheck --check-prefix=DATANOBSS %s
7+
8+
# RUN: llvm-mc -triple=x86_64-windows-cygnus -filetype=obj -o bss-no-data.obj bss-no-data.s
9+
# RUN: lld-link -lldmingw -entry:main bss-no-data.obj -out:bss-no-data.exe
10+
# RUN: llvm-objdump -s bss-no-data.exe | FileCheck --check-prefix=BSSNODATA %s
11+
12+
# RUN: llvm-mc -triple=x86_64-windows-cygnus -filetype=obj -o data-and-bss.obj data-and-bss.s
13+
# RUN: lld-link -lldmingw -entry:main data-and-bss.obj -out:data-and-bss.exe
14+
# RUN: llvm-objdump -s data-and-bss.exe | FileCheck --check-prefix=DATAANDBSS %s
15+
16+
#--- data-no-bss.s
17+
.globl main
18+
main:
19+
nop
20+
21+
.data
22+
.quad 1
23+
.byte 2
24+
25+
.section .data_cygwin_nocopy, "w"
26+
.align 4
27+
.quad 3
28+
.byte 4
29+
30+
.section .test, "w"
31+
.quad __data_start__
32+
.quad __data_end__
33+
.quad __bss_start__
34+
.quad __bss_end__
35+
36+
#--- bss-no-data.s
37+
.globl main
38+
main:
39+
nop
40+
41+
.bss
42+
.zero 8192
43+
44+
.section .test, "w"
45+
.quad __data_start__
46+
.quad __data_end__
47+
.quad __bss_start__
48+
.quad __bss_end__
49+
50+
#--- data-and-bss.s
51+
.globl main
52+
main:
53+
nop
54+
55+
.data
56+
.quad 1
57+
.byte 2
58+
59+
.section .data_cygwin_nocopy, "w"
60+
.align 4
61+
.quad 3
62+
.byte 4
63+
64+
.bss
65+
.zero 8192
66+
67+
.section .test, "w"
68+
.quad __data_start__
69+
.quad __data_end__
70+
.quad __bss_start__
71+
.quad __bss_end__
72+
73+
# DATANOBSS: Contents of section .data:
74+
# DATANOBSS-NEXT: 140003000 01000000 00000000 02000000 03000000
75+
# DATANOBSS-NEXT: 140003010 00000000 04
76+
# __data_start__ pointing at 0x140003000 and
77+
# __data_end__ pointing at 0x140003009.
78+
# DATANOBSS-NEXT: Contents of section .test:
79+
# DATANOBSS-NEXT: 140004000 00300040 01000000 09300040 01000000
80+
# DATANOBSS-NEXT: 140004010 18300040 01000000 18300040 01000000
81+
82+
# __bss_start__ pointing at 0x140003000 and
83+
# __bss_end__ pointing at 0x140005000.
84+
# BSSNODATA-NOT: Contents of section .data:
85+
# BSSNODATA: Contents of section .test:
86+
# BSSNODATA-NEXT: 140005000 00300040 01000000 00300040 01000000
87+
# BSSNODATA-NEXT: 140005010 00300040 01000000 00500040 01000000
88+
89+
# DATAANDBSS: Contents of section .data:
90+
# DATAANDBSS-NEXT: 140003000 01000000 00000000 02000000 03000000
91+
# DATAANDBSS-NEXT: 140003010 00000000 04000000 00000000 00000000
92+
# __data_start__ pointing at 0x140003000 and
93+
# __data_end__ pointing at 0x140003009.
94+
# __bss_start__ pointing at 0x140003018 and
95+
# __bss_end__ pointing at 0x140005018.
96+
# DATAANDBSS: 1400031f0 00000000 00000000 00000000 00000000
97+
# DATAANDBSS-NEXT: Contents of section .test:
98+
# DATAANDBSS-NEXT: 140006000 00300040 01000000 09300040 01000000
99+
# DATAANDBSS-NEXT: 140006010 18300040 01000000 18500040 01000000

0 commit comments

Comments
 (0)