Skip to content

Commit bae6a29

Browse files
committed
[LLD][COFF] Ensure .bss is merged at the end of a section.
Because it is full of zeros, it is expected that as much of it as possible is elided from the actual image, and that cannot happen if there is initialized data in the section after it. Test this by having large .bss sections in the cygwin-symbols test.
1 parent 05747de commit bae6a29

File tree

2 files changed

+45
-36
lines changed

2 files changed

+45
-36
lines changed

lld/COFF/Writer.cpp

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ class Writer {
215215
void appendImportThunks();
216216
void locateImportTables();
217217
void createExportTable();
218+
void mergeSection(const std::map<StringRef, StringRef>::value_type &p);
218219
void mergeSections();
219220
void sortECChunks();
220221
void appendECImportTables();
@@ -1571,6 +1572,30 @@ void Writer::createSymbolAndStringTable() {
15711572
fileSize = alignTo(fileOff, ctx.config.fileAlign);
15721573
}
15731574

1575+
void Writer::mergeSection(const std::map<StringRef, StringRef>::value_type &p) {
1576+
StringRef toName = p.second;
1577+
if (p.first == toName)
1578+
return;
1579+
StringSet<> names;
1580+
while (true) {
1581+
if (!names.insert(toName).second)
1582+
Fatal(ctx) << "/merge: cycle found for section '" << p.first << "'";
1583+
auto i = ctx.config.merge.find(toName);
1584+
if (i == ctx.config.merge.end())
1585+
break;
1586+
toName = i->second;
1587+
}
1588+
OutputSection *from = findSection(p.first);
1589+
OutputSection *to = findSection(toName);
1590+
if (!from)
1591+
return;
1592+
if (!to) {
1593+
from->name = toName;
1594+
return;
1595+
}
1596+
to->merge(from);
1597+
}
1598+
15741599
void Writer::mergeSections() {
15751600
llvm::TimeTraceScope timeScope("Merge sections");
15761601
if (!pdataSec->chunks.empty()) {
@@ -1599,28 +1624,13 @@ void Writer::mergeSections() {
15991624
}
16001625

16011626
for (auto &p : ctx.config.merge) {
1602-
StringRef toName = p.second;
1603-
if (p.first == toName)
1604-
continue;
1605-
StringSet<> names;
1606-
while (true) {
1607-
if (!names.insert(toName).second)
1608-
Fatal(ctx) << "/merge: cycle found for section '" << p.first << "'";
1609-
auto i = ctx.config.merge.find(toName);
1610-
if (i == ctx.config.merge.end())
1611-
break;
1612-
toName = i->second;
1613-
}
1614-
OutputSection *from = findSection(p.first);
1615-
OutputSection *to = findSection(toName);
1616-
if (!from)
1617-
continue;
1618-
if (!to) {
1619-
from->name = toName;
1620-
continue;
1621-
}
1622-
to->merge(from);
1627+
if (p.first != ".bss")
1628+
mergeSection(p);
16231629
}
1630+
1631+
auto it = ctx.config.merge.find(".bss");
1632+
if (it != ctx.config.merge.end())
1633+
mergeSection(*it);
16241634
}
16251635

16261636
// EC targets may have chunks of various architectures mixed together at this

lld/test/COFF/cygwin-symbols.s

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ main:
3939
nop
4040

4141
.bss
42-
.quad 0
43-
.byte 0
42+
.zero 8192
4443

4544
.section .test, "w"
4645
.quad __data_start__
@@ -63,8 +62,7 @@ main:
6362
.byte 4
6463

6564
.bss
66-
.quad 0
67-
.byte 0
65+
.zero 8192
6866

6967
.section .test, "w"
7068
.quad __data_start__
@@ -79,22 +77,23 @@ main:
7977
# __data_end__ pointing at 0x140003009.
8078
# DATANOBSS-NEXT: Contents of section .test:
8179
# DATANOBSS-NEXT: 140004000 00300040 01000000 09300040 01000000
82-
# DATANOBSS-NEXT: 140004010 0c300040 01000000 0c300040 01000000
80+
# DATANOBSS-NEXT: 140004010 18300040 01000000 18300040 01000000
8381

8482
# __bss_start__ pointing at 0x140003000 and
85-
# __bss_end__ pointing at 0x140003009.
83+
# __bss_end__ pointing at 0x140005000.
84+
# BSSNODATA-NOT: Contents of section .data:
8685
# BSSNODATA: Contents of section .test:
87-
# BSSNODATA-NEXT: 140004000 00300040 01000000 00300040 01000000
88-
# BSSNODATA-NEXT: 140004010 00300040 01000000 09300040 01000000
86+
# BSSNODATA-NEXT: 140005000 00300040 01000000 00300040 01000000
87+
# BSSNODATA-NEXT: 140005010 00300040 01000000 00500040 01000000
8988

9089
# DATAANDBSS: Contents of section .data:
91-
# DATAANDBSS-NEXT: 140003000 01000000 00000000 02000000 00000000
92-
# DATAANDBSS-NEXT: 140003010 00000000 00000000 03000000 00000000
93-
# DATAANDBSS-NEXT: 140003020 04
90+
# DATAANDBSS-NEXT: 140003000 01000000 00000000 02000000 03000000
91+
# DATAANDBSS-NEXT: 140003010 00000000 04000000 00000000 00000000
9492
# __data_start__ pointing at 0x140003000 and
9593
# __data_end__ pointing at 0x140003009.
96-
# __bss_start__ pointing at 0x14000300c and
97-
# __bss_end__ pointing at 0x140003015.
94+
# __bss_start__ pointing at 0x140003018 and
95+
# __bss_end__ pointing at 0x140005018.
96+
# DATAANDBSS: 1400031f0 00000000 00000000 00000000 00000000
9897
# DATAANDBSS-NEXT: Contents of section .test:
99-
# DATAANDBSS-NEXT: 140004000 00300040 01000000 09300040 01000000
100-
# DATAANDBSS-NEXT: 140004010 0c300040 01000000 15300040 01000000
98+
# DATAANDBSS-NEXT: 140006000 00300040 01000000 09300040 01000000
99+
# DATAANDBSS-NEXT: 140006010 18300040 01000000 18500040 01000000

0 commit comments

Comments
 (0)