1 //===-- DwarfException.h - Dwarf Exception Framework -----------*- C++ -*--===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains support for writing dwarf exception info into asm files. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H 15 #define LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H 16 17 #include "AsmPrinterHandler.h" 18 #include "llvm/ADT/DenseMap.h" 19 #include "llvm/CodeGen/AsmPrinter.h" 20 #include <vector> 21 22 namespace llvm { 23 24 template <typename T> class SmallVectorImpl; 25 struct LandingPadInfo; 26 class MachineModuleInfo; 27 class MachineInstr; 28 class MachineFunction; 29 class MCAsmInfo; 30 class MCExpr; 31 class MCSymbol; 32 class Function; 33 class ARMTargetStreamer; 34 class AsmPrinter; 35 36 //===----------------------------------------------------------------------===// 37 /// DwarfException - Emits Dwarf exception handling directives. 38 /// 39 class DwarfException : public AsmPrinterHandler { 40 protected: 41 /// Asm - Target of Dwarf emission. 42 AsmPrinter *Asm; 43 44 /// MMI - Collected machine module information. 45 MachineModuleInfo *MMI; 46 47 /// SharedTypeIds - How many leading type ids two landing pads have in common. 48 static unsigned SharedTypeIds(const LandingPadInfo *L, 49 const LandingPadInfo *R); 50 51 /// PadLT - Order landing pads lexicographically by type id. 52 static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R); 53 54 /// PadRange - Structure holding a try-range and the associated landing pad. 55 struct PadRange { 56 // The index of the landing pad. 57 unsigned PadIndex; 58 // The index of the begin and end labels in the landing pad's label lists. 59 unsigned RangeIndex; 60 }; 61 62 typedef DenseMap<MCSymbol *, PadRange> RangeMapType; 63 64 /// ActionEntry - Structure describing an entry in the actions table. 65 struct ActionEntry { 66 int ValueForTypeID; // The value to write - may not be equal to the type id. 67 int NextAction; 68 unsigned Previous; 69 }; 70 71 /// CallSiteEntry - Structure describing an entry in the call-site table. 72 struct CallSiteEntry { 73 // The 'try-range' is BeginLabel .. EndLabel. 74 MCSymbol *BeginLabel; // zero indicates the start of the function. 75 MCSymbol *EndLabel; // zero indicates the end of the function. 76 77 // The landing pad starts at PadLabel. 78 MCSymbol *PadLabel; // zero indicates that there is no landing pad. 79 unsigned Action; 80 }; 81 82 /// ComputeActionsTable - Compute the actions table and gather the first 83 /// action index for each landing pad site. 84 unsigned ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*>&LPs, 85 SmallVectorImpl<ActionEntry> &Actions, 86 SmallVectorImpl<unsigned> &FirstActions); 87 88 /// CallToNoUnwindFunction - Return `true' if this is a call to a function 89 /// marked `nounwind'. Return `false' otherwise. 90 bool CallToNoUnwindFunction(const MachineInstr *MI); 91 92 /// ComputeCallSiteTable - Compute the call-site table. The entry for an 93 /// invoke has a try-range containing the call, a non-zero landing pad and an 94 /// appropriate action. The entry for an ordinary call has a try-range 95 /// containing the call and zero for the landing pad and the action. Calls 96 /// marked 'nounwind' have no entry and must not be contained in the try-range 97 /// of any entry - they form gaps in the table. Entries must be ordered by 98 /// try-range address. 99 void ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, 100 const RangeMapType &PadMap, 101 const SmallVectorImpl<const LandingPadInfo *> &LPs, 102 const SmallVectorImpl<unsigned> &FirstActions); 103 104 /// EmitExceptionTable - Emit landing pads and actions. 105 /// 106 /// The general organization of the table is complex, but the basic concepts 107 /// are easy. First there is a header which describes the location and 108 /// organization of the three components that follow. 109 /// 1. The landing pad site information describes the range of code covered 110 /// by the try. In our case it's an accumulation of the ranges covered 111 /// by the invokes in the try. There is also a reference to the landing 112 /// pad that handles the exception once processed. Finally an index into 113 /// the actions table. 114 /// 2. The action table, in our case, is composed of pairs of type ids 115 /// and next action offset. Starting with the action index from the 116 /// landing pad site, each type Id is checked for a match to the current 117 /// exception. If it matches then the exception and type id are passed 118 /// on to the landing pad. Otherwise the next action is looked up. This 119 /// chain is terminated with a next action of zero. If no type id is 120 /// found the frame is unwound and handling continues. 121 /// 3. Type id table contains references to all the C++ typeinfo for all 122 /// catches in the function. This tables is reversed indexed base 1. 123 void EmitExceptionTable(); 124 125 virtual void EmitTypeInfos(unsigned TTypeEncoding); 126 127 public: 128 //===--------------------------------------------------------------------===// 129 // Main entry points. 130 // 131 DwarfException(AsmPrinter *A); 132 virtual ~DwarfException(); 133 134 /// endModule - Emit all exception information that should come after the 135 /// content. 136 virtual void endModule(); 137 138 /// beginFunction - Gather pre-function exception information. Assumes being 139 /// emitted immediately after the function entry point. 140 virtual void beginFunction(const MachineFunction *MF); 141 142 /// endFunction - Gather and emit post-function exception information. 143 virtual void endFunction(const MachineFunction *); 144 145 // We don't need these. 146 virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) {} 147 virtual void beginInstruction(const MachineInstr *MI) {} 148 virtual void endInstruction() {} 149 }; 150 151 class DwarfCFIException : public DwarfException { 152 /// shouldEmitPersonality - Per-function flag to indicate if .cfi_personality 153 /// should be emitted. 154 bool shouldEmitPersonality; 155 156 /// shouldEmitLSDA - Per-function flag to indicate if .cfi_lsda 157 /// should be emitted. 158 bool shouldEmitLSDA; 159 160 /// shouldEmitMoves - Per-function flag to indicate if frame moves info 161 /// should be emitted. 162 bool shouldEmitMoves; 163 164 AsmPrinter::CFIMoveType moveTypeModule; 165 166 public: 167 //===--------------------------------------------------------------------===// 168 // Main entry points. 169 // 170 DwarfCFIException(AsmPrinter *A); 171 virtual ~DwarfCFIException(); 172 173 /// endModule - Emit all exception information that should come after the 174 /// content. 175 virtual void endModule(); 176 177 /// beginFunction - Gather pre-function exception information. Assumes being 178 /// emitted immediately after the function entry point. 179 virtual void beginFunction(const MachineFunction *MF); 180 181 /// endFunction - Gather and emit post-function exception information. 182 virtual void endFunction(const MachineFunction *); 183 }; 184 185 class ARMException : public DwarfException { 186 void EmitTypeInfos(unsigned TTypeEncoding); 187 ARMTargetStreamer &getTargetStreamer(); 188 189 /// shouldEmitCFI - Per-function flag to indicate if frame CFI info 190 /// should be emitted. 191 bool shouldEmitCFI; 192 193 public: 194 //===--------------------------------------------------------------------===// 195 // Main entry points. 196 // 197 ARMException(AsmPrinter *A); 198 virtual ~ARMException(); 199 200 /// endModule - Emit all exception information that should come after the 201 /// content. 202 virtual void endModule(); 203 204 /// beginFunction - Gather pre-function exception information. Assumes being 205 /// emitted immediately after the function entry point. 206 virtual void beginFunction(const MachineFunction *MF); 207 208 /// endFunction - Gather and emit post-function exception information. 209 virtual void endFunction(const MachineFunction *); 210 }; 211 212 class Win64Exception : public DwarfException { 213 /// shouldEmitPersonality - Per-function flag to indicate if personality 214 /// info should be emitted. 215 bool shouldEmitPersonality; 216 217 /// shouldEmitLSDA - Per-function flag to indicate if the LSDA 218 /// should be emitted. 219 bool shouldEmitLSDA; 220 221 /// shouldEmitMoves - Per-function flag to indicate if frame moves info 222 /// should be emitted. 223 bool shouldEmitMoves; 224 225 public: 226 //===--------------------------------------------------------------------===// 227 // Main entry points. 228 // 229 Win64Exception(AsmPrinter *A); 230 virtual ~Win64Exception(); 231 232 /// endModule - Emit all exception information that should come after the 233 /// content. 234 virtual void endModule(); 235 236 /// beginFunction - Gather pre-function exception information. Assumes being 237 /// emitted immediately after the function entry point. 238 virtual void beginFunction(const MachineFunction *MF); 239 240 /// endFunction - Gather and emit post-function exception information. 241 virtual void endFunction(const MachineFunction *); 242 }; 243 244 } // End of namespace llvm 245 246 #endif 247