LLVM  14.0.0git
WinException.cpp
Go to the documentation of this file.
1 //===-- CodeGen/AsmPrinter/WinException.cpp - Dwarf Exception Impl ------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains support for writing Win64 exception info into asm files.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "WinException.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/BinaryFormat/COFF.h"
25 #include "llvm/IR/DataLayout.h"
26 #include "llvm/IR/Mangler.h"
27 #include "llvm/IR/Module.h"
28 #include "llvm/MC/MCAsmInfo.h"
29 #include "llvm/MC/MCContext.h"
30 #include "llvm/MC/MCExpr.h"
31 #include "llvm/MC/MCSection.h"
32 #include "llvm/MC/MCStreamer.h"
33 #include "llvm/MC/MCSymbol.h"
39 using namespace llvm;
40 
42  // MSVC's EH tables are always composed of 32-bit words. All known 64-bit
43  // platforms use an imagerel32 relocation to refer to symbols.
44  useImageRel32 = (A->getDataLayout().getPointerSizeInBits() == 64);
45  isAArch64 = Asm->TM.getTargetTriple().isAArch64();
46  isThumb = Asm->TM.getTargetTriple().isThumb();
47 }
48 
50 
51 /// endModule - Emit all exception information that should come after the
52 /// content.
54  auto &OS = *Asm->OutStreamer;
55  const Module *M = MMI->getModule();
56  for (const Function &F : *M)
57  if (F.hasFnAttribute("safeseh"))
58  OS.EmitCOFFSafeSEH(Asm->getSymbol(&F));
59 
60  if (M->getModuleFlag("ehcontguard") && !EHContTargets.empty()) {
61  // Emit the symbol index of each ehcont target.
62  OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGEHContSection());
63  for (const MCSymbol *S : EHContTargets) {
64  OS.EmitCOFFSymbolIndex(S);
65  }
66  }
67 }
68 
70  shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
71 
72  // If any landing pads survive, we need an EH table.
73  bool hasLandingPads = !MF->getLandingPads().empty();
74  bool hasEHFunclets = MF->hasEHFunclets();
75 
76  const Function &F = MF->getFunction();
77 
78  shouldEmitMoves = Asm->needsSEHMoves() && MF->hasWinCFI();
79 
81  unsigned PerEncoding = TLOF.getPersonalityEncoding();
82 
84  const Function *PerFn = nullptr;
85  if (F.hasPersonalityFn()) {
86  PerFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
87  Per = classifyEHPersonality(PerFn);
88  }
89 
90  bool forceEmitPersonality = F.hasPersonalityFn() &&
91  !isNoOpWithoutInvoke(Per) &&
92  F.needsUnwindTableEntry();
93 
94  shouldEmitPersonality =
95  forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
96  PerEncoding != dwarf::DW_EH_PE_omit && PerFn);
97 
98  unsigned LSDAEncoding = TLOF.getLSDAEncoding();
99  shouldEmitLSDA = shouldEmitPersonality &&
100  LSDAEncoding != dwarf::DW_EH_PE_omit;
101 
102  // If we're not using CFI, we don't want the CFI or the personality, but we
103  // might want EH tables if we had EH pads.
104  if (!Asm->MAI->usesWindowsCFI()) {
105  if (Per == EHPersonality::MSVC_X86SEH && !hasEHFunclets) {
106  // If this is 32-bit SEH and we don't have any funclets (really invokes),
107  // make sure we emit the parent offset label. Some unreferenced filter
108  // functions may still refer to it.
109  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
110  StringRef FLinkageName =
112  emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
113  }
114  shouldEmitLSDA = hasEHFunclets;
115  shouldEmitPersonality = false;
116  return;
117  }
118 
120 }
121 
123  if (isAArch64 && CurrentFuncletEntry &&
124  (shouldEmitMoves || shouldEmitPersonality))
125  Asm->OutStreamer->EmitWinCFIFuncletOrFuncEnd();
126 }
127 
128 /// endFunction - Gather and emit post-function exception information.
129 ///
131  if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA)
132  return;
133 
134  const Function &F = MF->getFunction();
136  if (F.hasPersonalityFn())
137  Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts());
138 
139  // Get rid of any dead landing pads if we're not using funclets. In funclet
140  // schemes, the landing pad is not actually reachable. It only exists so
141  // that we can emit the right table data.
142  if (!isFuncletEHPersonality(Per)) {
143  MachineFunction *NonConstMF = const_cast<MachineFunction*>(MF);
144  NonConstMF->tidyLandingPads();
145  }
146 
147  endFuncletImpl();
148 
149  // endFunclet will emit the necessary .xdata tables for table-based SEH.
150  if (Per == EHPersonality::MSVC_TableSEH && MF->hasEHFunclets())
151  return;
152 
153  if (shouldEmitPersonality || shouldEmitLSDA) {
154  Asm->OutStreamer->PushSection();
155 
156  // Just switch sections to the right xdata section.
157  MCSection *XData = Asm->OutStreamer->getAssociatedXDataSection(
158  Asm->OutStreamer->getCurrentSectionOnly());
159  Asm->OutStreamer->SwitchSection(XData);
160 
161  // Emit the tables appropriate to the personality function in use. If we
162  // don't recognize the personality, assume it uses an Itanium-style LSDA.
163  if (Per == EHPersonality::MSVC_TableSEH)
164  emitCSpecificHandlerTable(MF);
165  else if (Per == EHPersonality::MSVC_X86SEH)
166  emitExceptHandlerTable(MF);
167  else if (Per == EHPersonality::MSVC_CXX)
168  emitCXXFrameHandler3Table(MF);
169  else if (Per == EHPersonality::CoreCLR)
170  emitCLRExceptionTable(MF);
171  else
173 
174  Asm->OutStreamer->PopSection();
175  }
176 
177  if (!MF->getCatchretTargets().empty()) {
178  // Copy the function's catchret targets to a module-level list.
179  EHContTargets.insert(EHContTargets.end(), MF->getCatchretTargets().begin(),
180  MF->getCatchretTargets().end());
181  }
182 }
183 
184 /// Retrieve the MCSymbol for a GlobalValue or MachineBasicBlock.
186  const MachineBasicBlock *MBB) {
187  if (!MBB)
188  return nullptr;
189 
191 
192  // Give catches and cleanups a name based off of their parent function and
193  // their funclet entry block's number.
194  const MachineFunction *MF = MBB->getParent();
195  const Function &F = MF->getFunction();
196  StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
197  MCContext &Ctx = MF->getContext();
198  StringRef HandlerPrefix = MBB->isCleanupFuncletEntry() ? "dtor" : "catch";
199  return Ctx.getOrCreateSymbol("?" + HandlerPrefix + "$" +
200  Twine(MBB->getNumber()) + "@?0?" +
201  FuncLinkageName + "@4HA");
202 }
203 
205  MCSymbol *Sym) {
206  CurrentFuncletEntry = &MBB;
207 
208  const Function &F = Asm->MF->getFunction();
209  // If a symbol was not provided for the funclet, invent one.
210  if (!Sym) {
211  Sym = getMCSymbolForMBB(Asm, &MBB);
212 
213  // Describe our funclet symbol as a function with internal linkage.
214  Asm->OutStreamer->BeginCOFFSymbolDef(Sym);
215  Asm->OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
216  Asm->OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
218  Asm->OutStreamer->EndCOFFSymbolDef();
219 
220  // We want our funclet's entry point to be aligned such that no nops will be
221  // present after the label.
223  &F);
224 
225  // Now that we've emitted the alignment directive, point at our funclet.
226  Asm->OutStreamer->emitLabel(Sym);
227  }
228 
229  // Mark 'Sym' as starting our funclet.
230  if (shouldEmitMoves || shouldEmitPersonality) {
231  CurrentFuncletTextSection = Asm->OutStreamer->getCurrentSectionOnly();
232  Asm->OutStreamer->EmitWinCFIStartProc(Sym);
233  }
234 
235  if (shouldEmitPersonality) {
237  const Function *PerFn = nullptr;
238 
239  // Determine which personality routine we are using for this funclet.
240  if (F.hasPersonalityFn())
241  PerFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
242  const MCSymbol *PersHandlerSym =
243  TLOF.getCFIPersonalitySymbol(PerFn, Asm->TM, MMI);
244 
245  // Do not emit a .seh_handler directives for cleanup funclets.
246  // FIXME: This means cleanup funclets cannot handle exceptions. Given that
247  // Clang doesn't produce EH constructs inside cleanup funclets and LLVM's
248  // inliner doesn't allow inlining them, this isn't a major problem in
249  // practice.
250  if (!CurrentFuncletEntry->isCleanupFuncletEntry())
251  Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true);
252  }
253 }
254 
256  if (isAArch64 && CurrentFuncletEntry &&
257  (shouldEmitMoves || shouldEmitPersonality)) {
258  Asm->OutStreamer->SwitchSection(CurrentFuncletTextSection);
259  Asm->OutStreamer->EmitWinCFIFuncletOrFuncEnd();
260  }
261  endFuncletImpl();
262 }
263 
264 void WinException::endFuncletImpl() {
265  // No funclet to process? Great, we have nothing to do.
266  if (!CurrentFuncletEntry)
267  return;
268 
269  const MachineFunction *MF = Asm->MF;
270  if (shouldEmitMoves || shouldEmitPersonality) {
271  const Function &F = MF->getFunction();
273  if (F.hasPersonalityFn())
274  Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts());
275 
276  if (Per == EHPersonality::MSVC_CXX && shouldEmitPersonality &&
277  !CurrentFuncletEntry->isCleanupFuncletEntry()) {
278  // Emit an UNWIND_INFO struct describing the prologue.
279  Asm->OutStreamer->EmitWinEHHandlerData();
280 
281  // If this is a C++ catch funclet (or the parent function),
282  // emit a reference to the LSDA for the parent function.
283  StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
284  MCSymbol *FuncInfoXData = Asm->OutContext.getOrCreateSymbol(
285  Twine("$cppxdata$", FuncLinkageName));
286  Asm->OutStreamer->emitValue(create32bitRef(FuncInfoXData), 4);
287  } else if (Per == EHPersonality::MSVC_TableSEH && MF->hasEHFunclets() &&
288  !CurrentFuncletEntry->isEHFuncletEntry()) {
289  // Emit an UNWIND_INFO struct describing the prologue.
290  Asm->OutStreamer->EmitWinEHHandlerData();
291 
292  // If this is the parent function in Win64 SEH, emit the LSDA immediately
293  // following .seh_handlerdata.
294  emitCSpecificHandlerTable(MF);
295  } else if (shouldEmitPersonality || shouldEmitLSDA) {
296  // Emit an UNWIND_INFO struct describing the prologue.
297  Asm->OutStreamer->EmitWinEHHandlerData();
298  // In these cases, no further info is written to the .xdata section
299  // right here, but is written by e.g. emitExceptionTable in endFunction()
300  // above.
301  } else {
302  // No need to emit the EH handler data right here if nothing needs
303  // writing to the .xdata section; it will be emitted for all
304  // functions that need it in the end anyway.
305  }
306 
307  // Switch back to the funclet start .text section now that we are done
308  // writing to .xdata, and emit an .seh_endproc directive to mark the end of
309  // the function.
310  Asm->OutStreamer->SwitchSection(CurrentFuncletTextSection);
311  Asm->OutStreamer->EmitWinCFIEndProc();
312  }
313 
314  // Let's make sure we don't try to end the same funclet twice.
315  CurrentFuncletEntry = nullptr;
316 }
317 
318 const MCExpr *WinException::create32bitRef(const MCSymbol *Value) {
319  if (!Value)
321  return MCSymbolRefExpr::create(Value, useImageRel32
324  Asm->OutContext);
325 }
326 
327 const MCExpr *WinException::create32bitRef(const GlobalValue *GV) {
328  if (!GV)
330  return create32bitRef(Asm->getSymbol(GV));
331 }
332 
333 const MCExpr *WinException::getLabel(const MCSymbol *Label) {
335  Asm->OutContext);
336 }
337 
338 const MCExpr *WinException::getLabelPlusOne(const MCSymbol *Label) {
339  return MCBinaryExpr::createAdd(getLabel(Label),
341  Asm->OutContext);
342 }
343 
344 const MCExpr *WinException::getOffset(const MCSymbol *OffsetOf,
345  const MCSymbol *OffsetFrom) {
349 }
350 
351 const MCExpr *WinException::getOffsetPlusOne(const MCSymbol *OffsetOf,
352  const MCSymbol *OffsetFrom) {
353  return MCBinaryExpr::createAdd(getOffset(OffsetOf, OffsetFrom),
355  Asm->OutContext);
356 }
357 
358 int WinException::getFrameIndexOffset(int FrameIndex,
359  const WinEHFuncInfo &FuncInfo) {
361  Register UnusedReg;
362  if (Asm->MAI->usesWindowsCFI()) {
365  /*IgnoreSPUpdates*/ true);
366  assert(UnusedReg ==
367  Asm->MF->getSubtarget()
370  return Offset.getFixed();
371  }
372 
373  // For 32-bit, offsets should be relative to the end of the EH registration
374  // node. For 64-bit, it's relative to SP at the end of the prologue.
375  assert(FuncInfo.EHRegNodeEndOffset != INT_MAX);
378  assert(!Offset.getScalable() &&
379  "Frame offsets with a scalable component are not supported");
380  return Offset.getFixed();
381 }
382 
383 namespace {
384 
385 /// Top-level state used to represent unwind to caller
386 const int NullState = -1;
387 
388 struct InvokeStateChange {
389  /// EH Label immediately after the last invoke in the previous state, or
390  /// nullptr if the previous state was the null state.
391  const MCSymbol *PreviousEndLabel;
392 
393  /// EH label immediately before the first invoke in the new state, or nullptr
394  /// if the new state is the null state.
395  const MCSymbol *NewStartLabel;
396 
397  /// State of the invoke following NewStartLabel, or NullState to indicate
398  /// the presence of calls which may unwind to caller.
399  int NewState;
400 };
401 
402 /// Iterator that reports all the invoke state changes in a range of machine
403 /// basic blocks. Changes to the null state are reported whenever a call that
404 /// may unwind to caller is encountered. The MBB range is expected to be an
405 /// entire function or funclet, and the start and end of the range are treated
406 /// as being in the NullState even if there's not an unwind-to-caller call
407 /// before the first invoke or after the last one (i.e., the first state change
408 /// reported is the first change to something other than NullState, and a
409 /// change back to NullState is always reported at the end of iteration).
410 class InvokeStateChangeIterator {
411  InvokeStateChangeIterator(const WinEHFuncInfo &EHInfo,
415  int BaseState)
416  : EHInfo(EHInfo), MFI(MFI), MFE(MFE), MBBI(MBBI), BaseState(BaseState) {
417  LastStateChange.PreviousEndLabel = nullptr;
418  LastStateChange.NewStartLabel = nullptr;
419  LastStateChange.NewState = BaseState;
420  scan();
421  }
422 
423 public:
425  range(const WinEHFuncInfo &EHInfo, MachineFunction::const_iterator Begin,
426  MachineFunction::const_iterator End, int BaseState = NullState) {
427  // Reject empty ranges to simplify bookkeeping by ensuring that we can get
428  // the end of the last block.
429  assert(Begin != End);
430  auto BlockBegin = Begin->begin();
431  auto BlockEnd = std::prev(End)->end();
432  return make_range(
433  InvokeStateChangeIterator(EHInfo, Begin, End, BlockBegin, BaseState),
434  InvokeStateChangeIterator(EHInfo, End, End, BlockEnd, BaseState));
435  }
436 
437  // Iterator methods.
438  bool operator==(const InvokeStateChangeIterator &O) const {
439  assert(BaseState == O.BaseState);
440  // Must be visiting same block.
441  if (MFI != O.MFI)
442  return false;
443  // Must be visiting same isntr.
444  if (MBBI != O.MBBI)
445  return false;
446  // At end of block/instr iteration, we can still have two distinct states:
447  // one to report the final EndLabel, and another indicating the end of the
448  // state change iteration. Check for CurrentEndLabel equality to
449  // distinguish these.
450  return CurrentEndLabel == O.CurrentEndLabel;
451  }
452 
453  bool operator!=(const InvokeStateChangeIterator &O) const {
454  return !operator==(O);
455  }
456  InvokeStateChange &operator*() { return LastStateChange; }
457  InvokeStateChange *operator->() { return &LastStateChange; }
458  InvokeStateChangeIterator &operator++() { return scan(); }
459 
460 private:
461  InvokeStateChangeIterator &scan();
462 
463  const WinEHFuncInfo &EHInfo;
464  const MCSymbol *CurrentEndLabel = nullptr;
468  InvokeStateChange LastStateChange;
469  bool VisitingInvoke = false;
470  int BaseState;
471 };
472 
473 } // end anonymous namespace
474 
475 InvokeStateChangeIterator &InvokeStateChangeIterator::scan() {
476  bool IsNewBlock = false;
477  for (; MFI != MFE; ++MFI, IsNewBlock = true) {
478  if (IsNewBlock)
479  MBBI = MFI->begin();
480  for (auto MBBE = MFI->end(); MBBI != MBBE; ++MBBI) {
481  const MachineInstr &MI = *MBBI;
482  if (!VisitingInvoke && LastStateChange.NewState != BaseState &&
483  MI.isCall() && !EHStreamer::callToNoUnwindFunction(&MI)) {
484  // Indicate a change of state to the null state. We don't have
485  // start/end EH labels handy but the caller won't expect them for
486  // null state regions.
487  LastStateChange.PreviousEndLabel = CurrentEndLabel;
488  LastStateChange.NewStartLabel = nullptr;
489  LastStateChange.NewState = BaseState;
490  CurrentEndLabel = nullptr;
491  // Don't re-visit this instr on the next scan
492  ++MBBI;
493  return *this;
494  }
495 
496  // All other state changes are at EH labels before/after invokes.
497  if (!MI.isEHLabel())
498  continue;
499  MCSymbol *Label = MI.getOperand(0).getMCSymbol();
500  if (Label == CurrentEndLabel) {
501  VisitingInvoke = false;
502  continue;
503  }
504  auto InvokeMapIter = EHInfo.LabelToStateMap.find(Label);
505  // Ignore EH labels that aren't the ones inserted before an invoke
506  if (InvokeMapIter == EHInfo.LabelToStateMap.end())
507  continue;
508  auto &StateAndEnd = InvokeMapIter->second;
509  int NewState = StateAndEnd.first;
510  // Keep track of the fact that we're between EH start/end labels so
511  // we know not to treat the inoke we'll see as unwinding to caller.
512  VisitingInvoke = true;
513  if (NewState == LastStateChange.NewState) {
514  // The state isn't actually changing here. Record the new end and
515  // keep going.
516  CurrentEndLabel = StateAndEnd.second;
517  continue;
518  }
519  // Found a state change to report
520  LastStateChange.PreviousEndLabel = CurrentEndLabel;
521  LastStateChange.NewStartLabel = Label;
522  LastStateChange.NewState = NewState;
523  // Start keeping track of the new current end
524  CurrentEndLabel = StateAndEnd.second;
525  // Don't re-visit this instr on the next scan
526  ++MBBI;
527  return *this;
528  }
529  }
530  // Iteration hit the end of the block range.
531  if (LastStateChange.NewState != BaseState) {
532  // Report the end of the last new state
533  LastStateChange.PreviousEndLabel = CurrentEndLabel;
534  LastStateChange.NewStartLabel = nullptr;
535  LastStateChange.NewState = BaseState;
536  // Leave CurrentEndLabel non-null to distinguish this state from end.
537  assert(CurrentEndLabel != nullptr);
538  return *this;
539  }
540  // We've reported all state changes and hit the end state.
541  CurrentEndLabel = nullptr;
542  return *this;
543 }
544 
545 /// Emit the language-specific data that __C_specific_handler expects. This
546 /// handler lives in the x64 Microsoft C runtime and allows catching or cleaning
547 /// up after faults with __try, __except, and __finally. The typeinfo values
548 /// are not really RTTI data, but pointers to filter functions that return an
549 /// integer (1, 0, or -1) indicating how to handle the exception. For __finally
550 /// blocks and other cleanups, the landing pad label is zero, and the filter
551 /// function is actually a cleanup handler with the same prototype. A catch-all
552 /// entry is modeled with a null filter function field and a non-zero landing
553 /// pad label.
554 ///
555 /// Possible filter function return values:
556 /// EXCEPTION_EXECUTE_HANDLER (1):
557 /// Jump to the landing pad label after cleanups.
558 /// EXCEPTION_CONTINUE_SEARCH (0):
559 /// Continue searching this table or continue unwinding.
560 /// EXCEPTION_CONTINUE_EXECUTION (-1):
561 /// Resume execution at the trapping PC.
562 ///
563 /// Inferred table structure:
564 /// struct Table {
565 /// int NumEntries;
566 /// struct Entry {
567 /// imagerel32 LabelStart; // Inclusive
568 /// imagerel32 LabelEnd; // Exclusive
569 /// imagerel32 FilterOrFinally; // One means catch-all.
570 /// imagerel32 LabelLPad; // Zero means __finally.
571 /// } Entries[NumEntries];
572 /// };
573 void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
574  auto &OS = *Asm->OutStreamer;
575  MCContext &Ctx = Asm->OutContext;
576  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
577 
578  bool VerboseAsm = OS.isVerboseAsm();
579  auto AddComment = [&](const Twine &Comment) {
580  if (VerboseAsm)
581  OS.AddComment(Comment);
582  };
583 
584  if (!isAArch64) {
585  // Emit a label assignment with the SEH frame offset so we can use it for
586  // llvm.eh.recoverfp.
587  StringRef FLinkageName =
589  MCSymbol *ParentFrameOffset =
590  Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName);
591  const MCExpr *MCOffset =
593  Asm->OutStreamer->emitAssignment(ParentFrameOffset, MCOffset);
594  }
595 
596  // Use the assembler to compute the number of table entries through label
597  // difference and division.
598  MCSymbol *TableBegin =
599  Ctx.createTempSymbol("lsda_begin", /*AlwaysAddSuffix=*/true);
600  MCSymbol *TableEnd =
601  Ctx.createTempSymbol("lsda_end", /*AlwaysAddSuffix=*/true);
602  const MCExpr *LabelDiff = getOffset(TableEnd, TableBegin);
603  const MCExpr *EntrySize = MCConstantExpr::create(16, Ctx);
604  const MCExpr *EntryCount = MCBinaryExpr::createDiv(LabelDiff, EntrySize, Ctx);
605  AddComment("Number of call sites");
606  OS.emitValue(EntryCount, 4);
607 
608  OS.emitLabel(TableBegin);
609 
610  // Iterate over all the invoke try ranges. Unlike MSVC, LLVM currently only
611  // models exceptions from invokes. LLVM also allows arbitrary reordering of
612  // the code, so our tables end up looking a bit different. Rather than
613  // trying to match MSVC's tables exactly, we emit a denormalized table. For
614  // each range of invokes in the same state, we emit table entries for all
615  // the actions that would be taken in that state. This means our tables are
616  // slightly bigger, which is OK.
617  const MCSymbol *LastStartLabel = nullptr;
618  int LastEHState = -1;
619  // Break out before we enter into a finally funclet.
620  // FIXME: We need to emit separate EH tables for cleanups.
622  MachineFunction::const_iterator Stop = std::next(MF->begin());
623  while (Stop != End && !Stop->isEHFuncletEntry())
624  ++Stop;
625  for (const auto &StateChange :
626  InvokeStateChangeIterator::range(FuncInfo, MF->begin(), Stop)) {
627  // Emit all the actions for the state we just transitioned out of
628  // if it was not the null state
629  if (LastEHState != -1)
630  emitSEHActionsForRange(FuncInfo, LastStartLabel,
631  StateChange.PreviousEndLabel, LastEHState);
632  LastStartLabel = StateChange.NewStartLabel;
633  LastEHState = StateChange.NewState;
634  }
635 
636  OS.emitLabel(TableEnd);
637 }
638 
639 void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
640  const MCSymbol *BeginLabel,
641  const MCSymbol *EndLabel, int State) {
642  auto &OS = *Asm->OutStreamer;
643  MCContext &Ctx = Asm->OutContext;
644  bool VerboseAsm = OS.isVerboseAsm();
645  auto AddComment = [&](const Twine &Comment) {
646  if (VerboseAsm)
647  OS.AddComment(Comment);
648  };
649 
650  assert(BeginLabel && EndLabel);
651  while (State != -1) {
652  const SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
653  const MCExpr *FilterOrFinally;
654  const MCExpr *ExceptOrNull;
655  auto *Handler = UME.Handler.get<MachineBasicBlock *>();
656  if (UME.IsFinally) {
657  FilterOrFinally = create32bitRef(getMCSymbolForMBB(Asm, Handler));
658  ExceptOrNull = MCConstantExpr::create(0, Ctx);
659  } else {
660  // For an except, the filter can be 1 (catch-all) or a function
661  // label.
662  FilterOrFinally = UME.Filter ? create32bitRef(UME.Filter)
663  : MCConstantExpr::create(1, Ctx);
664  ExceptOrNull = create32bitRef(Handler->getSymbol());
665  }
666 
667  AddComment("LabelStart");
668  OS.emitValue(getLabel(BeginLabel), 4);
669  AddComment("LabelEnd");
670  OS.emitValue(getLabelPlusOne(EndLabel), 4);
671  AddComment(UME.IsFinally ? "FinallyFunclet" : UME.Filter ? "FilterFunction"
672  : "CatchAll");
673  OS.emitValue(FilterOrFinally, 4);
674  AddComment(UME.IsFinally ? "Null" : "ExceptionHandler");
675  OS.emitValue(ExceptOrNull, 4);
676 
677  assert(UME.ToState < State && "states should decrease");
678  State = UME.ToState;
679  }
680 }
681 
682 void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
683  const Function &F = MF->getFunction();
684  auto &OS = *Asm->OutStreamer;
685  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
686 
687  StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
688 
690  MCSymbol *FuncInfoXData = nullptr;
691  if (shouldEmitPersonality) {
692  // If we're 64-bit, emit a pointer to the C++ EH data, and build a map from
693  // IPs to state numbers.
694  FuncInfoXData =
695  Asm->OutContext.getOrCreateSymbol(Twine("$cppxdata$", FuncLinkageName));
696  computeIP2StateTable(MF, FuncInfo, IPToStateTable);
697  } else {
698  FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(FuncLinkageName);
699  }
700 
701  int UnwindHelpOffset = 0;
702  if (Asm->MAI->usesWindowsCFI())
703  UnwindHelpOffset =
704  getFrameIndexOffset(FuncInfo.UnwindHelpFrameIdx, FuncInfo);
705 
706  MCSymbol *UnwindMapXData = nullptr;
707  MCSymbol *TryBlockMapXData = nullptr;
708  MCSymbol *IPToStateXData = nullptr;
709  if (!FuncInfo.CxxUnwindMap.empty())
710  UnwindMapXData = Asm->OutContext.getOrCreateSymbol(
711  Twine("$stateUnwindMap$", FuncLinkageName));
712  if (!FuncInfo.TryBlockMap.empty())
713  TryBlockMapXData =
714  Asm->OutContext.getOrCreateSymbol(Twine("$tryMap$", FuncLinkageName));
715  if (!IPToStateTable.empty())
716  IPToStateXData =
717  Asm->OutContext.getOrCreateSymbol(Twine("$ip2state$", FuncLinkageName));
718 
719  bool VerboseAsm = OS.isVerboseAsm();
720  auto AddComment = [&](const Twine &Comment) {
721  if (VerboseAsm)
722  OS.AddComment(Comment);
723  };
724 
725  // FuncInfo {
726  // uint32_t MagicNumber
727  // int32_t MaxState;
728  // UnwindMapEntry *UnwindMap;
729  // uint32_t NumTryBlocks;
730  // TryBlockMapEntry *TryBlockMap;
731  // uint32_t IPMapEntries; // always 0 for x86
732  // IPToStateMapEntry *IPToStateMap; // always 0 for x86
733  // uint32_t UnwindHelp; // non-x86 only
734  // ESTypeList *ESTypeList;
735  // int32_t EHFlags;
736  // }
737  // EHFlags & 1 -> Synchronous exceptions only, no async exceptions.
738  // EHFlags & 2 -> ???
739  // EHFlags & 4 -> The function is noexcept(true), unwinding can't continue.
740  OS.emitValueToAlignment(4);
741  OS.emitLabel(FuncInfoXData);
742 
743  AddComment("MagicNumber");
744  OS.emitInt32(0x19930522);
745 
746  AddComment("MaxState");
747  OS.emitInt32(FuncInfo.CxxUnwindMap.size());
748 
749  AddComment("UnwindMap");
750  OS.emitValue(create32bitRef(UnwindMapXData), 4);
751 
752  AddComment("NumTryBlocks");
753  OS.emitInt32(FuncInfo.TryBlockMap.size());
754 
755  AddComment("TryBlockMap");
756  OS.emitValue(create32bitRef(TryBlockMapXData), 4);
757 
758  AddComment("IPMapEntries");
759  OS.emitInt32(IPToStateTable.size());
760 
761  AddComment("IPToStateXData");
762  OS.emitValue(create32bitRef(IPToStateXData), 4);
763 
764  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,
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(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:716
llvm::EHPersonality::MSVC_CXX
@ MSVC_CXX
AsmPrinter.h
llvm::MCContext::getObjectFileInfo
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:427
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:1746
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::AsmPrinter::getFunctionEnd
MCSymbol * getFunctionEnd() const
Definition: AsmPrinter.h:247
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:130
llvm::MCContext::getOrCreateParentFrameOffsetSymbol
MCSymbol * getOrCreateParentFrameOffsetSymbol(StringRef FuncName)
Definition: MCContext.cpp:210
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:488
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
llvm::Function
Definition: Function.h:62
llvm::EHStreamer
Emits exception handling directives.
Definition: EHStreamer.h:30
llvm::MachineFunction::getContext
MCContext & getContext() const
Definition: MachineFunction.h:586
llvm::WinException::beginFunclet
void beginFunclet(const MachineBasicBlock &MBB, MCSymbol *Sym) override
Emit target-specific EH funclet machinery.
Definition: WinException.cpp:204
llvm::WinEHFuncInfo::ClrEHUnwindMap
SmallVector< ClrEHUnwindMapEntry, 4 > ClrEHUnwindMap
Definition: WinEHFuncInfo.h:98
llvm::WinException::markFunctionEnd
void markFunctionEnd() override
Definition: WinException.cpp:122
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:552
llvm::MCConstantExpr::create
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::MachineFunction::end
iterator end()
Definition: MachineFunction.h:818
llvm::WinException::endModule
void endModule() override
Emit all exception information that should come after the content.
Definition: WinException.cpp:53
ErrorHandling.h
llvm::WinEHHandlerType::FrameIndex
int FrameIndex
Definition: WinEHFuncInfo.h:66
llvm::WinEHHandlerType
Definition: WinEHFuncInfo.h:60
llvm::COFF::SCT_COMPLEX_TYPE_SHIFT
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
Definition: COFF.h:265
Right
Vector Shift Left Right
Definition: README_P9.txt:118
COFF.h
llvm::MCStreamer::emitValue
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:177
llvm::StackOffset::getFixed
ScalarTy getFixed() const
Definition: TypeSize.h:149
llvm::WinEHFuncInfo::TryBlockMap
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
Definition: WinEHFuncInfo.h:96
Module.h
llvm::MCStreamer::emitInt32
void emitInt32(uint64_t Value)
Definition: MCStreamer.h:707
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:1983
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
llvm::WinException::beginFunction
void beginFunction(const MachineFunction *MF) override
Gather pre-function exception information.
Definition: WinException.cpp:69
llvm::PointerUnion::get
T get() const
Returns the value of the specified pointer type.
Definition: PointerUnion.h:158
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::WinException::endFunclet
void endFunclet() override
Definition: WinException.cpp:255
llvm::MCContext::getOrCreateLSDASymbol
MCSymbol * getOrCreateLSDASymbol(StringRef FuncName)
Definition: MCContext.cpp:215
llvm::TargetLoweringObjectFile
Definition: TargetLoweringObjectFile.h:44
llvm::CxxUnwindMapEntry::Cleanup
MBBOrBasicBlock Cleanup
Definition: WinEHFuncInfo.h:42
llvm::classifyEHPersonality
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Definition: EHPersonalities.cpp:21
llvm::AlignStyle::Left
@ Left
FormattedStream.h
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:199
llvm::WinEHFuncInfo::FuncletBaseStateMap
DenseMap< const FuncletPadInst *, int > FuncletBaseStateMap
Definition: WinEHFuncInfo.h:92
TargetLowering.h
llvm::MachineFunction::front
const MachineBasicBlock & front() const
Definition: MachineFunction.h:828
llvm::MCContext::getOrCreateSymbol
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:191
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:323
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:745
MCContext.h
llvm::EHStreamer::emitExceptionTable
MCSymbol * emitExceptionTable()
Emit landing pads and actions.
Definition: EHStreamer.cpp:376
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:415
MCSymbol.h
llvm::isNoOpWithoutInvoke
bool isNoOpWithoutInvoke(EHPersonality Pers)
Return true if this personality may be safely removed if there are no invoke instructions remaining i...
Definition: EHPersonalities.h:96
llvm::AsmPrinter::CurrentFnSym
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition: AsmPrinter.h:118
llvm::AsmPrinter::emitAlignment
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr) const
Emit an alignment directive to the specified power of two boundary.
Definition: AsmPrinter.cpp:2465
llvm::ClrHandlerType::Fault
@ Fault
llvm::MachineFunction::begin
iterator begin()
Definition: MachineFunction.h:816
llvm::MachineBasicBlock::isCleanupFuncletEntry
bool isCleanupFuncletEntry() const
Returns true if this is the entry block of a cleanup funclet.
Definition: MachineBasicBlock.h:558
llvm::MachineFunction::tidyLandingPads
void tidyLandingPads(DenseMap< MCSymbol *, uintptr_t > *LPMap=nullptr, bool TidyIfNoBeginLabels=true)
Remap landing pad labels and remove any deleted landing pads.
Definition: MachineFunction.cpp:785
llvm::AsmPrinter::getFunctionBegin
MCSymbol * getFunctionBegin() const
Definition: AsmPrinter.h:246
llvm::WinEHHandlerType::TypeDescriptor
GlobalVariable * TypeDescriptor
Definition: WinEHFuncInfo.h:68
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::MCConstantExpr
Definition: MCExpr.h:144
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:634
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:722
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:206
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::WinEHFuncInfo
Definition: WinEHFuncInfo.h:90
llvm::SEHUnwindMapEntry::IsFinally
bool IsFinally
Definition: WinEHFuncInfo.h:51
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::CxxUnwindMapEntry::ToState
int ToState
Definition: WinEHFuncInfo.h:41
llvm::TargetLoweringObjectFile::getPersonalityEncoding
unsigned getPersonalityEncoding() const
Definition: TargetLoweringObjectFile.h:167
llvm::MachineFrameInfo::hasStackProtectorIndex
bool hasStackProtectorIndex() const
Definition: MachineFrameInfo.h:358
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:165
llvm::DenseMap
Definition: DenseMap.h:714
llvm::WinEHTryBlockMapEntry::HandlerArray
SmallVector< WinEHHandlerType, 1 > HandlerArray
Definition: WinEHFuncInfo.h:76
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::AsmPrinter::needsSEHMoves
bool needsSEHMoves()
Definition: AsmPrinter.cpp:1072
llvm::concat
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&... Ranges)
Concatenated range across two or more ranges.
Definition: STLExtras.h:1041
llvm::MachineBasicBlock::getAlignment
Align getAlignment() const
Return alignment of the basic block.
Definition: MachineBasicBlock.h:519
llvm::MCObjectFileInfo::getGEHContSection
MCSection * getGEHContSection() const
Definition: MCObjectFileInfo.h:414
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:485
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:650
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:225
llvm::MCBinaryExpr::createSub
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:610
llvm::operator==
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:1981
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:1070
llvm::EHStreamer::callToNoUnwindFunction
static bool callToNoUnwindFunction(const MachineInstr *MI)
Return ‘true’ if this is a call to a function marked ‘nounwind’.
Definition: EHStreamer.cpp:159
llvm::AsmPrinter::OutContext
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h: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:67
llvm::EHPersonality::CoreCLR
@ CoreCLR
llvm::WinEHFuncInfo::EHGuardFrameIndex
int EHGuardFrameIndex
Definition: WinEHFuncInfo.h:109
MCSection.h
llvm::MachineFunction
Definition: MachineFunction.h:234
Mangler.h
TargetOptions.h
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:2105
llvm::WinException::~WinException
~WinException() override
Definition: WinException.cpp:49
llvm::MachineBasicBlock::getNumber
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
Definition: MachineBasicBlock.h:1056
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:168
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
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:309
llvm::MCContext::createTempSymbol
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:303
llvm::EHPersonality
EHPersonality
Definition: EHPersonalities.h:22
llvm::ClrHandlerType::Finally
@ Finally
llvm::StackOffset::getFixed
static StackOffset getFixed(ScalarTy Fixed)
Definition: TypeSize.h:143
llvm::SEHUnwindMapEntry::ToState
int ToState
If unwinding continues through this handler, transition to the handler at this state.
Definition: WinEHFuncInfo.h:49
llvm::EHPersonality::MSVC_X86SEH
@ MSVC_X86SEH
llvm::SEHUnwindMapEntry::Handler
MBBOrBasicBlock Handler
Holds the __except or __finally basic block.
Definition: WinEHFuncInfo.h:57
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::WinEHFuncInfo::SEHUnwindMap
SmallVector< SEHUnwindMapEntry, 4 > SEHUnwindMap
Definition: WinEHFuncInfo.h:97
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h: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:600
llvm::TargetSubtargetInfo::getFrameLowering
virtual const TargetFrameLowering * getFrameLowering() const
Definition: TargetSubtargetInfo.h:93
llvm::ilist_iterator
Iterator for intrusive lists based on ilist_node.
Definition: ilist_iterator.h:57
MachineFrameInfo.h
llvm::MachineFunction::getWinEHFuncInfo
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.
Definition: MachineFunction.h:678
llvm::TargetFrameLowering::getFrameIndexReference
virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
Definition: TargetFrameLoweringImpl.cpp:45
llvm::CxxUnwindMapEntry
Definition: WinEHFuncInfo.h:40
llvm::WinEHTryBlockMapEntry::TryLow
int TryLow
Definition: WinEHFuncInfo.h:73
llvm::AsmPrinter
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h: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:1059
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:365
getMCSymbolForMBB
static MCSymbol * getMCSymbolForMBB(AsmPrinter *Asm, const MachineBasicBlock *MBB)
Retrieve the MCSymbol for a GlobalValue or MachineBasicBlock.
Definition: WinException.cpp:185
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:107
llvm::AsmPrinter::TM
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:84
llvm::TargetSubtargetInfo::getTargetLowering
virtual const TargetLowering * getTargetLowering() const
Definition: TargetSubtargetInfo.h:96
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
llvm::WinException::WinException
WinException(AsmPrinter *A)
Definition: WinException.cpp:41
llvm::AsmPrinter::getObjFileLowering
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:223
MCStreamer.h
llvm::dwarf::DW_EH_PE_omit
@ DW_EH_PE_omit
Definition: Dwarf.h:433
llvm::TargetMachine::getTargetTriple
const Triple & getTargetTriple() const
Definition: TargetMachine.h:129
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::WinEHFuncInfo::SEHSetFrameOffset
int SEHSetFrameOffset
Definition: WinEHFuncInfo.h:110
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
llvm::TargetLoweringObjectFile::getCFIPersonalitySymbol
virtual MCSymbol * getCFIPersonalitySymbol(const GlobalValue *GV, const TargetMachine &TM, MachineModuleInfo *MMI) const
Definition: TargetLoweringObjectFile.cpp:140
llvm::MCStreamer::isVerboseAsm
virtual bool isVerboseAsm() const
Return true if this streamer supports verbose assembly and if it is enabled.
Definition: MCStreamer.h:319
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:1199
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
llvm::HexStyle::Asm
@ Asm
0ffh
Definition: MCInstPrinter.h:34
llvm::WinEHHandlerType::Handler
MBBOrBasicBlock Handler
Definition: WinEHFuncInfo.h:69
llvm::MachineFrameInfo::getStackProtectorIndex
int getStackProtectorIndex() const
Return the index for the stack protector object.
Definition: MachineFrameInfo.h:356
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:1034
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:313
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:778
llvm::MachineFunction::getAlignment
Align getAlignment() const
getAlignment - Return the alignment of the function.
Definition: MachineFunction.h:682
MCExpr.h
llvm::MachineModuleInfo::getModule
const Module * getModule() const
Definition: MachineModuleInfo.h:174
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:342
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:65
llvm::WinEHHandlerType::CatchObj
union llvm::WinEHHandlerType::@226 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
llvm::SmallVectorImpl::emplace_back
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:908