LLVM  15.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  if (Asm->MAI->usesWindowsCFI())
697  UnwindHelpOffset =
698  getFrameIndexOffset(FuncInfo.UnwindHelpFrameIdx, FuncInfo);
699 
700  MCSymbol *UnwindMapXData = nullptr;
701  MCSymbol *TryBlockMapXData = nullptr;
702  MCSymbol *IPToStateXData = nullptr;
703  if (!FuncInfo.CxxUnwindMap.empty())
704  UnwindMapXData = Asm->OutContext.getOrCreateSymbol(
705  Twine("$stateUnwindMap$", FuncLinkageName));
706  if (!FuncInfo.TryBlockMap.empty())
707  TryBlockMapXData =
708  Asm->OutContext.getOrCreateSymbol(Twine("$tryMap$", FuncLinkageName));
709  if (!IPToStateTable.empty())
710  IPToStateXData =
711  Asm->OutContext.getOrCreateSymbol(Twine("$ip2state$", FuncLinkageName));
712 
713  bool VerboseAsm = OS.isVerboseAsm();
714  auto AddComment = [&](const Twine &Comment) {
715  if (VerboseAsm)
716  OS.AddComment(Comment);
717  };
718 
719  // FuncInfo {
720  // uint32_t MagicNumber
721  // int32_t MaxState;
722  // UnwindMapEntry *UnwindMap;
723  // uint32_t NumTryBlocks;
724  // TryBlockMapEntry *TryBlockMap;
725  // uint32_t IPMapEntries; // always 0 for x86
726  // IPToStateMapEntry *IPToStateMap; // always 0 for x86
727  // uint32_t UnwindHelp; // non-x86 only
728  // ESTypeList *ESTypeList;
729  // int32_t EHFlags;
730  // }
731  // EHFlags & 1 -> Synchronous exceptions only, no async exceptions.
732  // EHFlags & 2 -> ???
733  // EHFlags & 4 -> The function is noexcept(true), unwinding can't continue.
734  OS.emitValueToAlignment(4);
735  OS.emitLabel(FuncInfoXData);
736 
737  AddComment("MagicNumber");
738  OS.emitInt32(0x19930522);
739 
740  AddComment("MaxState");
741  OS.emitInt32(FuncInfo.CxxUnwindMap.size());
742 
743  AddComment("UnwindMap");
744  OS.emitValue(create32bitRef(UnwindMapXData), 4);
745 
746  AddComment("NumTryBlocks");
747  OS.emitInt32(FuncInfo.TryBlockMap.size());
748 
749  AddComment("TryBlockMap");
750  OS.emitValue(create32bitRef(TryBlockMapXData), 4);
751 
752  AddComment("IPMapEntries");
753  OS.emitInt32(IPToStateTable.size());
754 
755  AddComment("IPToStateXData");
756  OS.emitValue(create32bitRef(IPToStateXData), 4);
757 
758  if (Asm->MAI->usesWindowsCFI()) {
759  AddComment("UnwindHelp");
760  OS.emitInt32(UnwindHelpOffset);
761  }
762 
763  AddComment("ESTypeList");
764  OS.emitInt32(0);
765 
766  AddComment("EHFlags");
767  OS.emitInt32(1);
768 
769  // UnwindMapEntry {
770  // int32_t ToState;
771  // void (*Action)();
772  // };
773  if (UnwindMapXData) {
774  OS.emitLabel(UnwindMapXData);
775  for (const CxxUnwindMapEntry &UME : FuncInfo.CxxUnwindMap) {
776  MCSymbol *CleanupSym =
778  AddComment("ToState");
779  OS.emitInt32(UME.ToState);
780 
781  AddComment("Action");
782  OS.emitValue(create32bitRef(CleanupSym), 4);
783  }
784  }
785 
786  // TryBlockMap {
787  // int32_t TryLow;
788  // int32_t TryHigh;
789  // int32_t CatchHigh;
790  // int32_t NumCatches;
791  // HandlerType *HandlerArray;
792  // };
793  if (TryBlockMapXData) {
794  OS.emitLabel(TryBlockMapXData);
795  SmallVector<MCSymbol *, 1> HandlerMaps;
796  for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
797  const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
798 
799  MCSymbol *HandlerMapXData = nullptr;
800  if (!TBME.HandlerArray.empty())
801  HandlerMapXData =
802  Asm->OutContext.getOrCreateSymbol(Twine("$handlerMap$")
803  .concat(Twine(I))
804  .concat("$")
805  .concat(FuncLinkageName));
806  HandlerMaps.push_back(HandlerMapXData);
807 
808  // TBMEs should form intervals.
809  assert(0 <= TBME.TryLow && "bad trymap interval");
810  assert(TBME.TryLow <= TBME.TryHigh && "bad trymap interval");
811  assert(TBME.TryHigh < TBME.CatchHigh && "bad trymap interval");
812  assert(TBME.CatchHigh < int(FuncInfo.CxxUnwindMap.size()) &&
813  "bad trymap interval");
814 
815  AddComment("TryLow");
816  OS.emitInt32(TBME.TryLow);
817 
818  AddComment("TryHigh");
819  OS.emitInt32(TBME.TryHigh);
820 
821  AddComment("CatchHigh");
822  OS.emitInt32(TBME.CatchHigh);
823 
824  AddComment("NumCatches");
825  OS.emitInt32(TBME.HandlerArray.size());
826 
827  AddComment("HandlerArray");
828  OS.emitValue(create32bitRef(HandlerMapXData), 4);
829  }
830 
831  // All funclets use the same parent frame offset currently.
832  unsigned ParentFrameOffset = 0;
833  if (shouldEmitPersonality) {
835  ParentFrameOffset = TFI->getWinEHParentFrameOffset(*MF);
836  }
837 
838  for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
839  const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
840  MCSymbol *HandlerMapXData = HandlerMaps[I];
841  if (!HandlerMapXData)
842  continue;
843  // HandlerType {
844  // int32_t Adjectives;
845  // TypeDescriptor *Type;
846  // int32_t CatchObjOffset;
847  // void (*Handler)();
848  // int32_t ParentFrameOffset; // x64 and AArch64 only
849  // };
850  OS.emitLabel(HandlerMapXData);
851  for (const WinEHHandlerType &HT : TBME.HandlerArray) {
852  // Get the frame escape label with the offset of the catch object. If
853  // the index is INT_MAX, then there is no catch object, and we should
854  // emit an offset of zero, indicating that no copy will occur.
855  const MCExpr *FrameAllocOffsetRef = nullptr;
856  if (HT.CatchObj.FrameIndex != INT_MAX) {
857  int Offset = getFrameIndexOffset(HT.CatchObj.FrameIndex, FuncInfo);
858  assert(Offset != 0 && "Illegal offset for catch object!");
859  FrameAllocOffsetRef = MCConstantExpr::create(Offset, Asm->OutContext);
860  } else {
861  FrameAllocOffsetRef = MCConstantExpr::create(0, Asm->OutContext);
862  }
863 
864  MCSymbol *HandlerSym =
866 
867  AddComment("Adjectives");
868  OS.emitInt32(HT.Adjectives);
869 
870  AddComment("Type");
871  OS.emitValue(create32bitRef(HT.TypeDescriptor), 4);
872 
873  AddComment("CatchObjOffset");
874  OS.emitValue(FrameAllocOffsetRef, 4);
875 
876  AddComment("Handler");
877  OS.emitValue(create32bitRef(HandlerSym), 4);
878 
879  if (shouldEmitPersonality) {
880  AddComment("ParentFrameOffset");
881  OS.emitInt32(ParentFrameOffset);
882  }
883  }
884  }
885  }
886 
887  // IPToStateMapEntry {
888  // void *IP;
889  // int32_t State;
890  // };
891  if (IPToStateXData) {
892  OS.emitLabel(IPToStateXData);
893  for (auto &IPStatePair : IPToStateTable) {
894  AddComment("IP");
895  OS.emitValue(IPStatePair.first, 4);
896  AddComment("ToState");
897  OS.emitInt32(IPStatePair.second);
898  }
899  }
900 }
901 
902 void WinException::computeIP2StateTable(
903  const MachineFunction *MF, const WinEHFuncInfo &FuncInfo,
904  SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable) {
905 
906  for (MachineFunction::const_iterator FuncletStart = MF->begin(),
907  FuncletEnd = MF->begin(),
908  End = MF->end();
909  FuncletStart != End; FuncletStart = FuncletEnd) {
910  // Find the end of the funclet
911  while (++FuncletEnd != End) {
912  if (FuncletEnd->isEHFuncletEntry()) {
913  break;
914  }
915  }
916 
917  // Don't emit ip2state entries for cleanup funclets. Any interesting
918  // exceptional actions in cleanups must be handled in a separate IR
919  // function.
920  if (FuncletStart->isCleanupFuncletEntry())
921  continue;
922 
923  MCSymbol *StartLabel;
924  int BaseState;
925  if (FuncletStart == MF->begin()) {
926  BaseState = NullState;
927  StartLabel = Asm->getFunctionBegin();
928  } else {
929  auto *FuncletPad =
930  cast<FuncletPadInst>(FuncletStart->getBasicBlock()->getFirstNonPHI());
931  assert(FuncInfo.FuncletBaseStateMap.count(FuncletPad) != 0);
932  BaseState = FuncInfo.FuncletBaseStateMap.find(FuncletPad)->second;
933  StartLabel = getMCSymbolForMBB(Asm, &*FuncletStart);
934  }
935  assert(StartLabel && "need local function start label");
936  IPToStateTable.push_back(
937  std::make_pair(create32bitRef(StartLabel), BaseState));
938 
939  for (const auto &StateChange : InvokeStateChangeIterator::range(
940  FuncInfo, FuncletStart, FuncletEnd, BaseState)) {
941  // Compute the label to report as the start of this entry; use the EH
942  // start label for the invoke if we have one, otherwise (this is a call
943  // which may unwind to our caller and does not have an EH start label, so)
944  // use the previous end label.
945  const MCSymbol *ChangeLabel = StateChange.NewStartLabel;
946  if (!ChangeLabel)
947  ChangeLabel = StateChange.PreviousEndLabel;
948  // Emit an entry indicating that PCs after 'Label' have this EH state.
949  // NOTE: On ARM architectures, the StateFromIp automatically takes into
950  // account that the return address is after the call instruction (whose EH
951  // state we should be using), but on other platforms we need to +1 to the
952  // label so that we are using the correct EH state.
953  const MCExpr *LabelExpression = (isAArch64 || isThumb)
954  ? getLabel(ChangeLabel)
955  : getLabelPlusOne(ChangeLabel);
956  IPToStateTable.push_back(
957  std::make_pair(LabelExpression, StateChange.NewState));
958  // FIXME: assert that NewState is between CatchLow and CatchHigh.
959  }
960  }
961 }
962 
963 void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
964  StringRef FLinkageName) {
965  // Outlined helpers called by the EH runtime need to know the offset of the EH
966  // registration in order to recover the parent frame pointer. Now that we know
967  // we've code generated the parent, we can emit the label assignment that
968  // those helpers use to get the offset of the registration node.
969 
970  // Compute the parent frame offset. The EHRegNodeFrameIndex will be invalid if
971  // after optimization all the invokes were eliminated. We still need to emit
972  // the parent frame offset label, but it should be garbage and should never be
973  // used.
974  int64_t Offset = 0;
975  int FI = FuncInfo.EHRegNodeFrameIndex;
976  if (FI != INT_MAX) {
979  }
980 
981  MCContext &Ctx = Asm->OutContext;
982  MCSymbol *ParentFrameOffset =
983  Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName);
984  Asm->OutStreamer->emitAssignment(ParentFrameOffset,
985  MCConstantExpr::create(Offset, Ctx));
986 }
987 
988 /// Emit the language-specific data that _except_handler3 and 4 expect. This is
989 /// functionally equivalent to the __C_specific_handler table, except it is
990 /// indexed by state number instead of IP.
991 void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
992  MCStreamer &OS = *Asm->OutStreamer;
993  const Function &F = MF->getFunction();
994  StringRef FLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
995 
996  bool VerboseAsm = OS.isVerboseAsm();
997  auto AddComment = [&](const Twine &Comment) {
998  if (VerboseAsm)
999  OS.AddComment(Comment);
1000  };
1001 
1002  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
1003  emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
1004 
1005  // Emit the __ehtable label that we use for llvm.x86.seh.lsda.
1006  MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName);
1007  OS.emitValueToAlignment(4);
1008  OS.emitLabel(LSDALabel);
1009 
1010  const auto *Per = cast<Function>(F.getPersonalityFn()->stripPointerCasts());
1011  StringRef PerName = Per->getName();
1012  int BaseState = -1;
1013  if (PerName == "_except_handler4") {
1014  // The LSDA for _except_handler4 starts with this struct, followed by the
1015  // scope table:
1016  //
1017  // struct EH4ScopeTable {
1018  // int32_t GSCookieOffset;
1019  // int32_t GSCookieXOROffset;
1020  // int32_t EHCookieOffset;
1021  // int32_t EHCookieXOROffset;
1022  // ScopeTableEntry ScopeRecord[];
1023  // };
1024  //
1025  // Offsets are %ebp relative.
1026  //
1027  // The GS cookie is present only if the function needs stack protection.
1028  // GSCookieOffset = -2 means that GS cookie is not used.
1029  //
1030  // The EH cookie is always present.
1031  //
1032  // Check is done the following way:
1033  // (ebp+CookieXOROffset) ^ [ebp+CookieOffset] == _security_cookie
1034 
1035  // Retrieve the Guard Stack slot.
1036  int GSCookieOffset = -2;
1037  const MachineFrameInfo &MFI = MF->getFrameInfo();
1038  if (MFI.hasStackProtectorIndex()) {
1039  Register UnusedReg;
1040  const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
1041  int SSPIdx = MFI.getStackProtectorIndex();
1042  GSCookieOffset =
1043  TFI->getFrameIndexReference(*MF, SSPIdx, UnusedReg).getFixed();
1044  }
1045 
1046  // Retrieve the EH Guard slot.
1047  // TODO(etienneb): Get rid of this value and change it for and assertion.
1048  int EHCookieOffset = 9999;
1049  if (FuncInfo.EHGuardFrameIndex != INT_MAX) {
1050  Register UnusedReg;
1051  const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
1052  int EHGuardIdx = FuncInfo.EHGuardFrameIndex;
1053  EHCookieOffset =
1054  TFI->getFrameIndexReference(*MF, EHGuardIdx, UnusedReg).getFixed();
1055  }
1056 
1057  AddComment("GSCookieOffset");
1058  OS.emitInt32(GSCookieOffset);
1059  AddComment("GSCookieXOROffset");
1060  OS.emitInt32(0);
1061  AddComment("EHCookieOffset");
1062  OS.emitInt32(EHCookieOffset);
1063  AddComment("EHCookieXOROffset");
1064  OS.emitInt32(0);
1065  BaseState = -2;
1066  }
1067 
1068  assert(!FuncInfo.SEHUnwindMap.empty());
1069  for (const SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
1070  auto *Handler = UME.Handler.get<MachineBasicBlock *>();
1071  const MCSymbol *ExceptOrFinally =
1072  UME.IsFinally ? getMCSymbolForMBB(Asm, Handler) : Handler->getSymbol();
1073  // -1 is usually the base state for "unwind to caller", but for
1074  // _except_handler4 it's -2. Do that replacement here if necessary.
1075  int ToState = UME.ToState == -1 ? BaseState : UME.ToState;
1076  AddComment("ToState");
1077  OS.emitInt32(ToState);
1078  AddComment(UME.IsFinally ? "Null" : "FilterFunction");
1079  OS.emitValue(create32bitRef(UME.Filter), 4);
1080  AddComment(UME.IsFinally ? "FinallyFunclet" : "ExceptionHandler");
1081  OS.emitValue(create32bitRef(ExceptOrFinally), 4);
1082  }
1083 }
1084 
1085 static int getTryRank(const WinEHFuncInfo &FuncInfo, int State) {
1086  int Rank = 0;
1087  while (State != -1) {
1088  ++Rank;
1089  State = FuncInfo.ClrEHUnwindMap[State].TryParentState;
1090  }
1091  return Rank;
1092 }
1093 
1094 static int getTryAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right) {
1095  int LeftRank = getTryRank(FuncInfo, Left);
1096  int RightRank = getTryRank(FuncInfo, Right);
1097 
1098  while (LeftRank < RightRank) {
1099  Right = FuncInfo.ClrEHUnwindMap[Right].TryParentState;
1100  --RightRank;
1101  }
1102 
1103  while (RightRank < LeftRank) {
1104  Left = FuncInfo.ClrEHUnwindMap[Left].TryParentState;
1105  --LeftRank;
1106  }
1107 
1108  while (Left != Right) {
1109  Left = FuncInfo.ClrEHUnwindMap[Left].TryParentState;
1110  Right = FuncInfo.ClrEHUnwindMap[Right].TryParentState;
1111  }
1112 
1113  return Left;
1114 }
1115 
1116 void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
1117  // CLR EH "states" are really just IDs that identify handlers/funclets;
1118  // states, handlers, and funclets all have 1:1 mappings between them, and a
1119  // handler/funclet's "state" is its index in the ClrEHUnwindMap.
1120  MCStreamer &OS = *Asm->OutStreamer;
1121  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
1122  MCSymbol *FuncBeginSym = Asm->getFunctionBegin();
1123  MCSymbol *FuncEndSym = Asm->getFunctionEnd();
1124 
1125  // A ClrClause describes a protected region.
1126  struct ClrClause {
1127  const MCSymbol *StartLabel; // Start of protected region
1128  const MCSymbol *EndLabel; // End of protected region
1129  int State; // Index of handler protecting the protected region
1130  int EnclosingState; // Index of funclet enclosing the protected region
1131  };
1132  SmallVector<ClrClause, 8> Clauses;
1133 
1134  // Build a map from handler MBBs to their corresponding states (i.e. their
1135  // indices in the ClrEHUnwindMap).
1136  int NumStates = FuncInfo.ClrEHUnwindMap.size();
1137  assert(NumStates > 0 && "Don't need exception table!");
1139  for (int State = 0; State < NumStates; ++State) {
1140  MachineBasicBlock *HandlerBlock =
1141  FuncInfo.ClrEHUnwindMap[State].Handler.get<MachineBasicBlock *>();
1142  HandlerStates[HandlerBlock] = State;
1143  // Use this loop through all handlers to verify our assumption (used in
1144  // the MinEnclosingState computation) that enclosing funclets have lower
1145  // state numbers than their enclosed funclets.
1146  assert(FuncInfo.ClrEHUnwindMap[State].HandlerParentState < State &&
1147  "ill-formed state numbering");
1148  }
1149  // Map the main function to the NullState.
1150  HandlerStates[&MF->front()] = NullState;
1151 
1152  // Write out a sentinel indicating the end of the standard (Windows) xdata
1153  // and the start of the additional (CLR) info.
1154  OS.emitInt32(0xffffffff);
1155  // Write out the number of funclets
1156  OS.emitInt32(NumStates);
1157 
1158  // Walk the machine blocks/instrs, computing and emitting a few things:
1159  // 1. Emit a list of the offsets to each handler entry, in lexical order.
1160  // 2. Compute a map (EndSymbolMap) from each funclet to the symbol at its end.
1161  // 3. Compute the list of ClrClauses, in the required order (inner before
1162  // outer, earlier before later; the order by which a forward scan with
1163  // early termination will find the innermost enclosing clause covering
1164  // a given address).
1165  // 4. A map (MinClauseMap) from each handler index to the index of the
1166  // outermost funclet/function which contains a try clause targeting the
1167  // key handler. This will be used to determine IsDuplicate-ness when
1168  // emitting ClrClauses. The NullState value is used to indicate that the
1169  // top-level function contains a try clause targeting the key handler.
1170  // HandlerStack is a stack of (PendingStartLabel, PendingState) pairs for
1171  // try regions we entered before entering the PendingState try but which
1172  // we haven't yet exited.
1174  // EndSymbolMap and MinClauseMap are maps described above.
1175  std::unique_ptr<MCSymbol *[]> EndSymbolMap(new MCSymbol *[NumStates]);
1176  SmallVector<int, 4> MinClauseMap((size_t)NumStates, NumStates);
1177 
1178  // Visit the root function and each funclet.
1179  for (MachineFunction::const_iterator FuncletStart = MF->begin(),
1180  FuncletEnd = MF->begin(),
1181  End = MF->end();
1182  FuncletStart != End; FuncletStart = FuncletEnd) {
1183  int FuncletState = HandlerStates[&*FuncletStart];
1184  // Find the end of the funclet
1185  MCSymbol *EndSymbol = FuncEndSym;
1186  while (++FuncletEnd != End) {
1187  if (FuncletEnd->isEHFuncletEntry()) {
1188  EndSymbol = getMCSymbolForMBB(Asm, &*FuncletEnd);
1189  break;
1190  }
1191  }
1192  // Emit the function/funclet end and, if this is a funclet (and not the
1193  // root function), record it in the EndSymbolMap.
1194  OS.emitValue(getOffset(EndSymbol, FuncBeginSym), 4);
1195  if (FuncletState != NullState) {
1196  // Record the end of the handler.
1197  EndSymbolMap[FuncletState] = EndSymbol;
1198  }
1199 
1200  // Walk the state changes in this function/funclet and compute its clauses.
1201  // Funclets always start in the null state.
1202  const MCSymbol *CurrentStartLabel = nullptr;
1203  int CurrentState = NullState;
1204  assert(HandlerStack.empty());
1205  for (const auto &StateChange :
1206  InvokeStateChangeIterator::range(FuncInfo, FuncletStart, FuncletEnd)) {
1207  // Close any try regions we're not still under
1208  int StillPendingState =
1209  getTryAncestor(FuncInfo, CurrentState, StateChange.NewState);
1210  while (CurrentState != StillPendingState) {
1211  assert(CurrentState != NullState &&
1212  "Failed to find still-pending state!");
1213  // Close the pending clause
1214  Clauses.push_back({CurrentStartLabel, StateChange.PreviousEndLabel,
1215  CurrentState, FuncletState});
1216  // Now the next-outer try region is current
1217  CurrentState = FuncInfo.ClrEHUnwindMap[CurrentState].TryParentState;
1218  // Pop the new start label from the handler stack if we've exited all
1219  // inner try regions of the corresponding try region.
1220  if (HandlerStack.back().second == CurrentState)
1221  CurrentStartLabel = HandlerStack.pop_back_val().first;
1222  }
1223 
1224  if (StateChange.NewState != CurrentState) {
1225  // For each clause we're starting, update the MinClauseMap so we can
1226  // know which is the topmost funclet containing a clause targeting
1227  // it.
1228  for (int EnteredState = StateChange.NewState;
1229  EnteredState != CurrentState;
1230  EnteredState =
1231  FuncInfo.ClrEHUnwindMap[EnteredState].TryParentState) {
1232  int &MinEnclosingState = MinClauseMap[EnteredState];
1233  if (FuncletState < MinEnclosingState)
1234  MinEnclosingState = FuncletState;
1235  }
1236  // Save the previous current start/label on the stack and update to
1237  // the newly-current start/state.
1238  HandlerStack.emplace_back(CurrentStartLabel, CurrentState);
1239  CurrentStartLabel = StateChange.NewStartLabel;
1240  CurrentState = StateChange.NewState;
1241  }
1242  }
1243  assert(HandlerStack.empty());
1244  }
1245 
1246  // Now emit the clause info, starting with the number of clauses.
1247  OS.emitInt32(Clauses.size());
1248  for (ClrClause &Clause : Clauses) {
1249  // Emit a CORINFO_EH_CLAUSE :
1250  /*
1251  struct CORINFO_EH_CLAUSE
1252  {
1253  CORINFO_EH_CLAUSE_FLAGS Flags; // actually a CorExceptionFlag
1254  DWORD TryOffset;
1255  DWORD TryLength; // actually TryEndOffset
1256  DWORD HandlerOffset;
1257  DWORD HandlerLength; // actually HandlerEndOffset
1258  union
1259  {
1260  DWORD ClassToken; // use for catch clauses
1261  DWORD FilterOffset; // use for filter clauses
1262  };
1263  };
1264 
1265  enum CORINFO_EH_CLAUSE_FLAGS
1266  {
1267  CORINFO_EH_CLAUSE_NONE = 0,
1268  CORINFO_EH_CLAUSE_FILTER = 0x0001, // This clause is for a filter
1269  CORINFO_EH_CLAUSE_FINALLY = 0x0002, // This clause is a finally clause
1270  CORINFO_EH_CLAUSE_FAULT = 0x0004, // This clause is a fault clause
1271  };
1272  typedef enum CorExceptionFlag
1273  {
1274  COR_ILEXCEPTION_CLAUSE_NONE,
1275  COR_ILEXCEPTION_CLAUSE_FILTER = 0x0001, // This is a filter clause
1276  COR_ILEXCEPTION_CLAUSE_FINALLY = 0x0002, // This is a finally clause
1277  COR_ILEXCEPTION_CLAUSE_FAULT = 0x0004, // This is a fault clause
1278  COR_ILEXCEPTION_CLAUSE_DUPLICATED = 0x0008, // duplicated clause. This
1279  // clause was duplicated
1280  // to a funclet which was
1281  // pulled out of line
1282  } CorExceptionFlag;
1283  */
1284  // Add 1 to the start/end of the EH clause; the IP associated with a
1285  // call when the runtime does its scan is the IP of the next instruction
1286  // (the one to which control will return after the call), so we need
1287  // to add 1 to the end of the clause to cover that offset. We also add
1288  // 1 to the start of the clause to make sure that the ranges reported
1289  // for all clauses are disjoint. Note that we'll need some additional
1290  // logic when machine traps are supported, since in that case the IP
1291  // that the runtime uses is the offset of the faulting instruction
1292  // itself; if such an instruction immediately follows a call but the
1293  // two belong to different clauses, we'll need to insert a nop between
1294  // them so the runtime can distinguish the point to which the call will
1295  // return from the point at which the fault occurs.
1296 
1297  const MCExpr *ClauseBegin =
1298  getOffsetPlusOne(Clause.StartLabel, FuncBeginSym);
1299  const MCExpr *ClauseEnd = getOffsetPlusOne(Clause.EndLabel, FuncBeginSym);
1300 
1301  const ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State];
1302  MachineBasicBlock *HandlerBlock = Entry.Handler.get<MachineBasicBlock *>();
1303  MCSymbol *BeginSym = getMCSymbolForMBB(Asm, HandlerBlock);
1304  const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym);
1305  MCSymbol *EndSym = EndSymbolMap[Clause.State];
1306  const MCExpr *HandlerEnd = getOffset(EndSym, FuncBeginSym);
1307 
1308  uint32_t Flags = 0;
1309  switch (Entry.HandlerType) {
1310  case ClrHandlerType::Catch:
1311  // Leaving bits 0-2 clear indicates catch.
1312  break;
1314  Flags |= 1;
1315  break;
1317  Flags |= 2;
1318  break;
1319  case ClrHandlerType::Fault:
1320  Flags |= 4;
1321  break;
1322  }
1323  if (Clause.EnclosingState != MinClauseMap[Clause.State]) {
1324  // This is a "duplicate" clause; the handler needs to be entered from a
1325  // frame above the one holding the invoke.
1326  assert(Clause.EnclosingState > MinClauseMap[Clause.State]);
1327  Flags |= 8;
1328  }
1329  OS.emitInt32(Flags);
1330 
1331  // Write the clause start/end
1332  OS.emitValue(ClauseBegin, 4);
1333  OS.emitValue(ClauseEnd, 4);
1334 
1335  // Write out the handler start/end
1336  OS.emitValue(HandlerBegin, 4);
1337  OS.emitValue(HandlerEnd, 4);
1338 
1339  // Write out the type token or filter offset
1340  assert(Entry.HandlerType != ClrHandlerType::Filter && "NYI: filters");
1341  OS.emitInt32(Entry.TypeToken);
1342  }
1343 }
llvm::MachineFunction::hasWinCFI
bool hasWinCFI() const
Definition: MachineFunction.h:722
llvm::EHPersonality::MSVC_CXX
@ MSVC_CXX
AsmPrinter.h
llvm::MCContext::getObjectFileInfo
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:443
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:1788
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::AsmPrinter::getFunctionEnd
MCSymbol * getFunctionEnd() const
Definition: AsmPrinter.h:264
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:209
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:223
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:487
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:74
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:592
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:87
llvm::MachineBasicBlock::isEHFuncletEntry
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
Definition: MachineBasicBlock.h:574
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:1185
llvm::MachineFunction::end
iterator end()
Definition: MachineFunction.h:824
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:264
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:2650
Module.h
llvm::MCStreamer::emitInt32
void emitInt32(uint64_t Value)
Definition: MCStreamer.h:727
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:2004
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:654
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:228
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:21
llvm::AlignStyle::Left
@ Left
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:201
llvm::WinEHFuncInfo::FuncletBaseStateMap
DenseMap< const FuncletPadInst *, int > FuncletBaseStateMap
Definition: WinEHFuncInfo.h:92
TargetLowering.h
llvm::MachineFunction::front
const MachineBasicBlock & front() const
Definition: MachineFunction.h:834
llvm::MCContext::getOrCreateSymbol
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:204
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:96
Twine.h
llvm::Triple::isAArch64
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
Definition: Triple.h:809
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:416
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:118
llvm::ClrHandlerType::Fault
@ Fault
llvm::MachineFunction::begin
iterator begin()
Definition: MachineFunction.h:822
llvm::MachineBasicBlock::isCleanupFuncletEntry
bool isCleanupFuncletEntry() const
Returns true if this is the entry block of a cleanup funclet.
Definition: MachineBasicBlock.h:580
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:263
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:640
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:751
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:239
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:412
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:359
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:716
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:1241
llvm::WinEHHandlerType::CatchObj
union llvm::WinEHHandlerType::@234 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
llvm::concat
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&... Ranges)
Concatenated range across two or more ranges.
Definition: STLExtras.h:1075
llvm::MachineBasicBlock::getAlignment
Align getAlignment() const
Return alignment of the basic block.
Definition: MachineBasicBlock.h:528
llvm::MCObjectFileInfo::getGEHContSection
MCSection * getGEHContSection() const
Definition: MCObjectFileInfo.h:424
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:654
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:656
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:234
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:2002
llvm::AsmPrinter::MF
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:99
llvm::MachineFunction::getLandingPads
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
Definition: MachineFunction.h:1078
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:91
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:241
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:2126
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:1078
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: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:305
llvm::MCContext::createTempSymbol
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:321
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:83
llvm::pdb::PDB_SymType::Label
@ Label
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:606
llvm::TargetSubtargetInfo::getFrameLowering
virtual const TargetFrameLowering * getFrameLowering() const
Definition: TargetSubtargetInfo.h:94
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:684
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:81
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:1067
getTryRank
static int getTryRank(const WinEHFuncInfo &FuncInfo, int State)
Definition: WinException.cpp:1085
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:105
llvm::AsmPrinter::TM
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:84
llvm::TargetSubtargetInfo::getTargetLowering
virtual const TargetLowering * getTargetLowering() const
Definition: TargetSubtargetInfo.h:97
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:277
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:382
MCStreamer.h
llvm::dwarf::DW_EH_PE_omit
@ DW_EH_PE_omit
Definition: Dwarf.h:438
llvm::TargetMachine::getTargetTriple
const Triple & getTargetTriple() const
Definition: TargetMachine.h:126
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:138
llvm::MCStreamer::isVerboseAsm
virtual bool isVerboseAsm() const
Return true if this streamer supports verbose assembly and if it is enabled.
Definition: MCStreamer.h:321
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:1205
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::MachineFrameInfo::getStackProtectorIndex
int getStackProtectorIndex() const
Return the index for the stack protector object.
Definition: MachineFrameInfo.h:357
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:1042
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:260
llvm::MachineInstrBundleIterator< const MachineInstr >
llvm::MCAsmInfo::usesWindowsCFI
bool usesWindowsCFI() const
Definition: MCAsmInfo.h:793
llvm::MachineFunction::getAlignment
Align getAlignment() const
getAlignment - Return the alignment of the function.
Definition: MachineFunction.h:688
MCExpr.h
llvm::MachineModuleInfo::getModule
const Module * getModule() const
Definition: MachineModuleInfo.h:151
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:344
getTryAncestor
static int getTryAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right)
Definition: WinException.cpp:1094
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:927