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