LLVM  13.0.0git
WinException.cpp
Go to the documentation of this file.
1 //===-- CodeGen/AsmPrinter/WinException.cpp - Dwarf Exception Impl ------===//
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 Win64 exception info into asm files.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "WinException.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/BinaryFormat/COFF.h"
25 #include "llvm/IR/DataLayout.h"
26 #include "llvm/IR/Mangler.h"
27 #include "llvm/IR/Module.h"
28 #include "llvm/MC/MCAsmInfo.h"
29 #include "llvm/MC/MCContext.h"
30 #include "llvm/MC/MCExpr.h"
31 #include "llvm/MC/MCSection.h"
32 #include "llvm/MC/MCStreamer.h"
33 #include "llvm/MC/MCSymbol.h"
39 using namespace llvm;
40 
42  // MSVC's EH tables are always composed of 32-bit words. All known 64-bit
43  // platforms use an imagerel32 relocation to refer to symbols.
44  useImageRel32 = (A->getDataLayout().getPointerSizeInBits() == 64);
45  isAArch64 = Asm->TM.getTargetTriple().isAArch64();
46 }
47 
49 
50 /// endModule - Emit all exception information that should come after the
51 /// content.
53  auto &OS = *Asm->OutStreamer;
54  const Module *M = MMI->getModule();
55  for (const Function &F : *M)
56  if (F.hasFnAttribute("safeseh"))
57  OS.EmitCOFFSafeSEH(Asm->getSymbol(&F));
58 
59  if (M->getModuleFlag("ehcontguard") && !EHContTargets.empty()) {
60  // Emit the symbol index of each ehcont target.
61  OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGEHContSection());
62  for (const MCSymbol *S : EHContTargets) {
63  OS.EmitCOFFSymbolIndex(S);
64  }
65  }
66 }
67 
69  shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
70 
71  // If any landing pads survive, we need an EH table.
72  bool hasLandingPads = !MF->getLandingPads().empty();
73  bool hasEHFunclets = MF->hasEHFunclets();
74 
75  const Function &F = MF->getFunction();
76 
77  shouldEmitMoves = Asm->needsSEHMoves() && MF->hasWinCFI();
78 
80  unsigned PerEncoding = TLOF.getPersonalityEncoding();
81 
83  const Function *PerFn = nullptr;
84  if (F.hasPersonalityFn()) {
85  PerFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
86  Per = classifyEHPersonality(PerFn);
87  }
88 
89  bool forceEmitPersonality = F.hasPersonalityFn() &&
90  !isNoOpWithoutInvoke(Per) &&
91  F.needsUnwindTableEntry();
92 
93  shouldEmitPersonality =
94  forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
95  PerEncoding != dwarf::DW_EH_PE_omit && PerFn);
96 
97  unsigned LSDAEncoding = TLOF.getLSDAEncoding();
98  shouldEmitLSDA = shouldEmitPersonality &&
99  LSDAEncoding != dwarf::DW_EH_PE_omit;
100 
101  // If we're not using CFI, we don't want the CFI or the personality, but we
102  // might want EH tables if we had EH pads.
103  if (!Asm->MAI->usesWindowsCFI()) {
104  if (Per == EHPersonality::MSVC_X86SEH && !hasEHFunclets) {
105  // If this is 32-bit SEH and we don't have any funclets (really invokes),
106  // make sure we emit the parent offset label. Some unreferenced filter
107  // functions may still refer to it.
108  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
109  StringRef FLinkageName =
111  emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
112  }
113  shouldEmitLSDA = hasEHFunclets;
114  shouldEmitPersonality = false;
115  return;
116  }
117 
119 }
120 
122  if (isAArch64 && CurrentFuncletEntry &&
123  (shouldEmitMoves || shouldEmitPersonality))
124  Asm->OutStreamer->EmitWinCFIFuncletOrFuncEnd();
125 }
126 
127 /// endFunction - Gather and emit post-function exception information.
128 ///
130  if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA)
131  return;
132 
133  const Function &F = MF->getFunction();
135  if (F.hasPersonalityFn())
136  Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts());
137 
138  // Get rid of any dead landing pads if we're not using funclets. In funclet
139  // schemes, the landing pad is not actually reachable. It only exists so
140  // that we can emit the right table data.
141  if (!isFuncletEHPersonality(Per)) {
142  MachineFunction *NonConstMF = const_cast<MachineFunction*>(MF);
143  NonConstMF->tidyLandingPads();
144  }
145 
146  endFuncletImpl();
147 
148  // endFunclet will emit the necessary .xdata tables for table-based SEH.
149  if (Per == EHPersonality::MSVC_TableSEH && MF->hasEHFunclets())
150  return;
151 
152  if (shouldEmitPersonality || shouldEmitLSDA) {
153  Asm->OutStreamer->PushSection();
154 
155  // Just switch sections to the right xdata section.
156  MCSection *XData = Asm->OutStreamer->getAssociatedXDataSection(
157  Asm->OutStreamer->getCurrentSectionOnly());
158  Asm->OutStreamer->SwitchSection(XData);
159 
160  // Emit the tables appropriate to the personality function in use. If we
161  // don't recognize the personality, assume it uses an Itanium-style LSDA.
162  if (Per == EHPersonality::MSVC_TableSEH)
163  emitCSpecificHandlerTable(MF);
164  else if (Per == EHPersonality::MSVC_X86SEH)
165  emitExceptHandlerTable(MF);
166  else if (Per == EHPersonality::MSVC_CXX)
167  emitCXXFrameHandler3Table(MF);
168  else if (Per == EHPersonality::CoreCLR)
169  emitCLRExceptionTable(MF);
170  else
172 
173  Asm->OutStreamer->PopSection();
174  }
175 
176  if (!MF->getCatchretTargets().empty()) {
177  // Copy the function's catchret targets to a module-level list.
178  EHContTargets.insert(EHContTargets.end(), MF->getCatchretTargets().begin(),
179  MF->getCatchretTargets().end());
180  }
181 }
182 
183 /// Retrieve the MCSymbol for a GlobalValue or MachineBasicBlock.
185  const MachineBasicBlock *MBB) {
186  if (!MBB)
187  return nullptr;
188 
190 
191  // Give catches and cleanups a name based off of their parent function and
192  // their funclet entry block's number.
193  const MachineFunction *MF = MBB->getParent();
194  const Function &F = MF->getFunction();
195  StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
196  MCContext &Ctx = MF->getContext();
197  StringRef HandlerPrefix = MBB->isCleanupFuncletEntry() ? "dtor" : "catch";
198  return Ctx.getOrCreateSymbol("?" + HandlerPrefix + "$" +
199  Twine(MBB->getNumber()) + "@?0?" +
200  FuncLinkageName + "@4HA");
201 }
202 
204  MCSymbol *Sym) {
205  CurrentFuncletEntry = &MBB;
206 
207  const Function &F = Asm->MF->getFunction();
208  // If a symbol was not provided for the funclet, invent one.
209  if (!Sym) {
210  Sym = getMCSymbolForMBB(Asm, &MBB);
211 
212  // Describe our funclet symbol as a function with internal linkage.
213  Asm->OutStreamer->BeginCOFFSymbolDef(Sym);
214  Asm->OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
215  Asm->OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
217  Asm->OutStreamer->EndCOFFSymbolDef();
218 
219  // We want our funclet's entry point to be aligned such that no nops will be
220  // present after the label.
222  &F);
223 
224  // Now that we've emitted the alignment directive, point at our funclet.
225  Asm->OutStreamer->emitLabel(Sym);
226  }
227 
228  // Mark 'Sym' as starting our funclet.
229  if (shouldEmitMoves || shouldEmitPersonality) {
230  CurrentFuncletTextSection = Asm->OutStreamer->getCurrentSectionOnly();
231  Asm->OutStreamer->EmitWinCFIStartProc(Sym);
232  }
233 
234  if (shouldEmitPersonality) {
236  const Function *PerFn = nullptr;
237 
238  // Determine which personality routine we are using for this funclet.
239  if (F.hasPersonalityFn())
240  PerFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
241  const MCSymbol *PersHandlerSym =
242  TLOF.getCFIPersonalitySymbol(PerFn, Asm->TM, MMI);
243 
244  // Do not emit a .seh_handler directives for cleanup funclets.
245  // FIXME: This means cleanup funclets cannot handle exceptions. Given that
246  // Clang doesn't produce EH constructs inside cleanup funclets and LLVM's
247  // inliner doesn't allow inlining them, this isn't a major problem in
248  // practice.
249  if (!CurrentFuncletEntry->isCleanupFuncletEntry())
250  Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true);
251  }
252 }
253 
255  if (isAArch64 && CurrentFuncletEntry &&
256  (shouldEmitMoves || shouldEmitPersonality)) {
257  Asm->OutStreamer->SwitchSection(CurrentFuncletTextSection);
258  Asm->OutStreamer->EmitWinCFIFuncletOrFuncEnd();
259  }
260  endFuncletImpl();
261 }
262 
263 void WinException::endFuncletImpl() {
264  // No funclet to process? Great, we have nothing to do.
265  if (!CurrentFuncletEntry)
266  return;
267 
268  const MachineFunction *MF = Asm->MF;
269  if (shouldEmitMoves || shouldEmitPersonality) {
270  const Function &F = MF->getFunction();
272  if (F.hasPersonalityFn())
273  Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts());
274 
275  if (Per == EHPersonality::MSVC_CXX && shouldEmitPersonality &&
276  !CurrentFuncletEntry->isCleanupFuncletEntry()) {
277  // Emit an UNWIND_INFO struct describing the prologue.
278  Asm->OutStreamer->EmitWinEHHandlerData();
279 
280  // If this is a C++ catch funclet (or the parent function),
281  // emit a reference to the LSDA for the parent function.
282  StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
283  MCSymbol *FuncInfoXData = Asm->OutContext.getOrCreateSymbol(
284  Twine("$cppxdata$", FuncLinkageName));
285  Asm->OutStreamer->emitValue(create32bitRef(FuncInfoXData), 4);
286  } else if (Per == EHPersonality::MSVC_TableSEH && MF->hasEHFunclets() &&
287  !CurrentFuncletEntry->isEHFuncletEntry()) {
288  // Emit an UNWIND_INFO struct describing the prologue.
289  Asm->OutStreamer->EmitWinEHHandlerData();
290 
291  // If this is the parent function in Win64 SEH, emit the LSDA immediately
292  // following .seh_handlerdata.
293  emitCSpecificHandlerTable(MF);
294  } else if (shouldEmitPersonality || shouldEmitLSDA) {
295  // Emit an UNWIND_INFO struct describing the prologue.
296  Asm->OutStreamer->EmitWinEHHandlerData();
297  // In these cases, no further info is written to the .xdata section
298  // right here, but is written by e.g. emitExceptionTable in endFunction()
299  // above.
300  } else {
301  // No need to emit the EH handler data right here if nothing needs
302  // writing to the .xdata section; it will be emitted for all
303  // functions that need it in the end anyway.
304  }
305 
306  // Switch back to the funclet start .text section now that we are done
307  // writing to .xdata, and emit an .seh_endproc directive to mark the end of
308  // the function.
309  Asm->OutStreamer->SwitchSection(CurrentFuncletTextSection);
310  Asm->OutStreamer->EmitWinCFIEndProc();
311  }
312 
313  // Let's make sure we don't try to end the same funclet twice.
314  CurrentFuncletEntry = nullptr;
315 }
316 
317 const MCExpr *WinException::create32bitRef(const MCSymbol *Value) {
318  if (!Value)
320  return MCSymbolRefExpr::create(Value, useImageRel32
323  Asm->OutContext);
324 }
325 
326 const MCExpr *WinException::create32bitRef(const GlobalValue *GV) {
327  if (!GV)
329  return create32bitRef(Asm->getSymbol(GV));
330 }
331 
332 const MCExpr *WinException::getLabel(const MCSymbol *Label) {
333  if (isAArch64)
335  Asm->OutContext);
336  return MCBinaryExpr::createAdd(create32bitRef(Label),
338  Asm->OutContext);
339 }
340 
341 const MCExpr *WinException::getOffset(const MCSymbol *OffsetOf,
342  const MCSymbol *OffsetFrom) {
346 }
347 
348 const MCExpr *WinException::getOffsetPlusOne(const MCSymbol *OffsetOf,
349  const MCSymbol *OffsetFrom) {
350  return MCBinaryExpr::createAdd(getOffset(OffsetOf, OffsetFrom),
352  Asm->OutContext);
353 }
354 
355 int WinException::getFrameIndexOffset(int FrameIndex,
356  const WinEHFuncInfo &FuncInfo) {
358  Register UnusedReg;
359  if (Asm->MAI->usesWindowsCFI()) {
362  /*IgnoreSPUpdates*/ true);
363  assert(UnusedReg ==
364  Asm->MF->getSubtarget()
367  return Offset.getFixed();
368  }
369 
370  // For 32-bit, offsets should be relative to the end of the EH registration
371  // node. For 64-bit, it's relative to SP at the end of the prologue.
372  assert(FuncInfo.EHRegNodeEndOffset != INT_MAX);
375  assert(!Offset.getScalable() &&
376  "Frame offsets with a scalable component are not supported");
377  return Offset.getFixed();
378 }
379 
380 namespace {
381 
382 /// Top-level state used to represent unwind to caller
383 const int NullState = -1;
384 
385 struct InvokeStateChange {
386  /// EH Label immediately after the last invoke in the previous state, or
387  /// nullptr if the previous state was the null state.
388  const MCSymbol *PreviousEndLabel;
389 
390  /// EH label immediately before the first invoke in the new state, or nullptr
391  /// if the new state is the null state.
392  const MCSymbol *NewStartLabel;
393 
394  /// State of the invoke following NewStartLabel, or NullState to indicate
395  /// the presence of calls which may unwind to caller.
396  int NewState;
397 };
398 
399 /// Iterator that reports all the invoke state changes in a range of machine
400 /// basic blocks. Changes to the null state are reported whenever a call that
401 /// may unwind to caller is encountered. The MBB range is expected to be an
402 /// entire function or funclet, and the start and end of the range are treated
403 /// as being in the NullState even if there's not an unwind-to-caller call
404 /// before the first invoke or after the last one (i.e., the first state change
405 /// reported is the first change to something other than NullState, and a
406 /// change back to NullState is always reported at the end of iteration).
407 class InvokeStateChangeIterator {
408  InvokeStateChangeIterator(const WinEHFuncInfo &EHInfo,
412  int BaseState)
413  : EHInfo(EHInfo), MFI(MFI), MFE(MFE), MBBI(MBBI), BaseState(BaseState) {
414  LastStateChange.PreviousEndLabel = nullptr;
415  LastStateChange.NewStartLabel = nullptr;
416  LastStateChange.NewState = BaseState;
417  scan();
418  }
419 
420 public:
422  range(const WinEHFuncInfo &EHInfo, MachineFunction::const_iterator Begin,
423  MachineFunction::const_iterator End, int BaseState = NullState) {
424  // Reject empty ranges to simplify bookkeeping by ensuring that we can get
425  // the end of the last block.
426  assert(Begin != End);
427  auto BlockBegin = Begin->begin();
428  auto BlockEnd = std::prev(End)->end();
429  return make_range(
430  InvokeStateChangeIterator(EHInfo, Begin, End, BlockBegin, BaseState),
431  InvokeStateChangeIterator(EHInfo, End, End, BlockEnd, BaseState));
432  }
433 
434  // Iterator methods.
435  bool operator==(const InvokeStateChangeIterator &O) const {
436  assert(BaseState == O.BaseState);
437  // Must be visiting same block.
438  if (MFI != O.MFI)
439  return false;
440  // Must be visiting same isntr.
441  if (MBBI != O.MBBI)
442  return false;
443  // At end of block/instr iteration, we can still have two distinct states:
444  // one to report the final EndLabel, and another indicating the end of the
445  // state change iteration. Check for CurrentEndLabel equality to
446  // distinguish these.
447  return CurrentEndLabel == O.CurrentEndLabel;
448  }
449 
450  bool operator!=(const InvokeStateChangeIterator &O) const {
451  return !operator==(O);
452  }
453  InvokeStateChange &operator*() { return LastStateChange; }
454  InvokeStateChange *operator->() { return &LastStateChange; }
455  InvokeStateChangeIterator &operator++() { return scan(); }
456 
457 private:
458  InvokeStateChangeIterator &scan();
459 
460  const WinEHFuncInfo &EHInfo;
461  const MCSymbol *CurrentEndLabel = nullptr;
465  InvokeStateChange LastStateChange;
466  bool VisitingInvoke = false;
467  int BaseState;
468 };
469 
470 } // end anonymous namespace
471 
472 InvokeStateChangeIterator &InvokeStateChangeIterator::scan() {
473  bool IsNewBlock = false;
474  for (; MFI != MFE; ++MFI, IsNewBlock = true) {
475  if (IsNewBlock)
476  MBBI = MFI->begin();
477  for (auto MBBE = MFI->end(); MBBI != MBBE; ++MBBI) {
478  const MachineInstr &MI = *MBBI;
479  if (!VisitingInvoke && LastStateChange.NewState != BaseState &&
480  MI.isCall() && !EHStreamer::callToNoUnwindFunction(&MI)) {
481  // Indicate a change of state to the null state. We don't have
482  // start/end EH labels handy but the caller won't expect them for
483  // null state regions.
484  LastStateChange.PreviousEndLabel = CurrentEndLabel;
485  LastStateChange.NewStartLabel = nullptr;
486  LastStateChange.NewState = BaseState;
487  CurrentEndLabel = nullptr;
488  // Don't re-visit this instr on the next scan
489  ++MBBI;
490  return *this;
491  }
492 
493  // All other state changes are at EH labels before/after invokes.
494  if (!MI.isEHLabel())
495  continue;
496  MCSymbol *Label = MI.getOperand(0).getMCSymbol();
497  if (Label == CurrentEndLabel) {
498  VisitingInvoke = false;
499  continue;
500  }
501  auto InvokeMapIter = EHInfo.LabelToStateMap.find(Label);
502  // Ignore EH labels that aren't the ones inserted before an invoke
503  if (InvokeMapIter == EHInfo.LabelToStateMap.end())
504  continue;
505  auto &StateAndEnd = InvokeMapIter->second;
506  int NewState = StateAndEnd.first;
507  // Keep track of the fact that we're between EH start/end labels so
508  // we know not to treat the inoke we'll see as unwinding to caller.
509  VisitingInvoke = true;
510  if (NewState == LastStateChange.NewState) {
511  // The state isn't actually changing here. Record the new end and
512  // keep going.
513  CurrentEndLabel = StateAndEnd.second;
514  continue;
515  }
516  // Found a state change to report
517  LastStateChange.PreviousEndLabel = CurrentEndLabel;
518  LastStateChange.NewStartLabel = Label;
519  LastStateChange.NewState = NewState;
520  // Start keeping track of the new current end
521  CurrentEndLabel = StateAndEnd.second;
522  // Don't re-visit this instr on the next scan
523  ++MBBI;
524  return *this;
525  }
526  }
527  // Iteration hit the end of the block range.
528  if (LastStateChange.NewState != BaseState) {
529  // Report the end of the last new state
530  LastStateChange.PreviousEndLabel = CurrentEndLabel;
531  LastStateChange.NewStartLabel = nullptr;
532  LastStateChange.NewState = BaseState;
533  // Leave CurrentEndLabel non-null to distinguish this state from end.
534  assert(CurrentEndLabel != nullptr);
535  return *this;
536  }
537  // We've reported all state changes and hit the end state.
538  CurrentEndLabel = nullptr;
539  return *this;
540 }
541 
542 /// Emit the language-specific data that __C_specific_handler expects. This
543 /// handler lives in the x64 Microsoft C runtime and allows catching or cleaning
544 /// up after faults with __try, __except, and __finally. The typeinfo values
545 /// are not really RTTI data, but pointers to filter functions that return an
546 /// integer (1, 0, or -1) indicating how to handle the exception. For __finally
547 /// blocks and other cleanups, the landing pad label is zero, and the filter
548 /// function is actually a cleanup handler with the same prototype. A catch-all
549 /// entry is modeled with a null filter function field and a non-zero landing
550 /// pad label.
551 ///
552 /// Possible filter function return values:
553 /// EXCEPTION_EXECUTE_HANDLER (1):
554 /// Jump to the landing pad label after cleanups.
555 /// EXCEPTION_CONTINUE_SEARCH (0):
556 /// Continue searching this table or continue unwinding.
557 /// EXCEPTION_CONTINUE_EXECUTION (-1):
558 /// Resume execution at the trapping PC.
559 ///
560 /// Inferred table structure:
561 /// struct Table {
562 /// int NumEntries;
563 /// struct Entry {
564 /// imagerel32 LabelStart;
565 /// imagerel32 LabelEnd;
566 /// imagerel32 FilterOrFinally; // One means catch-all.
567 /// imagerel32 LabelLPad; // Zero means __finally.
568 /// } Entries[NumEntries];
569 /// };
570 void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
571  auto &OS = *Asm->OutStreamer;
572  MCContext &Ctx = Asm->OutContext;
573  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
574 
575  bool VerboseAsm = OS.isVerboseAsm();
576  auto AddComment = [&](const Twine &Comment) {
577  if (VerboseAsm)
578  OS.AddComment(Comment);
579  };
580 
581  if (!isAArch64) {
582  // Emit a label assignment with the SEH frame offset so we can use it for
583  // llvm.eh.recoverfp.
584  StringRef FLinkageName =
586  MCSymbol *ParentFrameOffset =
587  Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName);
588  const MCExpr *MCOffset =
590  Asm->OutStreamer->emitAssignment(ParentFrameOffset, MCOffset);
591  }
592 
593  // Use the assembler to compute the number of table entries through label
594  // difference and division.
595  MCSymbol *TableBegin =
596  Ctx.createTempSymbol("lsda_begin", /*AlwaysAddSuffix=*/true);
597  MCSymbol *TableEnd =
598  Ctx.createTempSymbol("lsda_end", /*AlwaysAddSuffix=*/true);
599  const MCExpr *LabelDiff = getOffset(TableEnd, TableBegin);
600  const MCExpr *EntrySize = MCConstantExpr::create(16, Ctx);
601  const MCExpr *EntryCount = MCBinaryExpr::createDiv(LabelDiff, EntrySize, Ctx);
602  AddComment("Number of call sites");
603  OS.emitValue(EntryCount, 4);
604 
605  OS.emitLabel(TableBegin);
606 
607  // Iterate over all the invoke try ranges. Unlike MSVC, LLVM currently only
608  // models exceptions from invokes. LLVM also allows arbitrary reordering of
609  // the code, so our tables end up looking a bit different. Rather than
610  // trying to match MSVC's tables exactly, we emit a denormalized table. For
611  // each range of invokes in the same state, we emit table entries for all
612  // the actions that would be taken in that state. This means our tables are
613  // slightly bigger, which is OK.
614  const MCSymbol *LastStartLabel = nullptr;
615  int LastEHState = -1;
616  // Break out before we enter into a finally funclet.
617  // FIXME: We need to emit separate EH tables for cleanups.
619  MachineFunction::const_iterator Stop = std::next(MF->begin());
620  while (Stop != End && !Stop->isEHFuncletEntry())
621  ++Stop;
622  for (const auto &StateChange :
623  InvokeStateChangeIterator::range(FuncInfo, MF->begin(), Stop)) {
624  // Emit all the actions for the state we just transitioned out of
625  // if it was not the null state
626  if (LastEHState != -1)
627  emitSEHActionsForRange(FuncInfo, LastStartLabel,
628  StateChange.PreviousEndLabel, LastEHState);
629  LastStartLabel = StateChange.NewStartLabel;
630  LastEHState = StateChange.NewState;
631  }
632 
633  OS.emitLabel(TableEnd);
634 }
635 
636 void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
637  const MCSymbol *BeginLabel,
638  const MCSymbol *EndLabel, int State) {
639  auto &OS = *Asm->OutStreamer;
640  MCContext &Ctx = Asm->OutContext;
641  bool VerboseAsm = OS.isVerboseAsm();
642  auto AddComment = [&](const Twine &Comment) {
643  if (VerboseAsm)
644  OS.AddComment(Comment);
645  };
646 
647  assert(BeginLabel && EndLabel);
648  while (State != -1) {
649  const SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
650  const MCExpr *FilterOrFinally;
651  const MCExpr *ExceptOrNull;
652  auto *Handler = UME.Handler.get<MachineBasicBlock *>();
653  if (UME.IsFinally) {
654  FilterOrFinally = create32bitRef(getMCSymbolForMBB(Asm, Handler));
655  ExceptOrNull = MCConstantExpr::create(0, Ctx);
656  } else {
657  // For an except, the filter can be 1 (catch-all) or a function
658  // label.
659  FilterOrFinally = UME.Filter ? create32bitRef(UME.Filter)
660  : MCConstantExpr::create(1, Ctx);
661  ExceptOrNull = create32bitRef(Handler->getSymbol());
662  }
663 
664  AddComment("LabelStart");
665  OS.emitValue(getLabel(BeginLabel), 4);
666  AddComment("LabelEnd");
667  OS.emitValue(getLabel(EndLabel), 4);
668  AddComment(UME.IsFinally ? "FinallyFunclet" : UME.Filter ? "FilterFunction"
669  : "CatchAll");
670  OS.emitValue(FilterOrFinally, 4);
671  AddComment(UME.IsFinally ? "Null" : "ExceptionHandler");
672  OS.emitValue(ExceptOrNull, 4);
673 
674  assert(UME.ToState < State && "states should decrease");
675  State = UME.ToState;
676  }
677 }
678 
679 void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
680  const Function &F = MF->getFunction();
681  auto &OS = *Asm->OutStreamer;
682  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
683 
684  StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
685 
687  MCSymbol *FuncInfoXData = nullptr;
688  if (shouldEmitPersonality) {
689  // If we're 64-bit, emit a pointer to the C++ EH data, and build a map from
690  // IPs to state numbers.
691  FuncInfoXData =
692  Asm->OutContext.getOrCreateSymbol(Twine("$cppxdata$", FuncLinkageName));
693  computeIP2StateTable(MF, FuncInfo, IPToStateTable);
694  } else {
695  FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(FuncLinkageName);
696  }
697 
698  int UnwindHelpOffset = 0;
699  if (Asm->MAI->usesWindowsCFI())
700  UnwindHelpOffset =
701  getFrameIndexOffset(FuncInfo.UnwindHelpFrameIdx, FuncInfo);
702 
703  MCSymbol *UnwindMapXData = nullptr;
704  MCSymbol *TryBlockMapXData = nullptr;
705  MCSymbol *IPToStateXData = nullptr;
706  if (!FuncInfo.CxxUnwindMap.empty())
707  UnwindMapXData = Asm->OutContext.getOrCreateSymbol(
708  Twine("$stateUnwindMap$", FuncLinkageName));
709  if (!FuncInfo.TryBlockMap.empty())
710  TryBlockMapXData =
711  Asm->OutContext.getOrCreateSymbol(Twine("$tryMap$", FuncLinkageName));
712  if (!IPToStateTable.empty())
713  IPToStateXData =
714  Asm->OutContext.getOrCreateSymbol(Twine("$ip2state$", FuncLinkageName));
715 
716  bool VerboseAsm = OS.isVerboseAsm();
717  auto AddComment = [&](const Twine &Comment) {
718  if (VerboseAsm)
719  OS.AddComment(Comment);
720  };
721 
722  // FuncInfo {
723  // uint32_t MagicNumber
724  // int32_t MaxState;
725  // UnwindMapEntry *UnwindMap;
726  // uint32_t NumTryBlocks;
727  // TryBlockMapEntry *TryBlockMap;
728  // uint32_t IPMapEntries; // always 0 for x86
729  // IPToStateMapEntry *IPToStateMap; // always 0 for x86
730  // uint32_t UnwindHelp; // non-x86 only
731  // ESTypeList *ESTypeList;
732  // int32_t EHFlags;
733  // }
734  // EHFlags & 1 -> Synchronous exceptions only, no async exceptions.
735  // EHFlags & 2 -> ???
736  // EHFlags & 4 -> The function is noexcept(true), unwinding can't continue.
737  OS.emitValueToAlignment(4);
738  OS.emitLabel(FuncInfoXData);
739 
740  AddComment("MagicNumber");
741  OS.emitInt32(0x19930522);
742 
743  AddComment("MaxState");
744  OS.emitInt32(FuncInfo.CxxUnwindMap.size());
745 
746  AddComment("UnwindMap");
747  OS.emitValue(create32bitRef(UnwindMapXData), 4);
748 
749  AddComment("NumTryBlocks");
750  OS.emitInt32(FuncInfo.TryBlockMap.size());
751 
752  AddComment("TryBlockMap");
753  OS.emitValue(create32bitRef(TryBlockMapXData), 4);
754 
755  AddComment("IPMapEntries");
756  OS.emitInt32(IPToStateTable.size());
757 
758  AddComment("IPToStateXData");
759  OS.emitValue(create32bitRef(IPToStateXData), 4);
760 
761  if (Asm->MAI->usesWindowsCFI()) {
762  AddComment("UnwindHelp");
763  OS.emitInt32(UnwindHelpOffset);
764  }
765 
766  AddComment("ESTypeList");
767  OS.emitInt32(0);
768 
769  AddComment("EHFlags");
770  OS.emitInt32(1);
771 
772  // UnwindMapEntry {
773  // int32_t ToState;
774  // void (*Action)();
775  // };
776  if (UnwindMapXData) {
777  OS.emitLabel(UnwindMapXData);
778  for (const CxxUnwindMapEntry &UME : FuncInfo.CxxUnwindMap) {
779  MCSymbol *CleanupSym =
781  AddComment("ToState");
782  OS.emitInt32(UME.ToState);
783 
784  AddComment("Action");
785  OS.emitValue(create32bitRef(CleanupSym), 4);
786  }
787  }
788 
789  // TryBlockMap {
790  // int32_t TryLow;
791  // int32_t TryHigh;
792  // int32_t CatchHigh;
793  // int32_t NumCatches;
794  // HandlerType *HandlerArray;
795  // };
796  if (TryBlockMapXData) {
797  OS.emitLabel(TryBlockMapXData);
798  SmallVector<MCSymbol *, 1> HandlerMaps;
799  for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
800  const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
801 
802  MCSymbol *HandlerMapXData = nullptr;
803  if (!TBME.HandlerArray.empty())
804  HandlerMapXData =
805  Asm->OutContext.getOrCreateSymbol(Twine("$handlerMap$")
806  .concat(Twine(I))
807  .concat("$")
808  .concat(FuncLinkageName));
809  HandlerMaps.push_back(HandlerMapXData);
810 
811  // TBMEs should form intervals.
812  assert(0 <= TBME.TryLow && "bad trymap interval");
813  assert(TBME.TryLow <= TBME.TryHigh && "bad trymap interval");
814  assert(TBME.TryHigh < TBME.CatchHigh && "bad trymap interval");
815  assert(TBME.CatchHigh < int(FuncInfo.CxxUnwindMap.size()) &&
816  "bad trymap interval");
817 
818  AddComment("TryLow");
819  OS.emitInt32(TBME.TryLow);
820 
821  AddComment("TryHigh");
822  OS.emitInt32(TBME.TryHigh);
823 
824  AddComment("CatchHigh");
825  OS.emitInt32(TBME.CatchHigh);
826 
827  AddComment("NumCatches");
828  OS.emitInt32(TBME.HandlerArray.size());
829 
830  AddComment("HandlerArray");
831  OS.emitValue(create32bitRef(HandlerMapXData), 4);
832  }
833 
834  // All funclets use the same parent frame offset currently.
835  unsigned ParentFrameOffset = 0;
836  if (shouldEmitPersonality) {
838  ParentFrameOffset = TFI->getWinEHParentFrameOffset(*MF);
839  }
840 
841  for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
842  const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
843  MCSymbol *HandlerMapXData = HandlerMaps[I];
844  if (!HandlerMapXData)
845  continue;
846  // HandlerType {
847  // int32_t Adjectives;
848  // TypeDescriptor *Type;
849  // int32_t CatchObjOffset;
850  // void (*Handler)();
851  // int32_t ParentFrameOffset; // x64 and AArch64 only
852  // };
853  OS.emitLabel(HandlerMapXData);
854  for (const WinEHHandlerType &HT : TBME.HandlerArray) {
855  // Get the frame escape label with the offset of the catch object. If
856  // the index is INT_MAX, then there is no catch object, and we should
857  // emit an offset of zero, indicating that no copy will occur.
858  const MCExpr *FrameAllocOffsetRef = nullptr;
859  if (HT.CatchObj.FrameIndex != INT_MAX) {
860  int Offset = getFrameIndexOffset(HT.CatchObj.FrameIndex, FuncInfo);
861  assert(Offset != 0 && "Illegal offset for catch object!");
862  FrameAllocOffsetRef = MCConstantExpr::create(Offset, Asm->OutContext);
863  } else {
864  FrameAllocOffsetRef = MCConstantExpr::create(0, Asm->OutContext);
865  }
866 
867  MCSymbol *HandlerSym =
869 
870  AddComment("Adjectives");
871  OS.emitInt32(HT.Adjectives);
872 
873  AddComment("Type");
874  OS.emitValue(create32bitRef(HT.TypeDescriptor), 4);
875 
876  AddComment("CatchObjOffset");
877  OS.emitValue(FrameAllocOffsetRef, 4);
878 
879  AddComment("Handler");
880  OS.emitValue(create32bitRef(HandlerSym), 4);
881 
882  if (shouldEmitPersonality) {
883  AddComment("ParentFrameOffset");
884  OS.emitInt32(ParentFrameOffset);
885  }
886  }
887  }
888  }
889 
890  // IPToStateMapEntry {
891  // void *IP;
892  // int32_t State;
893  // };
894  if (IPToStateXData) {
895  OS.emitLabel(IPToStateXData);
896  for (auto &IPStatePair : IPToStateTable) {
897  AddComment("IP");
898  OS.emitValue(IPStatePair.first, 4);
899  AddComment("ToState");
900  OS.emitInt32(IPStatePair.second);
901  }
902  }
903 }
904 
905 void WinException::computeIP2StateTable(
906  const MachineFunction *MF, const WinEHFuncInfo &FuncInfo,
907  SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable) {
908 
909  for (MachineFunction::const_iterator FuncletStart = MF->begin(),
910  FuncletEnd = MF->begin(),
911  End = MF->end();
912  FuncletStart != End; FuncletStart = FuncletEnd) {
913  // Find the end of the funclet
914  while (++FuncletEnd != End) {
915  if (FuncletEnd->isEHFuncletEntry()) {
916  break;
917  }
918  }
919 
920  // Don't emit ip2state entries for cleanup funclets. Any interesting
921  // exceptional actions in cleanups must be handled in a separate IR
922  // function.
923  if (FuncletStart->isCleanupFuncletEntry())
924  continue;
925 
926  MCSymbol *StartLabel;
927  int BaseState;
928  if (FuncletStart == MF->begin()) {
929  BaseState = NullState;
930  StartLabel = Asm->getFunctionBegin();
931  } else {
932  auto *FuncletPad =
933  cast<FuncletPadInst>(FuncletStart->getBasicBlock()->getFirstNonPHI());
934  assert(FuncInfo.FuncletBaseStateMap.count(FuncletPad) != 0);
935  BaseState = FuncInfo.FuncletBaseStateMap.find(FuncletPad)->second;
936  StartLabel = getMCSymbolForMBB(Asm, &*FuncletStart);
937  }
938  assert(StartLabel && "need local function start label");
939  IPToStateTable.push_back(
940  std::make_pair(create32bitRef(StartLabel), BaseState));
941 
942  for (const auto &StateChange : InvokeStateChangeIterator::range(
943  FuncInfo, FuncletStart, FuncletEnd, BaseState)) {
944  // Compute the label to report as the start of this entry; use the EH
945  // start label for the invoke if we have one, otherwise (this is a call
946  // which may unwind to our caller and does not have an EH start label, so)
947  // use the previous end label.
948  const MCSymbol *ChangeLabel = StateChange.NewStartLabel;
949  if (!ChangeLabel)
950  ChangeLabel = StateChange.PreviousEndLabel;
951  // Emit an entry indicating that PCs after 'Label' have this EH state.
952  IPToStateTable.push_back(
953  std::make_pair(getLabel(ChangeLabel), StateChange.NewState));
954  // FIXME: assert that NewState is between CatchLow and CatchHigh.
955  }
956  }
957 }
958 
959 void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
960  StringRef FLinkageName) {
961  // Outlined helpers called by the EH runtime need to know the offset of the EH
962  // registration in order to recover the parent frame pointer. Now that we know
963  // we've code generated the parent, we can emit the label assignment that
964  // those helpers use to get the offset of the registration node.
965 
966  // Compute the parent frame offset. The EHRegNodeFrameIndex will be invalid if
967  // after optimization all the invokes were eliminated. We still need to emit
968  // the parent frame offset label, but it should be garbage and should never be
969  // used.
970  int64_t Offset = 0;
971  int FI = FuncInfo.EHRegNodeFrameIndex;
972  if (FI != INT_MAX) {
975  }
976 
977  MCContext &Ctx = Asm->OutContext;
978  MCSymbol *ParentFrameOffset =
979  Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName);
980  Asm->OutStreamer->emitAssignment(ParentFrameOffset,
982 }
983 
984 /// Emit the language-specific data that _except_handler3 and 4 expect. This is
985 /// functionally equivalent to the __C_specific_handler table, except it is
986 /// indexed by state number instead of IP.
987 void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
988  MCStreamer &OS = *Asm->OutStreamer;
989  const Function &F = MF->getFunction();
990  StringRef FLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
991 
992  bool VerboseAsm = OS.isVerboseAsm();
993  auto AddComment = [&](const Twine &Comment) {
994  if (VerboseAsm)
995  OS.AddComment(Comment);
996  };
997 
998  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
999  emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
1000 
1001  // Emit the __ehtable label that we use for llvm.x86.seh.lsda.
1002  MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName);
1003  OS.emitValueToAlignment(4);
1004  OS.emitLabel(LSDALabel);
1005 
1006  const auto *Per = cast<Function>(F.getPersonalityFn()->stripPointerCasts());
1007  StringRef PerName = Per->getName();
1008  int BaseState = -1;
1009  if (PerName == "_except_handler4") {
1010  // The LSDA for _except_handler4 starts with this struct, followed by the
1011  // scope table:
1012  //
1013  // struct EH4ScopeTable {
1014  // int32_t GSCookieOffset;
1015  // int32_t GSCookieXOROffset;
1016  // int32_t EHCookieOffset;
1017  // int32_t EHCookieXOROffset;
1018  // ScopeTableEntry ScopeRecord[];
1019  // };
1020  //
1021  // Offsets are %ebp relative.
1022  //
1023  // The GS cookie is present only if the function needs stack protection.
1024  // GSCookieOffset = -2 means that GS cookie is not used.
1025  //
1026  // The EH cookie is always present.
1027  //
1028  // Check is done the following way:
1029  // (ebp+CookieXOROffset) ^ [ebp+CookieOffset] == _security_cookie
1030 
1031  // Retrieve the Guard Stack slot.
1032  int GSCookieOffset = -2;
1033  const MachineFrameInfo &MFI = MF->getFrameInfo();
1034  if (MFI.hasStackProtectorIndex()) {
1035  Register UnusedReg;
1036  const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
1037  int SSPIdx = MFI.getStackProtectorIndex();
1038  GSCookieOffset =
1039  TFI->getFrameIndexReference(*MF, SSPIdx, UnusedReg).getFixed();
1040  }
1041 
1042  // Retrieve the EH Guard slot.
1043  // TODO(etienneb): Get rid of this value and change it for and assertion.
1044  int EHCookieOffset = 9999;
1045  if (FuncInfo.EHGuardFrameIndex != INT_MAX) {
1046  Register UnusedReg;
1047  const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
1048  int EHGuardIdx = FuncInfo.EHGuardFrameIndex;
1049  EHCookieOffset =
1050  TFI->getFrameIndexReference(*MF, EHGuardIdx, UnusedReg).getFixed();
1051  }
1052 
1053  AddComment("GSCookieOffset");
1054  OS.emitInt32(GSCookieOffset);
1055  AddComment("GSCookieXOROffset");
1056  OS.emitInt32(0);
1057  AddComment("EHCookieOffset");
1058  OS.emitInt32(EHCookieOffset);
1059  AddComment("EHCookieXOROffset");
1060  OS.emitInt32(0);
1061  BaseState = -2;
1062  }
1063 
1064  assert(!FuncInfo.SEHUnwindMap.empty());
1065  for (const SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
1066  auto *Handler = UME.Handler.get<MachineBasicBlock *>();
1067  const MCSymbol *ExceptOrFinally =
1068  UME.IsFinally ? getMCSymbolForMBB(Asm, Handler) : Handler->getSymbol();
1069  // -1 is usually the base state for "unwind to caller", but for
1070  // _except_handler4 it's -2. Do that replacement here if necessary.
1071  int ToState = UME.ToState == -1 ? BaseState : UME.ToState;
1072  AddComment("ToState");
1073  OS.emitInt32(ToState);
1074  AddComment(UME.IsFinally ? "Null" : "FilterFunction");
1075  OS.emitValue(create32bitRef(UME.Filter), 4);
1076  AddComment(UME.IsFinally ? "FinallyFunclet" : "ExceptionHandler");
1077  OS.emitValue(create32bitRef(ExceptOrFinally), 4);
1078  }
1079 }
1080 
1081 static int getTryRank(const WinEHFuncInfo &FuncInfo, int State) {
1082  int Rank = 0;
1083  while (State != -1) {
1084  ++Rank;
1085  State = FuncInfo.ClrEHUnwindMap[State].TryParentState;
1086  }
1087  return Rank;
1088 }
1089 
1090 static int getTryAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right) {
1091  int LeftRank = getTryRank(FuncInfo, Left);
1092  int RightRank = getTryRank(FuncInfo, Right);
1093 
1094  while (LeftRank < RightRank) {
1095  Right = FuncInfo.ClrEHUnwindMap[Right].TryParentState;
1096  --RightRank;
1097  }
1098 
1099  while (RightRank < LeftRank) {
1100  Left = FuncInfo.ClrEHUnwindMap[Left].TryParentState;
1101  --LeftRank;
1102  }
1103 
1104  while (Left != Right) {
1105  Left = FuncInfo.ClrEHUnwindMap[Left].TryParentState;
1106  Right = FuncInfo.ClrEHUnwindMap[Right].TryParentState;
1107  }
1108 
1109  return Left;
1110 }
1111 
1112 void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
1113  // CLR EH "states" are really just IDs that identify handlers/funclets;
1114  // states, handlers, and funclets all have 1:1 mappings between them, and a
1115  // handler/funclet's "state" is its index in the ClrEHUnwindMap.
1116  MCStreamer &OS = *Asm->OutStreamer;
1117  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
1118  MCSymbol *FuncBeginSym = Asm->getFunctionBegin();
1119  MCSymbol *FuncEndSym = Asm->getFunctionEnd();
1120 
1121  // A ClrClause describes a protected region.
1122  struct ClrClause {
1123  const MCSymbol *StartLabel; // Start of protected region
1124  const MCSymbol *EndLabel; // End of protected region
1125  int State; // Index of handler protecting the protected region
1126  int EnclosingState; // Index of funclet enclosing the protected region
1127  };
1128  SmallVector<ClrClause, 8> Clauses;
1129 
1130  // Build a map from handler MBBs to their corresponding states (i.e. their
1131  // indices in the ClrEHUnwindMap).
1132  int NumStates = FuncInfo.ClrEHUnwindMap.size();
1133  assert(NumStates > 0 && "Don't need exception table!");
1135  for (int State = 0; State < NumStates; ++State) {
1136  MachineBasicBlock *HandlerBlock =
1137  FuncInfo.ClrEHUnwindMap[State].Handler.get<MachineBasicBlock *>();
1138  HandlerStates[HandlerBlock] = State;
1139  // Use this loop through all handlers to verify our assumption (used in
1140  // the MinEnclosingState computation) that enclosing funclets have lower
1141  // state numbers than their enclosed funclets.
1142  assert(FuncInfo.ClrEHUnwindMap[State].HandlerParentState < State &&
1143  "ill-formed state numbering");
1144  }
1145  // Map the main function to the NullState.
1146  HandlerStates[&MF->front()] = NullState;
1147 
1148  // Write out a sentinel indicating the end of the standard (Windows) xdata
1149  // and the start of the additional (CLR) info.
1150  OS.emitInt32(0xffffffff);
1151  // Write out the number of funclets
1152  OS.emitInt32(NumStates);
1153 
1154  // Walk the machine blocks/instrs, computing and emitting a few things:
1155  // 1. Emit a list of the offsets to each handler entry, in lexical order.
1156  // 2. Compute a map (EndSymbolMap) from each funclet to the symbol at its end.
1157  // 3. Compute the list of ClrClauses, in the required order (inner before
1158  // outer, earlier before later; the order by which a forward scan with
1159  // early termination will find the innermost enclosing clause covering
1160  // a given address).
1161  // 4. A map (MinClauseMap) from each handler index to the index of the
1162  // outermost funclet/function which contains a try clause targeting the
1163  // key handler. This will be used to determine IsDuplicate-ness when
1164  // emitting ClrClauses. The NullState value is used to indicate that the
1165  // top-level function contains a try clause targeting the key handler.
1166  // HandlerStack is a stack of (PendingStartLabel, PendingState) pairs for
1167  // try regions we entered before entering the PendingState try but which
1168  // we haven't yet exited.
1170  // EndSymbolMap and MinClauseMap are maps described above.
1171  std::unique_ptr<MCSymbol *[]> EndSymbolMap(new MCSymbol *[NumStates]);
1172  SmallVector<int, 4> MinClauseMap((size_t)NumStates, NumStates);
1173 
1174  // Visit the root function and each funclet.
1175  for (MachineFunction::const_iterator FuncletStart = MF->begin(),
1176  FuncletEnd = MF->begin(),
1177  End = MF->end();
1178  FuncletStart != End; FuncletStart = FuncletEnd) {
1179  int FuncletState = HandlerStates[&*FuncletStart];
1180  // Find the end of the funclet
1181  MCSymbol *EndSymbol = FuncEndSym;
1182  while (++FuncletEnd != End) {
1183  if (FuncletEnd->isEHFuncletEntry()) {
1184  EndSymbol = getMCSymbolForMBB(Asm, &*FuncletEnd);
1185  break;
1186  }
1187  }
1188  // Emit the function/funclet end and, if this is a funclet (and not the
1189  // root function), record it in the EndSymbolMap.
1190  OS.emitValue(getOffset(EndSymbol, FuncBeginSym), 4);
1191  if (FuncletState != NullState) {
1192  // Record the end of the handler.
1193  EndSymbolMap[FuncletState] = EndSymbol;
1194  }
1195 
1196  // Walk the state changes in this function/funclet and compute its clauses.
1197  // Funclets always start in the null state.
1198  const MCSymbol *CurrentStartLabel = nullptr;
1199  int CurrentState = NullState;
1200  assert(HandlerStack.empty());
1201  for (const auto &StateChange :
1202  InvokeStateChangeIterator::range(FuncInfo, FuncletStart, FuncletEnd)) {
1203  // Close any try regions we're not still under
1204  int StillPendingState =
1205  getTryAncestor(FuncInfo, CurrentState, StateChange.NewState);
1206  while (CurrentState != StillPendingState) {
1207  assert(CurrentState != NullState &&
1208  "Failed to find still-pending state!");
1209  // Close the pending clause
1210  Clauses.push_back({CurrentStartLabel, StateChange.PreviousEndLabel,
1211  CurrentState, FuncletState});
1212  // Now the next-outer try region is current
1213  CurrentState = FuncInfo.ClrEHUnwindMap[CurrentState].TryParentState;
1214  // Pop the new start label from the handler stack if we've exited all
1215  // inner try regions of the corresponding try region.
1216  if (HandlerStack.back().second == CurrentState)
1217  CurrentStartLabel = HandlerStack.pop_back_val().first;
1218  }
1219 
1220  if (StateChange.NewState != CurrentState) {
1221  // For each clause we're starting, update the MinClauseMap so we can
1222  // know which is the topmost funclet containing a clause targeting
1223  // it.
1224  for (int EnteredState = StateChange.NewState;
1225  EnteredState != CurrentState;
1226  EnteredState =
1227  FuncInfo.ClrEHUnwindMap[EnteredState].TryParentState) {
1228  int &MinEnclosingState = MinClauseMap[EnteredState];
1229  if (FuncletState < MinEnclosingState)
1230  MinEnclosingState = FuncletState;
1231  }
1232  // Save the previous current start/label on the stack and update to
1233  // the newly-current start/state.
1234  HandlerStack.emplace_back(CurrentStartLabel, CurrentState);
1235  CurrentStartLabel = StateChange.NewStartLabel;
1236  CurrentState = StateChange.NewState;
1237  }
1238  }
1239  assert(HandlerStack.empty());
1240  }
1241 
1242  // Now emit the clause info, starting with the number of clauses.
1243  OS.emitInt32(Clauses.size());
1244  for (ClrClause &Clause : Clauses) {
1245  // Emit a CORINFO_EH_CLAUSE :
1246  /*
1247  struct CORINFO_EH_CLAUSE
1248  {
1249  CORINFO_EH_CLAUSE_FLAGS Flags; // actually a CorExceptionFlag
1250  DWORD TryOffset;
1251  DWORD TryLength; // actually TryEndOffset
1252  DWORD HandlerOffset;
1253  DWORD HandlerLength; // actually HandlerEndOffset
1254  union
1255  {
1256  DWORD ClassToken; // use for catch clauses
1257  DWORD FilterOffset; // use for filter clauses
1258  };
1259  };
1260 
1261  enum CORINFO_EH_CLAUSE_FLAGS
1262  {
1263  CORINFO_EH_CLAUSE_NONE = 0,
1264  CORINFO_EH_CLAUSE_FILTER = 0x0001, // This clause is for a filter
1265  CORINFO_EH_CLAUSE_FINALLY = 0x0002, // This clause is a finally clause
1266  CORINFO_EH_CLAUSE_FAULT = 0x0004, // This clause is a fault clause
1267  };
1268  typedef enum CorExceptionFlag
1269  {
1270  COR_ILEXCEPTION_CLAUSE_NONE,
1271  COR_ILEXCEPTION_CLAUSE_FILTER = 0x0001, // This is a filter clause
1272  COR_ILEXCEPTION_CLAUSE_FINALLY = 0x0002, // This is a finally clause
1273  COR_ILEXCEPTION_CLAUSE_FAULT = 0x0004, // This is a fault clause
1274  COR_ILEXCEPTION_CLAUSE_DUPLICATED = 0x0008, // duplicated clause. This
1275  // clause was duplicated
1276  // to a funclet which was
1277  // pulled out of line
1278  } CorExceptionFlag;
1279  */
1280  // Add 1 to the start/end of the EH clause; the IP associated with a
1281  // call when the runtime does its scan is the IP of the next instruction
1282  // (the one to which control will return after the call), so we need
1283  // to add 1 to the end of the clause to cover that offset. We also add
1284  // 1 to the start of the clause to make sure that the ranges reported
1285  // for all clauses are disjoint. Note that we'll need some additional
1286  // logic when machine traps are supported, since in that case the IP
1287  // that the runtime uses is the offset of the faulting instruction
1288  // itself; if such an instruction immediately follows a call but the
1289  // two belong to different clauses, we'll need to insert a nop between
1290  // them so the runtime can distinguish the point to which the call will
1291  // return from the point at which the fault occurs.
1292 
1293  const MCExpr *ClauseBegin =
1294  getOffsetPlusOne(Clause.StartLabel, FuncBeginSym);
1295  const MCExpr *ClauseEnd = getOffsetPlusOne(Clause.EndLabel, FuncBeginSym);
1296 
1297  const ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State];
1298  MachineBasicBlock *HandlerBlock = Entry.Handler.get<MachineBasicBlock *>();
1299  MCSymbol *BeginSym = getMCSymbolForMBB(Asm, HandlerBlock);
1300  const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym);
1301  MCSymbol *EndSym = EndSymbolMap[Clause.State];
1302  const MCExpr *HandlerEnd = getOffset(EndSym, FuncBeginSym);
1303 
1304  uint32_t Flags = 0;
1305  switch (Entry.HandlerType) {
1306  case ClrHandlerType::Catch:
1307  // Leaving bits 0-2 clear indicates catch.
1308  break;
1310  Flags |= 1;
1311  break;
1313  Flags |= 2;
1314  break;
1315  case ClrHandlerType::Fault:
1316  Flags |= 4;
1317  break;
1318  }
1319  if (Clause.EnclosingState != MinClauseMap[Clause.State]) {
1320  // This is a "duplicate" clause; the handler needs to be entered from a
1321  // frame above the one holding the invoke.
1322  assert(Clause.EnclosingState > MinClauseMap[Clause.State]);
1323  Flags |= 8;
1324  }
1325  OS.emitInt32(Flags);
1326 
1327  // Write the clause start/end
1328  OS.emitValue(ClauseBegin, 4);
1329  OS.emitValue(ClauseEnd, 4);
1330 
1331  // Write out the handler start/end
1332  OS.emitValue(HandlerBegin, 4);
1333  OS.emitValue(HandlerEnd, 4);
1334 
1335  // Write out the type token or filter offset
1336  assert(Entry.HandlerType != ClrHandlerType::Filter && "NYI: filters");
1337  OS.emitInt32(Entry.TypeToken);
1338  }
1339 }
llvm::MachineFunction::hasWinCFI
bool hasWinCFI() const
Definition: MachineFunction.h:658
llvm::EHPersonality::MSVC_CXX
@ MSVC_CXX
AsmPrinter.h
llvm::MCContext::getObjectFileInfo
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:424
llvm::MCBinaryExpr::createDiv
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:533
scan
static Expected< BitVector > scan(StringRef &S, StringRef Original)
Definition: GlobPattern.cpp:67
llvm::TargetLoweringBase::getStackPointerRegisterToSaveRestore
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
Definition: TargetLowering.h:1725
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:102
llvm
Definition: AllocatorList.h:23
llvm::AsmPrinter::getFunctionEnd
MCSymbol * getFunctionEnd() const
Definition: AsmPrinter.h:248
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
TargetFrameLowering.h
llvm::TargetFrameLowering
Information about stack frame layout on the target.
Definition: TargetFrameLowering.h:43
llvm::COFF::IMAGE_SYM_CLASS_STATIC
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition: COFF.h:210
llvm::WinException::endFunction
void endFunction(const MachineFunction *) override
Gather and emit post-function exception information.
Definition: WinException.cpp:129
llvm::MCContext::getOrCreateParentFrameOffsetSymbol
MCSymbol * getOrCreateParentFrameOffsetSymbol(StringRef FuncName)
Definition: MCContext.cpp:206
llvm::WinEHFuncInfo::CxxUnwindMap
SmallVector< CxxUnwindMapEntry, 4 > CxxUnwindMap
Definition: WinEHFuncInfo.h:95
llvm::GlobalValue::dropLLVMManglingEscape
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
Definition: GlobalValue.h:482
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:71
llvm::Function
Definition: Function.h:61
llvm::EHStreamer
Emits exception handling directives.
Definition: EHStreamer.h:30
llvm::MachineFunction::getContext
MCContext & getContext() const
Definition: MachineFunction.h:528
llvm::WinException::beginFunclet
void beginFunclet(const MachineBasicBlock &MBB, MCSymbol *Sym) override
Emit target-specific EH funclet machinery.
Definition: WinException.cpp:203
llvm::WinEHFuncInfo::ClrEHUnwindMap
SmallVector< ClrEHUnwindMapEntry, 4 > ClrEHUnwindMap
Definition: WinEHFuncInfo.h:98
llvm::WinException::markFunctionEnd
void markFunctionEnd() override
Definition: WinException.cpp:121
llvm::ClrEHUnwindMapEntry
Definition: WinEHFuncInfo.h:81
llvm::AsmPrinter::MAI
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:88
llvm::MachineBasicBlock::isEHFuncletEntry
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
Definition: MachineBasicBlock.h:552
llvm::MCConstantExpr::create
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1167
llvm::MachineFunction::end
iterator end()
Definition: MachineFunction.h:760
llvm::WinException::endModule
void endModule() override
Emit all exception information that should come after the content.
Definition: WinException.cpp:52
ErrorHandling.h
llvm::WinEHHandlerType::FrameIndex
int FrameIndex
Definition: WinEHFuncInfo.h:66
llvm::WinEHHandlerType
Definition: WinEHFuncInfo.h:60
llvm::COFF::SCT_COMPLEX_TYPE_SHIFT
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
Definition: COFF.h:265
Right
Vector Shift Left Right
Definition: README_P9.txt:118
COFF.h
llvm::MCStreamer::emitValue
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:175
llvm::StackOffset::getFixed
ScalarTy getFixed() const
Definition: TypeSize.h:149
llvm::WinEHFuncInfo::TryBlockMap
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
Definition: WinEHFuncInfo.h:96
Module.h
llvm::MCStreamer::emitInt32
void emitInt32(uint64_t Value)
Definition: MCStreamer.h:702
llvm::EHStreamer::MMI
MachineModuleInfo * MMI
Collected machine module information.
Definition: EHStreamer.h:36
llvm::operator!=
bool operator!=(uint64_t V1, const APInt &V2)
Definition: APInt.h:2039
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:634
llvm::WinException::beginFunction
void beginFunction(const MachineFunction *MF) override
Gather pre-function exception information.
Definition: WinException.cpp:68
llvm::PointerUnion::get
T get() const
Returns the value of the specified pointer type.
Definition: PointerUnion.h:187
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::WinException::endFunclet
void endFunclet() override
Definition: WinException.cpp:254
llvm::MCContext::getOrCreateLSDASymbol
MCSymbol * getOrCreateLSDASymbol(StringRef FuncName)
Definition: MCContext.cpp:211
llvm::TargetLoweringObjectFile
Definition: TargetLoweringObjectFile.h:43
llvm::CxxUnwindMapEntry::Cleanup
MBBOrBasicBlock Cleanup
Definition: WinEHFuncInfo.h:42
llvm::classifyEHPersonality
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Definition: EHPersonalities.cpp:21
llvm::AlignStyle::Left
@ Left
FormattedStream.h
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:197
llvm::WinEHFuncInfo::FuncletBaseStateMap
DenseMap< const FuncletPadInst *, int > FuncletBaseStateMap
Definition: WinEHFuncInfo.h:92
TargetLowering.h
llvm::MachineFunction::front
const MachineBasicBlock & front() const
Definition: MachineFunction.h:770
llvm::MCContext::getOrCreateSymbol
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:187
TargetMachine.h
llvm::WinEHHandlerType::Adjectives
int Adjectives
Definition: WinEHFuncInfo.h:61
llvm::TargetFrameLowering::getNonLocalFrameIndexReference
virtual StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF, int FI) const
getNonLocalFrameIndexReference - This method returns the offset used to reference a frame index locat...
Definition: TargetFrameLowering.h:317
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::AsmPrinter::OutStreamer
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:97
Twine.h
llvm::Triple::isAArch64
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
Definition: Triple.h:724
MCContext.h
llvm::EHStreamer::emitExceptionTable
MCSymbol * emitExceptionTable()
Emit landing pads and actions.
Definition: EHStreamer.cpp:378
llvm::WinEHFuncInfo::EHRegNodeFrameIndex
int EHRegNodeFrameIndex
Definition: WinEHFuncInfo.h:107
llvm::SEHUnwindMapEntry::Filter
const Function * Filter
Holds the filter expression function.
Definition: WinEHFuncInfo.h:54
llvm::MCStreamer::emitLabel
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:413
MCSymbol.h
llvm::isNoOpWithoutInvoke
bool isNoOpWithoutInvoke(EHPersonality Pers)
Return true if this personality may be safely removed if there are no invoke instructions remaining i...
Definition: EHPersonalities.h:96
llvm::AsmPrinter::CurrentFnSym
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition: AsmPrinter.h:119
llvm::AsmPrinter::emitAlignment
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr) const
Emit an alignment directive to the specified power of two boundary.
Definition: AsmPrinter.cpp:2428
llvm::ClrHandlerType::Fault
@ Fault
llvm::MachineFunction::begin
iterator begin()
Definition: MachineFunction.h:758
llvm::MachineBasicBlock::isCleanupFuncletEntry
bool isCleanupFuncletEntry() const
Returns true if this is the entry block of a cleanup funclet.
Definition: MachineBasicBlock.h:558
llvm::MachineFunction::tidyLandingPads
void tidyLandingPads(DenseMap< MCSymbol *, uintptr_t > *LPMap=nullptr, bool TidyIfNoBeginLabels=true)
Remap landing pad labels and remove any deleted landing pads.
Definition: MachineFunction.cpp:766
llvm::AsmPrinter::getFunctionBegin
MCSymbol * getFunctionBegin() const
Definition: AsmPrinter.h:247
llvm::WinEHHandlerType::TypeDescriptor
GlobalVariable * TypeDescriptor
Definition: WinEHFuncInfo.h:68
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::MCConstantExpr
Definition: MCExpr.h:144
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:576
llvm::ClrHandlerType::Filter
@ Filter
llvm::Clause
Definition: DirectiveEmitter.h:123
llvm::WinEHTryBlockMapEntry
Definition: WinEHFuncInfo.h:72
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:179
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::WinEHFuncInfo
Definition: WinEHFuncInfo.h:90
llvm::SEHUnwindMapEntry::IsFinally
bool IsFinally
Definition: WinEHFuncInfo.h:51
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::CxxUnwindMapEntry::ToState
int ToState
Definition: WinEHFuncInfo.h:41
llvm::TargetLoweringObjectFile::getPersonalityEncoding
unsigned getPersonalityEncoding() const
Definition: TargetLoweringObjectFile.h:166
llvm::MachineFrameInfo::hasStackProtectorIndex
bool hasStackProtectorIndex() const
Definition: MachineFrameInfo.h:356
llvm::PointerUnion::dyn_cast
T dyn_cast() const
Returns the current pointer if it is of the specified pointer type, otherwise returns null.
Definition: PointerUnion.h:194
llvm::DenseMap
Definition: DenseMap.h:714
llvm::WinEHTryBlockMapEntry::HandlerArray
SmallVector< WinEHHandlerType, 1 > HandlerArray
Definition: WinEHFuncInfo.h:76
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::AsmPrinter::needsSEHMoves
bool needsSEHMoves()
Definition: AsmPrinter.cpp:1066
llvm::concat
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&... Ranges)
Concatenated range across two or more ranges.
Definition: STLExtras.h:1011
llvm::MachineBasicBlock::getAlignment
Align getAlignment() const
Return alignment of the basic block.
Definition: MachineBasicBlock.h:519
llvm::MCObjectFileInfo::getGEHContSection
MCSection * getGEHContSection() const
Definition: MCObjectFileInfo.h:410
llvm::WinEHTryBlockMapEntry::TryHigh
int TryHigh
Definition: WinEHFuncInfo.h:74
llvm::WinEHFuncInfo::LabelToStateMap
DenseMap< MCSymbol *, std::pair< int, MCSymbol * > > LabelToStateMap
Definition: WinEHFuncInfo.h:94
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::AsmPrinter::getSymbol
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:478
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:592
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:225
llvm::MCBinaryExpr::createSub
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:608
llvm::operator==
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:2037
llvm::AsmPrinter::MF
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:100
llvm::MachineFunction::getLandingPads
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
Definition: MachineFunction.h:997
llvm::EHStreamer::callToNoUnwindFunction
static bool callToNoUnwindFunction(const MachineInstr *MI)
Return ‘true’ if this is a call to a function marked ‘nounwind’.
Definition: EHStreamer.cpp:159
llvm::AsmPrinter::OutContext
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:92
MachineModuleInfo.h
llvm::WinEHFuncInfo::UnwindHelpFrameIdx
int UnwindHelpFrameIdx
Definition: WinEHFuncInfo.h:99
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::EHPersonality::CoreCLR
@ CoreCLR
llvm::WinEHFuncInfo::EHGuardFrameIndex
int EHGuardFrameIndex
Definition: WinEHFuncInfo.h:109
MCSection.h
llvm::MachineFunction
Definition: MachineFunction.h:230
Mangler.h
TargetOptions.h
llvm::MCBinaryExpr::createAdd
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:523
llvm::operator*
APInt operator*(APInt a, uint64_t RHS)
Definition: APInt.h:2161
llvm::WinException::~WinException
~WinException() override
Definition: WinException.cpp:48
llvm::MachineBasicBlock::getNumber
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
Definition: MachineBasicBlock.h:1060
MCAsmInfo.h
llvm::EHStreamer::Asm
AsmPrinter * Asm
Target of directive emission.
Definition: EHStreamer.h:33
DataLayout.h
llvm::TargetLoweringObjectFile::getLSDAEncoding
unsigned getLSDAEncoding() const
Definition: TargetLoweringObjectFile.h:167
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
Dwarf.h
llvm::EHPersonality::MSVC_TableSEH
@ MSVC_TableSEH
MBBI
MachineBasicBlock MachineBasicBlock::iterator MBBI
Definition: AArch64SLSHardening.cpp:75
TargetLoweringObjectFile.h
uint32_t
llvm::SEHUnwindMapEntry
Similar to CxxUnwindMapEntry, but supports SEH filters.
Definition: WinEHFuncInfo.h:46
llvm::StackOffset
StackOffset is a class to represent an offset with 2 dimensions, named fixed and scalable,...
Definition: TypeSize.h:134
TargetSubtargetInfo.h
llvm::MCSection
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::WinEHFuncInfo::EHRegNodeEndOffset
int EHRegNodeEndOffset
Definition: WinEHFuncInfo.h:108
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:294
llvm::MCContext::createTempSymbol
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:297
llvm::EHPersonality
EHPersonality
Definition: EHPersonalities.h:22
llvm::ClrHandlerType::Finally
@ Finally
llvm::StackOffset::getFixed
static StackOffset getFixed(ScalarTy Fixed)
Definition: TypeSize.h:143
llvm::SEHUnwindMapEntry::ToState
int ToState
If unwinding continues through this handler, transition to the handler at this state.
Definition: WinEHFuncInfo.h:49
llvm::EHPersonality::MSVC_X86SEH
@ MSVC_X86SEH
llvm::SEHUnwindMapEntry::Handler
MBBOrBasicBlock Handler
Holds the __except or __finally basic block.
Definition: WinEHFuncInfo.h:57
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::WinEHFuncInfo::SEHUnwindMap
SmallVector< SEHUnwindMapEntry, 4 > SEHUnwindMap
Definition: WinEHFuncInfo.h:97
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:73
llvm::EHPersonality::Unknown
@ Unknown
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::WinEHTryBlockMapEntry::CatchHigh
int CatchHigh
Definition: WinEHFuncInfo.h:75
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
llvm::pdb::PDB_SymType::Label
@ Label
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:542
llvm::TargetSubtargetInfo::getFrameLowering
virtual const TargetFrameLowering * getFrameLowering() const
Definition: TargetSubtargetInfo.h:93
llvm::ilist_iterator
Iterator for intrusive lists based on ilist_node.
Definition: ilist_iterator.h:57
MachineFrameInfo.h
llvm::MachineFunction::getWinEHFuncInfo
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.
Definition: MachineFunction.h:620
llvm::TargetFrameLowering::getFrameIndexReference
virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
Definition: TargetFrameLoweringImpl.cpp:45
llvm::CxxUnwindMapEntry
Definition: WinEHFuncInfo.h:40
llvm::WinEHTryBlockMapEntry::TryLow
int TryLow
Definition: WinEHFuncInfo.h:73
llvm::AsmPrinter
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:82
llvm::MCSymbolRefExpr::VK_COFF_IMGREL32
@ VK_COFF_IMGREL32
Definition: MCExpr.h:315
llvm::MCSymbolRefExpr::create
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:384
WinException.h
llvm::MachineFunction::hasEHFunclets
bool hasEHFunclets() const
Definition: MachineFunction.h:986
getTryRank
static int getTryRank(const WinEHFuncInfo &FuncInfo, int State)
Definition: WinException.cpp:1081
WinEHFuncInfo.h
llvm::ClrHandlerType::Catch
@ Catch
llvm::TargetFrameLowering::getWinEHParentFrameOffset
virtual unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const
Definition: TargetFrameLowering.h:359
getMCSymbolForMBB
static MCSymbol * getMCSymbolForMBB(AsmPrinter *Asm, const MachineBasicBlock *MBB)
Retrieve the MCSymbol for a GlobalValue or MachineBasicBlock.
Definition: WinException.cpp:184
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:107
llvm::AsmPrinter::TM
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:85
llvm::TargetSubtargetInfo::getTargetLowering
virtual const TargetLowering * getTargetLowering() const
Definition: TargetSubtargetInfo.h:96
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
llvm::WinException::WinException
WinException(AsmPrinter *A)
Definition: WinException.cpp:41
llvm::AsmPrinter::getObjFileLowering
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:223
MCStreamer.h
llvm::dwarf::DW_EH_PE_omit
@ DW_EH_PE_omit
Definition: Dwarf.h:433
llvm::TargetMachine::getTargetTriple
const Triple & getTargetTriple() const
Definition: TargetMachine.h:123
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::WinEHFuncInfo::SEHSetFrameOffset
int SEHSetFrameOffset
Definition: WinEHFuncInfo.h:110
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
llvm::TargetLoweringObjectFile::getCFIPersonalitySymbol
virtual MCSymbol * getCFIPersonalitySymbol(const GlobalValue *GV, const TargetMachine &TM, MachineModuleInfo *MMI) const
Definition: TargetLoweringObjectFile.cpp:140
llvm::MCStreamer::isVerboseAsm
virtual bool isVerboseAsm() const
Return true if this streamer supports verbose assembly and if it is enabled.
Definition: MCStreamer.h:317
llvm::MCStreamer::emitValueToAlignment
virtual void emitValueToAlignment(unsigned ByteAlignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
Definition: MCStreamer.cpp:1181
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
llvm::HexStyle::Asm
@ Asm
0ffh
Definition: MCInstPrinter.h:34
llvm::WinEHHandlerType::Handler
MBBOrBasicBlock Handler
Definition: WinEHFuncInfo.h:69
llvm::MachineFrameInfo::getStackProtectorIndex
int getStackProtectorIndex() const
Return the index for the stack protector object.
Definition: MachineFrameInfo.h:354
llvm::MCSymbolRefExpr::VK_None
@ VK_None
Definition: MCExpr.h:195
llvm::MachineFunction::getCatchretTargets
const std::vector< MCSymbol * > & getCatchretTargets() const
Returns a reference to a list of symbols that we have catchrets.
Definition: MachineFunction.h:961
llvm::TargetFrameLowering::getFrameIndexReferencePreferSP
virtual StackOffset getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, Register &FrameReg, bool IgnoreSPUpdates) const
Same as getFrameIndexReference, except that the stack pointer (as opposed to the frame pointer) will ...
Definition: TargetFrameLowering.h:307
MachineFunction.h
llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
Definition: COFF.h:261
llvm::MachineInstrBundleIterator< const MachineInstr >
llvm::MCAsmInfo::usesWindowsCFI
bool usesWindowsCFI() const
Definition: MCAsmInfo.h:766
llvm::MachineFunction::getAlignment
Align getAlignment() const
getAlignment - Return the alignment of the function.
Definition: MachineFunction.h:624
MCExpr.h
llvm::MachineModuleInfo::getModule
const Module * getModule() const
Definition: MachineModuleInfo.h:174
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::MCStreamer::AddComment
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition: MCStreamer.h:340
getTryAncestor
static int getTryAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right)
Definition: WinException.cpp:1090
llvm::isFuncletEHPersonality
bool isFuncletEHPersonality(EHPersonality Pers)
Returns true if this is a personality function that invokes handler funclets (which must return to it...
Definition: EHPersonalities.h:65
llvm::WinEHHandlerType::CatchObj
union llvm::WinEHHandlerType::@221 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
llvm::SmallVectorImpl::emplace_back
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:907