Skip to content

Commit 93a4244

Browse files
authored
[BOLT] Use new assembler directives for EH table emission (#116294)
When emitting C++ exception tables (LSDAs), BOLT used to estimate the size of the tables beforehand. This implementation was necessary as the assembler/streamer lacked the emitULEB128IntValue() functionality. As I plan to introduce [u|s]uleb128-encoded exception tables in BOLT, now is a perfect time to switch to the new API and eliminate the need to pre-compute the size of the tables.
1 parent c4eeef3 commit 93a4244

File tree

1 file changed

+19
-35
lines changed

1 file changed

+19
-35
lines changed

bolt/lib/Core/BinaryEmitter.cpp

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -906,17 +906,6 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, const FunctionFragment &FF) {
906906
if (Sites.empty())
907907
return;
908908

909-
// Calculate callsite table size. Size of each callsite entry is:
910-
//
911-
// sizeof(start) + sizeof(length) + sizeof(LP) + sizeof(uleb128(action))
912-
//
913-
// or
914-
//
915-
// sizeof(dwarf::DW_EH_PE_data4) * 3 + sizeof(uleb128(action))
916-
uint64_t CallSiteTableLength = llvm::size(Sites) * 4 * 3;
917-
for (const auto &FragmentCallSite : Sites)
918-
CallSiteTableLength += getULEB128Size(FragmentCallSite.second.Action);
919-
920909
Streamer.switchSection(BC.MOFI->getLSDASection());
921910

922911
const unsigned TTypeEncoding = BF.getLSDATypeEncoding();
@@ -975,36 +964,24 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, const FunctionFragment &FF) {
975964

976965
Streamer.emitIntValue(TTypeEncoding, 1); // TType format
977966

978-
// See the comment in EHStreamer::emitExceptionTable() on to use
979-
// uleb128 encoding (which can use variable number of bytes to encode the same
980-
// value) to ensure type info table is properly aligned at 4 bytes without
981-
// iteratively fixing sizes of the tables.
982-
unsigned CallSiteTableLengthSize = getULEB128Size(CallSiteTableLength);
983-
unsigned TTypeBaseOffset =
984-
sizeof(int8_t) + // Call site format
985-
CallSiteTableLengthSize + // Call site table length size
986-
CallSiteTableLength + // Call site table length
987-
BF.getLSDAActionTable().size() + // Actions table size
988-
BF.getLSDATypeTable().size() * TTypeEncodingSize; // Types table size
989-
unsigned TTypeBaseOffsetSize = getULEB128Size(TTypeBaseOffset);
990-
unsigned TotalSize = sizeof(int8_t) + // LPStart format
991-
sizeof(int8_t) + // TType format
992-
TTypeBaseOffsetSize + // TType base offset size
993-
TTypeBaseOffset; // TType base offset
994-
unsigned SizeAlign = (4 - TotalSize) & 3;
995-
996-
if (TTypeEncoding != dwarf::DW_EH_PE_omit)
997-
// Account for any extra padding that will be added to the call site table
998-
// length.
999-
Streamer.emitULEB128IntValue(TTypeBaseOffset,
1000-
/*PadTo=*/TTypeBaseOffsetSize + SizeAlign);
967+
MCSymbol *TTBaseLabel = nullptr;
968+
if (TTypeEncoding != dwarf::DW_EH_PE_omit) {
969+
TTBaseLabel = BC.Ctx->createTempSymbol("TTBase");
970+
MCSymbol *TTBaseRefLabel = BC.Ctx->createTempSymbol("TTBaseRef");
971+
Streamer.emitAbsoluteSymbolDiffAsULEB128(TTBaseLabel, TTBaseRefLabel);
972+
Streamer.emitLabel(TTBaseRefLabel);
973+
}
1001974

1002975
// Emit the landing pad call site table. We use signed data4 since we can emit
1003976
// a landing pad in a different part of the split function that could appear
1004977
// earlier in the address space than LPStart.
1005978
Streamer.emitIntValue(dwarf::DW_EH_PE_sdata4, 1);
1006-
Streamer.emitULEB128IntValue(CallSiteTableLength);
1007979

980+
MCSymbol *CSTStartLabel = BC.Ctx->createTempSymbol("CSTStart");
981+
MCSymbol *CSTEndLabel = BC.Ctx->createTempSymbol("CSTEnd");
982+
Streamer.emitAbsoluteSymbolDiffAsULEB128(CSTEndLabel, CSTStartLabel);
983+
984+
Streamer.emitLabel(CSTStartLabel);
1008985
for (const auto &FragmentCallSite : Sites) {
1009986
const BinaryFunction::CallSite &CallSite = FragmentCallSite.second;
1010987
const MCSymbol *BeginLabel = CallSite.Start;
@@ -1020,6 +997,7 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, const FunctionFragment &FF) {
1020997
emitLandingPad(CallSite.LP);
1021998
Streamer.emitULEB128IntValue(CallSite.Action);
1022999
}
1000+
Streamer.emitLabel(CSTEndLabel);
10231001

10241002
// Write out action, type, and type index tables at the end.
10251003
//
@@ -1038,6 +1016,8 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, const FunctionFragment &FF) {
10381016
assert(TypeTable.size() == BF.getLSDATypeTable().size() &&
10391017
"indirect type table size mismatch");
10401018

1019+
Streamer.emitValueToAlignment(Align(TTypeAlignment));
1020+
10411021
for (int Index = TypeTable.size() - 1; Index >= 0; --Index) {
10421022
const uint64_t TypeAddress = TypeTable[Index];
10431023
switch (TTypeEncoding & 0x70) {
@@ -1063,6 +1043,10 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, const FunctionFragment &FF) {
10631043
}
10641044
}
10651045
}
1046+
1047+
if (TTypeEncoding != dwarf::DW_EH_PE_omit)
1048+
Streamer.emitLabel(TTBaseLabel);
1049+
10661050
for (uint8_t const &Byte : BF.getLSDATypeIndexTable())
10671051
Streamer.emitIntValue(Byte, 1);
10681052
}

0 commit comments

Comments
 (0)