Skip to content

Commit fad1a24

Browse files
maksfbmemfrob
authored andcommitted
[BOLT] Account for FDE functions when calculating max function size
Summary: When we calculate maximum function size we only used to rely on the symbol table information, and ignore function info coming from FDEs. Invalid maximum function size can lead to code emission over the code of neighbouring function. Fix this by considering FDE functions when determining the maximum function size. (cherry picked from FBD6025613)
1 parent f5aa80a commit fad1a24

File tree

1 file changed

+21
-20
lines changed

1 file changed

+21
-20
lines changed

bolt/RewriteInstance.cpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,12 +1351,14 @@ void RewriteInstance::disassemblePLT() {
13511351
}
13521352

13531353
void RewriteInstance::adjustFunctionBoundaries() {
1354-
for (auto &BFI : BinaryFunctions) {
1355-
auto &Function = BFI.second;
1356-
1357-
// Check if there's a symbol with a larger address in the same section.
1358-
// If there is - it determines the maximum size for the current function,
1359-
// otherwise, it is the size of containing section the defines it.
1354+
for (auto BFI = BinaryFunctions.begin(), BFE = BinaryFunctions.end();
1355+
BFI != BFE; ++BFI) {
1356+
auto &Function = BFI->second;
1357+
1358+
// Check if there's a symbol or a function with a larger address in the
1359+
// same section. If there is - it determines the maximum size for the
1360+
// current function. Otherwise, it is the size of a containing section
1361+
// the defines it.
13601362
//
13611363
// NOTE: ignore some symbols that could be tolerated inside the body
13621364
// of a function.
@@ -1387,22 +1389,21 @@ void RewriteInstance::adjustFunctionBoundaries() {
13871389
? InputFile->section_end()
13881390
: NextSymRefI->second.getSection();
13891391

1390-
uint64_t MaxSize;
1391-
if (NextSymRefI != FileSymRefs.end() &&
1392-
NextSymRefI->second.getSection() &&
1393-
*NextSymRefI->second.getSection() != InputFile->section_end() &&
1394-
**NextSymRefI->second.getSection() == Function.getSection()) {
1395-
MaxSize = NextSymRefI->first - Function.getAddress();
1396-
} else {
1397-
// Function runs till the end of the containing section.
1398-
uint64_t SectionEnd = Function.getSection().getAddress() +
1399-
Function.getSection().getSize();
1400-
assert((NextSymRefI == FileSymRefs.end() ||
1401-
NextSymRefI->first >= SectionEnd) &&
1402-
"different sections should not overlap");
1403-
MaxSize = SectionEnd - Function.getAddress();
1392+
// Function runs at most till the end of the containing section.
1393+
uint64_t NextObjectAddress = Function.getSection().getAddress() +
1394+
Function.getSection().getSize();
1395+
// Or till the next object marked by a symbol.
1396+
if (NextSymRefI != FileSymRefs.end()) {
1397+
NextObjectAddress = std::min(NextSymRefI->first, NextObjectAddress);
1398+
}
1399+
// Or till the next function not marked by a symbol.
1400+
if (std::next(BFI) != BFE) {
1401+
const auto &NextFunction = std::next(BFI)->second;
1402+
NextObjectAddress = std::min(NextFunction.getAddress(),
1403+
NextObjectAddress);
14041404
}
14051405

1406+
const auto MaxSize = NextObjectAddress - Function.getAddress();
14061407
if (MaxSize < Function.getSize()) {
14071408
errs() << "BOLT-ERROR: symbol seen in the middle of the function "
14081409
<< Function << ". Skipping.\n";

0 commit comments

Comments
 (0)