[BOLT] Skip FDE emission for patch functions (#136224)

Patch functions are used to fix instructions in the original code, i.e.,
they are not functions in a traditional sense, but rather pieces of
emitted code that are embedded into real functions.

We used to emit FDEs for all functions, including patch functions.
However, FDEs for patches are not only unnecessary, but they can lead to
problems with libraries and runtimes that consume FDEs, e.g. C++
exception handling runtime.

Note that we use named patches to fix function entry points and in that
case they behave more like regular functions. Thus we issue FDEs for
those.
This commit is contained in:
Maksim Panchenko
2025-04-17 19:58:32 -07:00
committed by GitHub
parent e5263e3ec8
commit 0977a7130b
2 changed files with 11 additions and 2 deletions

View File

@@ -373,8 +373,10 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function,
Streamer.emitLabel(StartSymbol);
}
const bool NeedsFDE =
Function.hasCFI() && !(Function.isPatch() && Function.isAnonymous());
// Emit CFI start
if (Function.hasCFI()) {
if (NeedsFDE) {
Streamer.emitCFIStartProc(/*IsSimple=*/false);
if (Function.getPersonalityFunction() != nullptr)
Streamer.emitCFIPersonality(Function.getPersonalityFunction(),
@@ -421,7 +423,7 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function,
Streamer.emitBytes(BC.MIB->getTrapFillValue());
// Emit CFI end
if (Function.hasCFI())
if (NeedsFDE)
Streamer.emitCFIEndProc();
MCSymbol *EndSymbol = Function.getFunctionEndLabel(FF.getFragmentNum());

View File

@@ -11,6 +11,13 @@
# RUN: llvm-objdump -d --disassemble-symbols=cold_function %t.bolt \
# RUN: | FileCheck %s
## Verify that the number of FDEs matches the number of functions in the output
## binary. There are three original functions and two optimized.
# RUN: llvm-readelf -u %t.bolt | grep -wc FDE \
# RUN: | FileCheck --check-prefix=CHECK-FDE %s
# CHECK-FDE: 5
## In lite mode, optimized code will be separated from the original .text by
## over 128MB, making it impossible for call/bl instructions in cold functions
## to reach optimized functions directly.