[LLD][COFF] Ensure .bss is merged at the end of a section. (#137677)

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.
This commit is contained in:
jeremyd2019 2025-04-30 02:09:20 -07:00 committed by GitHub
parent 08f0aa4800
commit bb2f7596a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 126 additions and 21 deletions

View File

@ -215,6 +215,7 @@ private:
void appendImportThunks();
void locateImportTables();
void createExportTable();
void mergeSection(const std::map<StringRef, StringRef>::value_type &p);
void mergeSections();
void sortECChunks();
void appendECImportTables();
@ -1566,6 +1567,30 @@ void Writer::createSymbolAndStringTable() {
fileSize = alignTo(fileOff, ctx.config.fileAlign);
}
void Writer::mergeSection(const std::map<StringRef, StringRef>::value_type &p) {
StringRef toName = p.second;
if (p.first == toName)
return;
StringSet<> names;
while (true) {
if (!names.insert(toName).second)
Fatal(ctx) << "/merge: cycle found for section '" << p.first << "'";
auto i = ctx.config.merge.find(toName);
if (i == ctx.config.merge.end())
break;
toName = i->second;
}
OutputSection *from = findSection(p.first);
OutputSection *to = findSection(toName);
if (!from)
return;
if (!to) {
from->name = toName;
return;
}
to->merge(from);
}
void Writer::mergeSections() {
llvm::TimeTraceScope timeScope("Merge sections");
if (!pdataSec->chunks.empty()) {
@ -1594,28 +1619,16 @@ void Writer::mergeSections() {
}
for (auto &p : ctx.config.merge) {
StringRef toName = p.second;
if (p.first == toName)
continue;
StringSet<> names;
while (true) {
if (!names.insert(toName).second)
Fatal(ctx) << "/merge: cycle found for section '" << p.first << "'";
auto i = ctx.config.merge.find(toName);
if (i == ctx.config.merge.end())
break;
toName = i->second;
}
OutputSection *from = findSection(p.first);
OutputSection *to = findSection(toName);
if (!from)
continue;
if (!to) {
from->name = toName;
continue;
}
to->merge(from);
if (p.first != ".bss")
mergeSection(p);
}
// Because .bss contains all zeros, it should be merged at the end of
// whatever section it is being merged into (usually .data) so that the image
// need not actually contain all of the zeros.
auto it = ctx.config.merge.find(".bss");
if (it != ctx.config.merge.end())
mergeSection(*it);
}
// EC targets may have chunks of various architectures mixed together at this

View File

@ -0,0 +1,92 @@
# RUN: yaml2obj %s -o %t.obj
# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
# RUN: /merge:.other=.data %t.obj /debug
# RUN: llvm-readobj --sections %t.exe | FileCheck %s
# CHECK: Name: .data
# CHECK-NEXT: VirtualSize: 0x2018
# CHECK-NEXT: VirtualAddress: 0x3000
# CHECK-NEXT: RawDataSize: 512
# CHECK-NOT: Name: .other
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_AMD64
Characteristics: [ ]
sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: '90'
SizeOfRawData: 1
- Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: '010000000000000002'
SizeOfRawData: 9
- Name: .bss
Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: ''
SizeOfRawData: 8192
- Name: .other
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: '030000000000000004'
SizeOfRawData: 9
symbols:
- Name: .text
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 1
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 4027552580
Number: 1
- Name: .data
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 9
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 4185224559
Number: 2
- Name: .bss
Value: 0
SectionNumber: 3
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 8192
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 3
- Name: .other
Value: 0
SectionNumber: 4
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 9
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 1054931164
Number: 4
- Name: main
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...