diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h --- a/bolt/include/bolt/Core/BinaryContext.h +++ b/bolt/include/bolt/Core/BinaryContext.h @@ -383,6 +383,8 @@ } unsigned getDWARFEncodingSize(unsigned Encoding) { + if (Encoding == dwarf::DW_EH_PE_omit) + return 0; switch (Encoding & 0x0f) { default: llvm_unreachable("unknown encoding"); @@ -666,7 +668,6 @@ /// DWARF encoding. Available encoding types defined in BinaryFormat/Dwarf.h /// enum Constants, e.g. DW_EH_PE_omit. - unsigned TTypeEncoding = dwarf::DW_EH_PE_omit; unsigned LSDAEncoding = dwarf::DW_EH_PE_omit; BinaryContext(std::unique_ptr Ctx, diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h --- a/bolt/include/bolt/Core/BinaryFunction.h +++ b/bolt/include/bolt/Core/BinaryFunction.h @@ -191,7 +191,7 @@ /// Mark injected functions bool IsInjected = false; - + unsigned LSDATypeEncoding = dwarf::DW_EH_PE_omit; using LSDATypeTableTy = SmallVector; /// List of DWARF CFI instructions. Original CFI from the binary must be diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp --- a/bolt/lib/Core/BinaryContext.cpp +++ b/bolt/lib/Core/BinaryContext.cpp @@ -186,13 +186,9 @@ Large = true; unsigned LSDAEncoding = Large ? dwarf::DW_EH_PE_absptr : dwarf::DW_EH_PE_udata4; - unsigned TTypeEncoding = - Large ? dwarf::DW_EH_PE_absptr : dwarf::DW_EH_PE_udata4; if (IsPIC) { LSDAEncoding = dwarf::DW_EH_PE_pcrel | (Large ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); - TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - (Large ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); } std::unique_ptr DisAsm( @@ -236,7 +232,6 @@ std::move(InstructionPrinter), std::move(MIA), nullptr, std::move(MRI), std::move(DisAsm)); - BC->TTypeEncoding = TTypeEncoding; BC->LSDAEncoding = LSDAEncoding; BC->MAB = std::unique_ptr( diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp --- a/bolt/lib/Core/BinaryEmitter.cpp +++ b/bolt/lib/Core/BinaryEmitter.cpp @@ -900,7 +900,7 @@ Streamer.switchSection(BC.MOFI->getLSDASection()); - const unsigned TTypeEncoding = BC.TTypeEncoding; + const unsigned TTypeEncoding = BF.LSDATypeEncoding; const unsigned TTypeEncodingSize = BC.getDWARFEncodingSize(TTypeEncoding); const uint16_t TTypeAlignment = 4; @@ -979,8 +979,9 @@ // Account for any extra padding that will be added to the call site table // length. - Streamer.emitULEB128IntValue(TTypeBaseOffset, - /*PadTo=*/TTypeBaseOffsetSize + SizeAlign); + if (TTypeEncoding != dwarf::DW_EH_PE_omit) + Streamer.emitULEB128IntValue(TTypeBaseOffset, + /*PadTo=*/TTypeBaseOffsetSize + SizeAlign); // Emit the landing pad call site table. We use signed data4 since we can emit // a landing pad in a different part of the split function that could appear diff --git a/bolt/lib/Core/Exceptions.cpp b/bolt/lib/Core/Exceptions.cpp --- a/bolt/lib/Core/Exceptions.cpp +++ b/bolt/lib/Core/Exceptions.cpp @@ -120,12 +120,12 @@ LPStart = (LPStartEncoding && 0xFF == 0) ? *MaybeLPStart : *MaybeLPStart - Address; - const uint8_t TTypeEncoding = Data.getU8(&Offset); + LSDATypeEncoding = Data.getU8(&Offset); size_t TTypeEncodingSize = 0; uintptr_t TTypeEnd = 0; - if (TTypeEncoding != DW_EH_PE_omit) { + if (LSDATypeEncoding != DW_EH_PE_omit) { TTypeEnd = Data.getULEB128(&Offset); - TTypeEncodingSize = BC.getDWARFEncodingSize(TTypeEncoding); + TTypeEncodingSize = BC.getDWARFEncodingSize(LSDATypeEncoding); } if (opts::PrintExceptions) { @@ -134,7 +134,7 @@ outs() << "LPStart Encoding = 0x" << Twine::utohexstr(LPStartEncoding) << '\n'; outs() << "LPStart = 0x" << Twine::utohexstr(LPStart) << '\n'; - outs() << "TType Encoding = 0x" << Twine::utohexstr(TTypeEncoding) << '\n'; + outs() << "TType Encoding = 0x" << Twine::utohexstr(LSDATypeEncoding) << '\n'; outs() << "TType End = " << TTypeEnd << '\n'; } @@ -174,7 +174,6 @@ uint64_t LandingPad = *Data.getEncodedPointer( &CallSitePtr, CallSiteEncoding, CallSitePtr + LSDASectionAddress); uint64_t ActionEntry = Data.getULEB128(&CallSitePtr); - uint64_t LPOffset = LPStart + LandingPad; uint64_t LPAddress = Address + LPOffset; @@ -252,14 +251,14 @@ uint64_t TTEntry = TypeTableStart - Index * TTypeEncodingSize; const uint64_t TTEntryAddress = TTEntry + LSDASectionAddress; uint64_t TypeAddress = - *Data.getEncodedPointer(&TTEntry, TTypeEncoding, TTEntryAddress); - if ((TTypeEncoding & DW_EH_PE_pcrel) && TypeAddress == TTEntryAddress) + *Data.getEncodedPointer(&TTEntry, LSDATypeEncoding, TTEntryAddress); + if ((LSDATypeEncoding & DW_EH_PE_pcrel) && TypeAddress == TTEntryAddress) TypeAddress = 0; if (TypeAddress == 0) { OS << ""; return; } - if (TTypeEncoding & DW_EH_PE_indirect) { + if (LSDATypeEncoding & DW_EH_PE_indirect) { ErrorOr PointerOrErr = BC.getPointerAtAddress(TypeAddress); assert(PointerOrErr && "failed to decode indirect address"); TypeAddress = *PointerOrErr; @@ -337,10 +336,10 @@ uint64_t TTEntry = TypeTableStart - Index * TTypeEncodingSize; const uint64_t TTEntryAddress = TTEntry + LSDASectionAddress; uint64_t TypeAddress = - *Data.getEncodedPointer(&TTEntry, TTypeEncoding, TTEntryAddress); - if ((TTypeEncoding & DW_EH_PE_pcrel) && (TypeAddress == TTEntryAddress)) + *Data.getEncodedPointer(&TTEntry, LSDATypeEncoding, TTEntryAddress); + if ((LSDATypeEncoding & DW_EH_PE_pcrel) && (TypeAddress == TTEntryAddress)) TypeAddress = 0; - if (TTypeEncoding & DW_EH_PE_indirect) { + if (LSDATypeEncoding & DW_EH_PE_indirect) { LSDATypeAddressTable.emplace_back(TypeAddress); if (TypeAddress) { ErrorOr PointerOrErr = BC.getPointerAtAddress(TypeAddress); diff --git a/bolt/test/runtime/exceptions-no-pie.cpp b/bolt/test/runtime/exceptions-no-pie.cpp new file mode 100644 --- /dev/null +++ b/bolt/test/runtime/exceptions-no-pie.cpp @@ -0,0 +1,41 @@ +// REQUIRES: system-linux +// RUN: %clangxx -no-pie -Wl,-q %s -o %t.exe +// RUN: llvm-bolt %t.exe -o %t.bolt.exe -lite=false +// RUN: not --crash %t.bolt.exe 2>&1 | FileCheck %s --check-prefix=CHECK-FAIL +// CHECK-FAIL: Should pass one argument +// RUN: not %t.bolt.exe -1 | FileCheck %s --check-prefix=CHECK-BAD +// CHECK-BAD: Bad value +// RUN: not %t.bolt.exe 0 | FileCheck %s --check-prefix=CHECK-ZERO +// CHECK-ZERO: Value is zero +// RUN: %t.bolt.exe 1 | FileCheck %s --check-prefix=CHECK-GOOD +// CHECK-GOOD: Good value +#include +#include + +struct ValIsZero { + const char *error = "Value is zero\n"; +}; +int dummy(int arg) { + if (arg == 0) + throw ValIsZero(); + if (arg > 0) + return 0; + else + throw std::out_of_range("Bad value"); +} + +int main(int argc, char **argv) { + if (argc != 2) + throw std::invalid_argument("Should pass one argument"); + try { + dummy(std::strtol(argv[1], nullptr, 10)); + } catch (std::out_of_range &e) { + std::cout << e.what() << "\n"; + return 1; + } catch (ValIsZero &e) { + std::cout << e.error; + return 1; + } + std::cout << "Good value\n"; + return 0; +}