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