diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter/Win64Exception.cpp')
| -rw-r--r-- | lib/CodeGen/AsmPrinter/Win64Exception.cpp | 149 | 
1 files changed, 1 insertions, 148 deletions
diff --git a/lib/CodeGen/AsmPrinter/Win64Exception.cpp b/lib/CodeGen/AsmPrinter/Win64Exception.cpp index 2138cb9514f82..0f0ad755835dc 100644 --- a/lib/CodeGen/AsmPrinter/Win64Exception.cpp +++ b/lib/CodeGen/AsmPrinter/Win64Exception.cpp @@ -99,156 +99,9 @@ void Win64Exception::endFunction(const MachineFunction *) {    if (shouldEmitPersonality) {      Asm->OutStreamer.PushSection(); - -    // Emit an UNWIND_INFO struct describing the prologue.      Asm->OutStreamer.EmitWinEHHandlerData(); - -    // Emit either MSVC-compatible tables or the usual Itanium-style LSDA after -    // the UNWIND_INFO struct. -    if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::MSVC) { -      const Function *Per = MMI->getPersonalities()[MMI->getPersonalityIndex()]; -      if (Per->getName() == "__C_specific_handler") -        emitCSpecificHandlerTable(); -      else -        report_fatal_error(Twine("unexpected personality function: ") + -                           Per->getName()); -    } else { -      emitExceptionTable(); -    } - +    emitExceptionTable();      Asm->OutStreamer.PopSection();    }    Asm->OutStreamer.EmitWinCFIEndProc();  } - -const MCSymbolRefExpr *Win64Exception::createImageRel32(const MCSymbol *Value) { -  return MCSymbolRefExpr::Create(Value, MCSymbolRefExpr::VK_COFF_IMGREL32, -                                 Asm->OutContext); -} - -/// Emit the language-specific data that __C_specific_handler expects.  This -/// handler lives in the x64 Microsoft C runtime and allows catching or cleaning -/// up after faults with __try, __except, and __finally.  The typeinfo values -/// are not really RTTI data, but pointers to filter functions that return an -/// integer (1, 0, or -1) indicating how to handle the exception. For __finally -/// blocks and other cleanups, the landing pad label is zero, and the filter -/// function is actually a cleanup handler with the same prototype.  A catch-all -/// entry is modeled with a null filter function field and a non-zero landing -/// pad label. -/// -/// Possible filter function return values: -///   EXCEPTION_EXECUTE_HANDLER (1): -///     Jump to the landing pad label after cleanups. -///   EXCEPTION_CONTINUE_SEARCH (0): -///     Continue searching this table or continue unwinding. -///   EXCEPTION_CONTINUE_EXECUTION (-1): -///     Resume execution at the trapping PC. -/// -/// Inferred table structure: -///   struct Table { -///     int NumEntries; -///     struct Entry { -///       imagerel32 LabelStart; -///       imagerel32 LabelEnd; -///       imagerel32 FilterOrFinally;  // Zero means catch-all. -///       imagerel32 LabelLPad;        // Zero means __finally. -///     } Entries[NumEntries]; -///   }; -void Win64Exception::emitCSpecificHandlerTable() { -  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); - -  // Simplifying assumptions for first implementation: -  // - Cleanups are not implemented. -  // - Filters are not implemented. - -  // The Itanium LSDA table sorts similar landing pads together to simplify the -  // actions table, but we don't need that. -  SmallVector<const LandingPadInfo *, 64> LandingPads; -  LandingPads.reserve(PadInfos.size()); -  for (const auto &LP : PadInfos) -    LandingPads.push_back(&LP); - -  // Compute label ranges for call sites as we would for the Itanium LSDA, but -  // use an all zero action table because we aren't using these actions. -  SmallVector<unsigned, 64> FirstActions; -  FirstActions.resize(LandingPads.size()); -  SmallVector<CallSiteEntry, 64> CallSites; -  computeCallSiteTable(CallSites, LandingPads, FirstActions); - -  MCSymbol *EHFuncBeginSym = -      Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber()); -  MCSymbol *EHFuncEndSym = -      Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber()); - -  // Emit the number of table entries. -  unsigned NumEntries = 0; -  for (const CallSiteEntry &CSE : CallSites) { -    if (!CSE.LPad) -      continue; // Ignore gaps. -    for (int Selector : CSE.LPad->TypeIds) { -      // Ignore C++ filter clauses in SEH. -      // FIXME: Implement cleanup clauses. -      if (isCatchEHSelector(Selector)) -        ++NumEntries; -    } -  } -  Asm->OutStreamer.EmitIntValue(NumEntries, 4); - -  // Emit the four-label records for each call site entry. The table has to be -  // sorted in layout order, and the call sites should already be sorted. -  for (const CallSiteEntry &CSE : CallSites) { -    // Ignore gaps. Unlike the Itanium model, unwinding through a frame without -    // an EH table entry will propagate the exception rather than terminating -    // the program. -    if (!CSE.LPad) -      continue; -    const LandingPadInfo *LPad = CSE.LPad; - -    // Compute the label range. We may reuse the function begin and end labels -    // rather than forming new ones. -    const MCExpr *Begin = -        createImageRel32(CSE.BeginLabel ? CSE.BeginLabel : EHFuncBeginSym); -    const MCExpr *End; -    if (CSE.EndLabel) { -      // The interval is half-open, so we have to add one to include the return -      // address of the last invoke in the range. -      End = MCBinaryExpr::CreateAdd(createImageRel32(CSE.EndLabel), -                                    MCConstantExpr::Create(1, Asm->OutContext), -                                    Asm->OutContext); -    } else { -      End = createImageRel32(EHFuncEndSym); -    } - -    // These aren't really type info globals, they are actually pointers to -    // filter functions ordered by selector. The zero selector is used for -    // cleanups, so slot zero corresponds to selector 1. -    const std::vector<const GlobalValue *> &SelectorToFilter = MMI->getTypeInfos(); - -    // Do a parallel iteration across typeids and clause labels, skipping filter -    // clauses. -    assert(LPad->TypeIds.size() == LPad->ClauseLabels.size()); -    for (size_t I = 0, E = LPad->TypeIds.size(); I < E; ++I) { -      // AddLandingPadInfo stores the clauses in reverse, but there is a FIXME -      // to change that. -      int Selector = LPad->TypeIds[E - I - 1]; -      MCSymbol *ClauseLabel = LPad->ClauseLabels[I]; - -      // Ignore C++ filter clauses in SEH. -      // FIXME: Implement cleanup clauses. -      if (!isCatchEHSelector(Selector)) -        continue; - -      Asm->OutStreamer.EmitValue(Begin, 4); -      Asm->OutStreamer.EmitValue(End, 4); -      if (isCatchEHSelector(Selector)) { -        assert(unsigned(Selector - 1) < SelectorToFilter.size()); -        const GlobalValue *TI = SelectorToFilter[Selector - 1]; -        if (TI) // Emit the filter function pointer. -          Asm->OutStreamer.EmitValue(createImageRel32(Asm->getSymbol(TI)), 4); -        else  // Otherwise, this is a "catch i8* null", or catch all. -          Asm->OutStreamer.EmitIntValue(0, 4); -      } -      Asm->OutStreamer.EmitValue(createImageRel32(ClauseLabel), 4); -    } -  } -}  | 
