EHStreamer.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. //===- EHStreamer.h - Exception Handling Directive Streamer -----*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file contains support for writing exception info into assembly files.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_EHSTREAMER_H
  13. #define LLVM_LIB_CODEGEN_ASMPRINTER_EHSTREAMER_H
  14. #include "llvm/ADT/DenseMap.h"
  15. #include "llvm/CodeGen/AsmPrinterHandler.h"
  16. #include "llvm/Support/Compiler.h"
  17. namespace llvm {
  18. class AsmPrinter;
  19. struct LandingPadInfo;
  20. class MachineInstr;
  21. class MachineModuleInfo;
  22. class MCSymbol;
  23. template <typename T> class SmallVectorImpl;
  24. /// Emits exception handling directives.
  25. class LLVM_LIBRARY_VISIBILITY EHStreamer : public AsmPrinterHandler {
  26. protected:
  27. /// Target of directive emission.
  28. AsmPrinter *Asm;
  29. /// Collected machine module information.
  30. MachineModuleInfo *MMI;
  31. /// How many leading type ids two landing pads have in common.
  32. static unsigned sharedTypeIDs(const LandingPadInfo *L,
  33. const LandingPadInfo *R);
  34. /// Structure holding a try-range and the associated landing pad.
  35. struct PadRange {
  36. // The index of the landing pad.
  37. unsigned PadIndex;
  38. // The index of the begin and end labels in the landing pad's label lists.
  39. unsigned RangeIndex;
  40. };
  41. using RangeMapType = DenseMap<MCSymbol *, PadRange>;
  42. /// Structure describing an entry in the actions table.
  43. struct ActionEntry {
  44. int ValueForTypeID; // The value to write - may not be equal to the type id.
  45. int NextAction;
  46. unsigned Previous;
  47. };
  48. /// Structure describing an entry in the call-site table.
  49. struct CallSiteEntry {
  50. // The 'try-range' is BeginLabel .. EndLabel.
  51. MCSymbol *BeginLabel; // Null indicates the start of the function.
  52. MCSymbol *EndLabel; // Null indicates the end of the function.
  53. // LPad contains the landing pad start labels.
  54. const LandingPadInfo *LPad; // Null indicates that there is no landing pad.
  55. unsigned Action;
  56. };
  57. /// Structure describing a contiguous range of call-sites which reside
  58. /// in the same procedure fragment. With -fbasic-block-sections, there will
  59. /// be one call site range per basic block section. Otherwise, we will have
  60. /// one call site range containing all the call sites in the function.
  61. struct CallSiteRange {
  62. // Symbol marking the beginning of the precedure fragment.
  63. MCSymbol *FragmentBeginLabel = nullptr;
  64. // Symbol marking the end of the procedure fragment.
  65. MCSymbol *FragmentEndLabel = nullptr;
  66. // LSDA symbol for this call-site range.
  67. MCSymbol *ExceptionLabel = nullptr;
  68. // Index of the first call-site entry in the call-site table which
  69. // belongs to this range.
  70. size_t CallSiteBeginIdx = 0;
  71. // Index just after the last call-site entry in the call-site table which
  72. // belongs to this range.
  73. size_t CallSiteEndIdx = 0;
  74. // Whether this is the call-site range containing all the landing pads.
  75. bool IsLPRange = false;
  76. };
  77. /// Compute the actions table and gather the first action index for each
  78. /// landing pad site.
  79. void computeActionsTable(
  80. const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
  81. SmallVectorImpl<ActionEntry> &Actions,
  82. SmallVectorImpl<unsigned> &FirstActions);
  83. void computePadMap(const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
  84. RangeMapType &PadMap);
  85. /// Compute the call-site table and the call-site ranges. The entry for an
  86. /// invoke has a try-range containing the call, a non-zero landing pad and an
  87. /// appropriate action. The entry for an ordinary call has a try-range
  88. /// containing the call and zero for the landing pad and the action. Calls
  89. /// marked 'nounwind' have no entry and must not be contained in the try-range
  90. /// of any entry - they form gaps in the table. Entries must be ordered by
  91. /// try-range address. CallSiteRanges vector is only populated for Itanium
  92. /// exception handling.
  93. virtual void computeCallSiteTable(
  94. SmallVectorImpl<CallSiteEntry> &CallSites,
  95. SmallVectorImpl<CallSiteRange> &CallSiteRanges,
  96. const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
  97. const SmallVectorImpl<unsigned> &FirstActions);
  98. /// Emit landing pads and actions.
  99. ///
  100. /// The general organization of the table is complex, but the basic concepts
  101. /// are easy. First there is a header which describes the location and
  102. /// organization of the three components that follow.
  103. /// 1. The landing pad site information describes the range of code covered
  104. /// by the try. In our case it's an accumulation of the ranges covered
  105. /// by the invokes in the try. There is also a reference to the landing
  106. /// pad that handles the exception once processed. Finally an index into
  107. /// the actions table.
  108. /// 2. The action table, in our case, is composed of pairs of type ids
  109. /// and next action offset. Starting with the action index from the
  110. /// landing pad site, each type Id is checked for a match to the current
  111. /// exception. If it matches then the exception and type id are passed
  112. /// on to the landing pad. Otherwise the next action is looked up. This
  113. /// chain is terminated with a next action of zero. If no type id is
  114. /// found the frame is unwound and handling continues.
  115. /// 3. Type id table contains references to all the C++ typeinfo for all
  116. /// catches in the function. This tables is reversed indexed base 1.
  117. ///
  118. /// Returns the starting symbol of an exception table.
  119. MCSymbol *emitExceptionTable();
  120. virtual void emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel);
  121. // Helpers for identifying what kind of clause an EH typeid or selector
  122. // corresponds to. Negative selectors are for filter clauses, the zero
  123. // selector is for cleanups, and positive selectors are for catch clauses.
  124. static bool isFilterEHSelector(int Selector) { return Selector < 0; }
  125. static bool isCleanupEHSelector(int Selector) { return Selector == 0; }
  126. static bool isCatchEHSelector(int Selector) { return Selector > 0; }
  127. public:
  128. EHStreamer(AsmPrinter *A);
  129. ~EHStreamer() override;
  130. // Unused.
  131. void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
  132. void beginInstruction(const MachineInstr *MI) override {}
  133. void endInstruction() override {}
  134. /// Return `true' if this is a call to a function marked `nounwind'. Return
  135. /// `false' otherwise.
  136. static bool callToNoUnwindFunction(const MachineInstr *MI);
  137. };
  138. } // end namespace llvm
  139. #endif // LLVM_LIB_CODEGEN_ASMPRINTER_EHSTREAMER_H