@@ -140,7 +140,7 @@ class BinaryEmitter {
140140
141141 void emitCFIInstruction (const MCCFIInstruction &Inst) const ;
142142
143- // / Emit exception handling ranges for the function.
143+ // / Emit exception handling ranges for the function fragment .
144144 void emitLSDA (BinaryFunction &BF, const FunctionFragment &FF);
145145
146146 // / Emit line number information corresponding to \p NewLoc. \p PrevLoc
@@ -915,17 +915,29 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, const FunctionFragment &FF) {
915915 // Emit the LSDA header.
916916
917917 // If LPStart is omitted, then the start of the FDE is used as a base for
918- // landing pad displacements. Then, if a cold fragment starts with a landing
919- // pad, this means that the first landing pad offset will be 0. However, C++
920- // runtime treats 0 as if there is no landing pad present , thus we *must* emit
921- // non-zero offsets for all valid LPs .
918+ // landing pad displacements. Then, if a cold fragment starts with
919+ // a landing pad, this means that the first landing pad offset will be 0.
920+ // However, C++ runtime will treat 0 as if there is no landing pad, thus we
921+ // cannot emit LP offset as 0 .
922922 //
923923 // As a solution, for fixed-address binaries we set LPStart to 0, and for
924- // position-independent binaries we set LP start to FDE start minus one byte
925- // for FDEs that start with a landing pad.
926- const bool NeedsLPAdjustment = !FF.empty () && FF.front ()->isLandingPad ();
924+ // position-independent binaries we offset LP start by one byte.
925+ bool NeedsLPAdjustment = false ;
927926 std::function<void (const MCSymbol *)> emitLandingPad;
928- if (BC.HasFixedLoadAddress ) {
927+
928+ // Check if there's a symbol associated with a landing pad fragment.
929+ const MCSymbol *LPStartSymbol = BF.getLPStartSymbol (FF.getFragmentNum ());
930+ if (!LPStartSymbol) {
931+ // Since landing pads are not in the same fragment, we fall back to emitting
932+ // absolute addresses for this FDE.
933+ if (opts::Verbosity >= 2 ) {
934+ BC.outs () << " BOLT-INFO: falling back to generating absolute-address "
935+ << " exception ranges for " << BF << ' \n ' ;
936+ }
937+
938+ assert (BC.HasFixedLoadAddress &&
939+ " Cannot emit absolute-address landing pads for PIE/DSO" );
940+
929941 Streamer.emitIntValue (dwarf::DW_EH_PE_udata4, 1 ); // LPStart format
930942 Streamer.emitIntValue (0 , 4 ); // LPStart
931943 emitLandingPad = [&](const MCSymbol *LPSymbol) {
@@ -935,17 +947,23 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, const FunctionFragment &FF) {
935947 Streamer.emitIntValue (0 , 4 );
936948 };
937949 } else {
938- if (NeedsLPAdjustment) {
939- // Use relative LPStart format and emit LPStart as [SymbolStart - 1].
950+ std::optional<FragmentNum> LPFN = BF.getLPFragment (FF.getFragmentNum ());
951+ const FunctionFragment &LPFragment = BF.getLayout ().getFragment (*LPFN);
952+ NeedsLPAdjustment =
953+ (!LPFragment.empty () && LPFragment.front ()->isLandingPad ());
954+
955+ // Emit LPStart encoding and optionally LPStart.
956+ if (NeedsLPAdjustment || LPStartSymbol != StartSymbol) {
940957 Streamer.emitIntValue (dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4, 1 );
941958 MCSymbol *DotSymbol = BC.Ctx ->createTempSymbol (" LPBase" );
942959 Streamer.emitLabel (DotSymbol);
943960
944961 const MCExpr *LPStartExpr = MCBinaryExpr::createSub (
945- MCSymbolRefExpr::create (StartSymbol , *BC.Ctx ),
962+ MCSymbolRefExpr::create (LPStartSymbol , *BC.Ctx ),
946963 MCSymbolRefExpr::create (DotSymbol, *BC.Ctx ), *BC.Ctx );
947- LPStartExpr = MCBinaryExpr::createSub (
948- LPStartExpr, MCConstantExpr::create (1 , *BC.Ctx ), *BC.Ctx );
964+ if (NeedsLPAdjustment)
965+ LPStartExpr = MCBinaryExpr::createSub (
966+ LPStartExpr, MCConstantExpr::create (1 , *BC.Ctx ), *BC.Ctx );
949967 Streamer.emitValue (LPStartExpr, 4 );
950968 } else {
951969 // DW_EH_PE_omit means FDE start (StartSymbol) will be used as LPStart.
@@ -955,13 +973,13 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, const FunctionFragment &FF) {
955973 if (LPSymbol) {
956974 const MCExpr *LPOffsetExpr = MCBinaryExpr::createSub (
957975 MCSymbolRefExpr::create (LPSymbol, *BC.Ctx ),
958- MCSymbolRefExpr::create (StartSymbol , *BC.Ctx ), *BC.Ctx );
976+ MCSymbolRefExpr::create (LPStartSymbol , *BC.Ctx ), *BC.Ctx );
959977 if (NeedsLPAdjustment)
960978 LPOffsetExpr = MCBinaryExpr::createAdd (
961979 LPOffsetExpr, MCConstantExpr::create (1 , *BC.Ctx ), *BC.Ctx );
962- Streamer.emitValue (LPOffsetExpr, 4 );
980+ Streamer.emitULEB128Value (LPOffsetExpr);
963981 } else {
964- Streamer.emitIntValue ( 0 , 4 );
982+ Streamer.emitULEB128IntValue ( 0 );
965983 }
966984 };
967985 }
@@ -976,10 +994,12 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, const FunctionFragment &FF) {
976994 Streamer.emitLabel (TTBaseRefLabel);
977995 }
978996
979- // Emit the landing pad call site table. We use signed data4 since we can emit
980- // a landing pad in a different part of the split function that could appear
981- // earlier in the address space than LPStart.
982- Streamer.emitIntValue (dwarf::DW_EH_PE_sdata4, 1 );
997+ // Emit encoding of entries in the call site table. The format is used for the
998+ // call site start, length, and corresponding landing pad.
999+ if (!LPStartSymbol)
1000+ Streamer.emitIntValue (dwarf::DW_EH_PE_sdata4, 1 );
1001+ else
1002+ Streamer.emitIntValue (dwarf::DW_EH_PE_uleb128, 1 );
9831003
9841004 MCSymbol *CSTStartLabel = BC.Ctx ->createTempSymbol (" CSTStart" );
9851005 MCSymbol *CSTEndLabel = BC.Ctx ->createTempSymbol (" CSTEnd" );
@@ -996,8 +1016,13 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, const FunctionFragment &FF) {
9961016
9971017 // Start of the range is emitted relative to the start of current
9981018 // function split part.
999- Streamer.emitAbsoluteSymbolDiff (BeginLabel, StartSymbol, 4 );
1000- Streamer.emitAbsoluteSymbolDiff (EndLabel, BeginLabel, 4 );
1019+ if (!LPStartSymbol) {
1020+ Streamer.emitAbsoluteSymbolDiff (BeginLabel, StartSymbol, 4 );
1021+ Streamer.emitAbsoluteSymbolDiff (EndLabel, BeginLabel, 4 );
1022+ } else {
1023+ Streamer.emitAbsoluteSymbolDiffAsULEB128 (BeginLabel, StartSymbol);
1024+ Streamer.emitAbsoluteSymbolDiffAsULEB128 (EndLabel, BeginLabel);
1025+ }
10011026 emitLandingPad (CallSite.LP );
10021027 Streamer.emitULEB128IntValue (CallSite.Action );
10031028 }
0 commit comments