Skip to content

Commit 116e801

Browse files
authored
[BOLT] Adjust section sizes based on file offsets (#80226)
When we adjust section sizes while rewriting a binary, we should be using section offsets and not addresses to determine if section overlap. NFC for existing binaries.
1 parent f883365 commit 116e801

File tree

2 files changed

+67
-15
lines changed

2 files changed

+67
-15
lines changed

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4141,10 +4141,10 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File,
41414141

41424142
// Keep track of section header entries attached to the corresponding section.
41434143
std::vector<std::pair<BinarySection *, ELFShdrTy>> OutputSections;
4144-
auto addSection = [&](const ELFShdrTy &Section, BinarySection *BinSec) {
4144+
auto addSection = [&](const ELFShdrTy &Section, BinarySection &BinSec) {
41454145
ELFShdrTy NewSection = Section;
4146-
NewSection.sh_name = SHStrTab.getOffset(BinSec->getOutputName());
4147-
OutputSections.emplace_back(BinSec, std::move(NewSection));
4146+
NewSection.sh_name = SHStrTab.getOffset(BinSec.getOutputName());
4147+
OutputSections.emplace_back(&BinSec, std::move(NewSection));
41484148
};
41494149

41504150
// Copy over entries for original allocatable sections using modified name.
@@ -4162,7 +4162,7 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File,
41624162
BinarySection *BinSec = BC->getSectionForSectionRef(SecRef);
41634163
assert(BinSec && "Matching BinarySection should exist.");
41644164

4165-
addSection(Section, BinSec);
4165+
addSection(Section, *BinSec);
41664166
}
41674167

41684168
for (BinarySection &Section : BC->allocatableSections()) {
@@ -4189,7 +4189,7 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File,
41894189
NewSection.sh_link = 0;
41904190
NewSection.sh_info = 0;
41914191
NewSection.sh_addralign = Section.getAlignment();
4192-
addSection(NewSection, &Section);
4192+
addSection(NewSection, Section);
41934193
}
41944194

41954195
// Sort all allocatable sections by their offset.
@@ -4203,19 +4203,19 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File,
42034203
for (auto &SectionKV : OutputSections) {
42044204
ELFShdrTy &Section = SectionKV.second;
42054205

4206-
// TBSS section does not take file or memory space. Ignore it for layout
4207-
// purposes.
4208-
if (Section.sh_type == ELF::SHT_NOBITS && (Section.sh_flags & ELF::SHF_TLS))
4206+
// Ignore TLS sections as they don't take any space in the file.
4207+
if (Section.sh_type == ELF::SHT_NOBITS)
42094208
continue;
42104209

4210+
// Note that address continuity is not guaranteed as sections could be
4211+
// placed in different loadable segments.
42114212
if (PrevSection &&
4212-
PrevSection->sh_addr + PrevSection->sh_size > Section.sh_addr) {
4213-
if (opts::Verbosity > 1)
4213+
PrevSection->sh_offset + PrevSection->sh_size > Section.sh_offset) {
4214+
if (opts::Verbosity > 1) {
42144215
outs() << "BOLT-INFO: adjusting size for section "
42154216
<< PrevBinSec->getOutputName() << '\n';
4216-
PrevSection->sh_size = Section.sh_addr > PrevSection->sh_addr
4217-
? Section.sh_addr - PrevSection->sh_addr
4218-
: 0;
4217+
}
4218+
PrevSection->sh_size = Section.sh_offset - PrevSection->sh_offset;
42194219
}
42204220

42214221
PrevSection = &Section;
@@ -4249,7 +4249,7 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File,
42494249
if (NewSection.sh_type == ELF::SHT_SYMTAB)
42504250
NewSection.sh_info = NumLocalSymbols;
42514251

4252-
addSection(NewSection, BinSec);
4252+
addSection(NewSection, *BinSec);
42534253

42544254
LastFileOffset = BinSec->getOutputFileOffset();
42554255
}
@@ -4274,7 +4274,7 @@ RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File,
42744274
NewSection.sh_info = 0;
42754275
NewSection.sh_addralign = Section.getAlignment();
42764276

4277-
addSection(NewSection, &Section);
4277+
addSection(NewSection, Section);
42784278
}
42794279

42804280
// Assign indices to sections.

bolt/test/X86/phdr-out-of-order.test

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
## Check that llvm-bolt correctly processes a binary with program headers and
2+
## corresponding sections specified in non-ascending address order.
3+
4+
RUN: split-file %s %t
5+
RUN: yaml2obj %t/yaml -o %t.exe --max-size=0
6+
RUN: llvm-bolt %t.exe -o %t.bolt --allow-stripped
7+
RUN: llvm-readelf -WS %t.bolt | FileCheck %s
8+
9+
CHECK: .a PROGBITS 0000000000400000 [[#%.6x, OFFSET:]] 000001
10+
CHECK-NEXT: .b PROGBITS 0000000000000000 [[#%.6x, OFFSET+1]] 000001
11+
CHECK-NEXT: .c PROGBITS 0000000000600000 [[#%.6x, OFFSET+2]] 000001
12+
13+
#--- yaml
14+
--- !ELF
15+
FileHeader:
16+
Class: ELFCLASS64
17+
Data: ELFDATA2LSB
18+
Type: ET_EXEC
19+
Machine: EM_X86_64
20+
ProgramHeaders:
21+
- Type: PT_LOAD
22+
FirstSec: .a
23+
LastSec: .a
24+
VAddr: 0x400000
25+
- Type: PT_LOAD
26+
FirstSec: .b
27+
LastSec: .b
28+
VAddr: 0x0
29+
- Type: PT_LOAD
30+
FirstSec: .c
31+
LastSec: .c
32+
VAddr: 0x600000
33+
Sections:
34+
- Name: .a
35+
Type: SHT_PROGBITS
36+
Flags: [ SHF_ALLOC ]
37+
Content: 00
38+
AddressAlign: 0x1
39+
Address: 0x400000
40+
- Name: .b
41+
Type: SHT_PROGBITS
42+
Flags: [ SHF_ALLOC ]
43+
Content: 00
44+
AddressAlign: 0x1
45+
Address: 0x0
46+
- Name: .c
47+
Type: SHT_PROGBITS
48+
Flags: [ SHF_ALLOC ]
49+
Content: 00
50+
AddressAlign: 0x1
51+
Address: 0x600000
52+
...

0 commit comments

Comments
 (0)