//===- CodeGen/AsmPrinter/EHStreamer.cpp - Exception Directive Streamer ---===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing exception info into assembly files.
//
//===----------------------------------------------------------------------===//

#include "EHStreamer.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <vector>

using namespace llvm;

EHStreamer::EHStreamer(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}

EHStreamer::~EHStreamer() = default;

/// How many leading type ids two landing pads have in common.
unsigned EHStreamer::sharedTypeIDs(const LandingPadInfo *L,
                                   const LandingPadInfo *R) {
  const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
  return std::mismatch(LIds.begin(), LIds.end(), RIds.begin(), RIds.end())
             .first -
         LIds.begin();
}

/// Compute the actions table and gather the first action index for each landing
/// pad site.
void EHStreamer::computeActionsTable(
    const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
    SmallVectorImpl<ActionEntry> &Actions,
    SmallVectorImpl<unsigned> &FirstActions) {
  // The action table follows the call-site table in the LSDA. The individual
  // records are of two types:
  //
  //   * Catch clause
  //   * Exception specification
  //
  // The two record kinds have the same format, with only small differences.
  // They are distinguished by the "switch value" field: Catch clauses
  // (TypeInfos) have strictly positive switch values, and exception
  // specifications (FilterIds) have strictly negative switch values. Value 0
  // indicates a catch-all clause.
  //
  // Negative type IDs index into FilterIds. Positive type IDs index into
  // TypeInfos.  The value written for a positive type ID is just the type ID
  // itself.  For a negative type ID, however, the value written is the
  // (negative) byte offset of the corresponding FilterIds entry.  The byte
  // offset is usually equal to the type ID (because the FilterIds entries are
  // written using a variable width encoding, which outputs one byte per entry
  // as long as the value written is not too large) but can differ.  This kind
  // of complication does not occur for positive type IDs because type infos are
  // output using a fixed width encoding.  FilterOffsets[i] holds the byte
  // offset corresponding to FilterIds[i].

  const std::vector<unsigned> &FilterIds = Asm->MF->getFilterIds();
  SmallVector<int, 16> FilterOffsets;
  FilterOffsets.reserve(FilterIds.size());
  int Offset = -1;

  for (unsigned FilterId : FilterIds) {
    FilterOffsets.push_back(Offset);
    Offset -= getULEB128Size(FilterId);
  }

  FirstActions.reserve(LandingPads.size());

  int FirstAction = 0;
  unsigned SizeActions = 0; // Total size of all action entries for a function
  const LandingPadInfo *PrevLPI = nullptr;

  for (const LandingPadInfo *LPI : LandingPads) {
    const std::vector<int> &TypeIds = LPI->TypeIds;
    unsigned NumShared = PrevLPI ? sharedTypeIDs(LPI, PrevLPI) : 0;
    unsigned SizeSiteActions = 0; // Total size of all entries for a landingpad

    if (NumShared < TypeIds.size()) {
      // Size of one action entry (typeid + next action)
      unsigned SizeActionEntry = 0;
      unsigned PrevAction = (unsigned)-1;

      if (NumShared) {
        unsigned SizePrevIds = PrevLPI->TypeIds.size();
        assert(Actions.size());
        PrevAction = Actions.size() - 1;
        SizeActionEntry = getSLEB128Size(Actions[PrevAction].NextAction) +
                          getSLEB128Size(Actions[PrevAction].ValueForTypeID);

        for (unsigned j = NumShared; j != SizePrevIds; ++j) {
          assert(PrevAction != (unsigned)-1 && "PrevAction is invalid!");
          SizeActionEntry -= getSLEB128Size(Actions[PrevAction].ValueForTypeID);
          SizeActionEntry += -Actions[PrevAction].NextAction;
          PrevAction = Actions[PrevAction].Previous;
        }
      }

      // Compute the actions.
      for (unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) {
        int TypeID = TypeIds[J];
        assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
        int ValueForTypeID =
            isFilterEHSelector(TypeID) ? FilterOffsets[-1 - TypeID] : TypeID;
        unsigned SizeTypeID = getSLEB128Size(ValueForTypeID);

        int NextAction = SizeActionEntry ? -(SizeActionEntry + SizeTypeID) : 0;
        SizeActionEntry = SizeTypeID + getSLEB128Size(NextAction);
        SizeSiteActions += SizeActionEntry;

        ActionEntry Action = { ValueForTypeID, NextAction, PrevAction };
        Actions.push_back(Action);
        PrevAction = Actions.size() - 1;
      }

      // Record the first action of the landing pad site.
      FirstAction = SizeActions + SizeSiteActions - SizeActionEntry + 1;
    } // else identical - re-use previous FirstAction

    // Information used when creating the call-site table. The action record
    // field of the call site record is the offset of the first associated
    // action record, relative to the start of the actions table. This value is
    // biased by 1 (1 indicating the start of the actions table), and 0
    // indicates that there are no actions.
    FirstActions.push_back(FirstAction);

    // Compute this sites contribution to size.
    SizeActions += SizeSiteActions;

    PrevLPI = LPI;
  }
}

/// Return `true' if this is a call to a function marked `nounwind'. Return
/// `false' otherwise.
bool EHStreamer::callToNoUnwindFunction(const MachineInstr *MI) {
  assert(MI->isCall() && "This should be a call instruction!");

  bool MarkedNoUnwind = false;
  bool SawFunc = false;

  for (const MachineOperand &MO : MI->operands()) {
    if (!MO.isGlobal()) continue;

    const Function *F = dyn_cast<Function>(MO.getGlobal());
    if (!F) continue;

    if (SawFunc) {
      // Be conservative. If we have more than one function operand for this
      // call, then we can't make the assumption that it's the callee and
      // not a parameter to the call.
      //
      // FIXME: Determine if there's a way to say that `F' is the callee or
      // parameter.
      MarkedNoUnwind = false;
      break;
    }

    MarkedNoUnwind = F->doesNotThrow();
    SawFunc = true;
  }

  return MarkedNoUnwind;
}

void EHStreamer::computePadMap(
    const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
    RangeMapType &PadMap) {
  // Invokes and nounwind calls have entries in PadMap (due to being bracketed
  // by try-range labels when lowered).  Ordinary calls do not, so appropriate
  // try-ranges for them need be deduced so we can put them in the LSDA.
  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
    const LandingPadInfo *LandingPad = LandingPads[i];
    for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
      MCSymbol *BeginLabel = LandingPad->BeginLabels[j];
      MCSymbol *EndLabel = LandingPad->BeginLabels[j];
      // If we have deleted the code for a given invoke after registering it in
      // the LandingPad label list, the associated symbols will not have been
      // emitted. In that case, ignore this callsite entry.
      if (!BeginLabel->isDefined() || !EndLabel->isDefined())
        continue;
      assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
      PadRange P = { i, j };
      PadMap[BeginLabel] = P;
    }
  }
}

/// Compute the call-site table.  The entry for an invoke has a try-range
/// containing the call, a non-zero landing pad, and an appropriate action.  The
/// entry for an ordinary call has a try-range containing the call and zero for
/// the landing pad and the action.  Calls marked 'nounwind' have no entry and
/// must not be contained in the try-range of any entry - they form gaps in the
/// table.  Entries must be ordered by try-range address.
///
/// Call-sites are split into one or more call-site ranges associated with
/// different sections of the function.
///
///   - Without -basic-block-sections, all call-sites are grouped into one
///     call-site-range corresponding to the function section.
///
///   - With -basic-block-sections, one call-site range is created for each
///     section, with its FragmentBeginLabel and FragmentEndLabel respectively
//      set to the beginning and ending of the corresponding section and its
//      ExceptionLabel set to the exception symbol dedicated for this section.
//      Later, one LSDA header will be emitted for each call-site range with its
//      call-sites following. The action table and type info table will be
//      shared across all ranges.
void EHStreamer::computeCallSiteTable(
    SmallVectorImpl<CallSiteEntry> &CallSites,
    SmallVectorImpl<CallSiteRange> &CallSiteRanges,
    const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
    const SmallVectorImpl<unsigned> &FirstActions) {
  RangeMapType PadMap;
  computePadMap(LandingPads, PadMap);

  // The end label of the previous invoke or nounwind try-range.
  MCSymbol *LastLabel = Asm->getFunctionBegin();

  // Whether there is a potentially throwing instruction (currently this means
  // an ordinary call) between the end of the previous try-range and now.
  bool SawPotentiallyThrowing = false;

  // Whether the last CallSite entry was for an invoke.
  bool PreviousIsInvoke = false;

  bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;

  // Visit all instructions in order of address.
  for (const auto &MBB : *Asm->MF) {
    if (&MBB == &Asm->MF->front() || MBB.isBeginSection()) {
      // We start a call-site range upon function entry and at the beginning of
      // every basic block section.
      auto &Range = Asm->MBBSectionRanges[MBB.getSectionID()];
      CallSiteRanges.push_back({Range.BeginLabel, Range.EndLabel,
                                Asm->getMBBExceptionSym(MBB),
                                CallSites.size()});
      PreviousIsInvoke = false;
      SawPotentiallyThrowing = false;
      LastLabel = nullptr;
    }

    if (MBB.isEHPad())
      CallSiteRanges.back().IsLPRange = true;

    for (const auto &MI : MBB) {
      if (!MI.isEHLabel()) {
        if (MI.isCall())
          SawPotentiallyThrowing |= !callToNoUnwindFunction(&MI);
        continue;
      }

      // End of the previous try-range?
      MCSymbol *BeginLabel = MI.getOperand(0).getMCSymbol();
      if (BeginLabel == LastLabel)
        SawPotentiallyThrowing = false;

      // Beginning of a new try-range?
      RangeMapType::const_iterator L = PadMap.find(BeginLabel);
      if (L == PadMap.end())
        // Nope, it was just some random label.
        continue;

      const PadRange &P = L->second;
      const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
      assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
             "Inconsistent landing pad map!");

      // For Dwarf and AIX exception handling (SjLj handling doesn't use this).
      // If some instruction between the previous try-range and this one may
      // throw, create a call-site entry with no landing pad for the region
      // between the try-ranges.
      if (SawPotentiallyThrowing &&
          (Asm->MAI->usesCFIForEH() ||
           Asm->MAI->getExceptionHandlingType() == ExceptionHandling::AIX)) {
        CallSites.push_back({LastLabel, BeginLabel, nullptr, 0});
        PreviousIsInvoke = false;
      }

      LastLabel = LandingPad->EndLabels[P.RangeIndex];
      assert(BeginLabel && LastLabel && "Invalid landing pad!");

      if (!LandingPad->LandingPadLabel) {
        // Create a gap.
        PreviousIsInvoke = false;
      } else {
        // This try-range is for an invoke.
        CallSiteEntry Site = {
          BeginLabel,
          LastLabel,
          LandingPad,
          FirstActions[P.PadIndex]
        };

        // Try to merge with the previous call-site. SJLJ doesn't do this
        if (PreviousIsInvoke && !IsSJLJ) {
          CallSiteEntry &Prev = CallSites.back();
          if (Site.LPad == Prev.LPad && Site.Action == Prev.Action) {
            // Extend the range of the previous entry.
            Prev.EndLabel = Site.EndLabel;
            continue;
          }
        }

        // Otherwise, create a new call-site.
        if (!IsSJLJ)
          CallSites.push_back(Site);
        else {
          // SjLj EH must maintain the call sites in the order assigned
          // to them by the SjLjPrepare pass.
          unsigned SiteNo = Asm->MF->getCallSiteBeginLabel(BeginLabel);
          if (CallSites.size() < SiteNo)
            CallSites.resize(SiteNo);
          CallSites[SiteNo - 1] = Site;
        }
        PreviousIsInvoke = true;
      }
    }

    // We end the call-site range upon function exit and at the end of every
    // basic block section.
    if (&MBB == &Asm->MF->back() || MBB.isEndSection()) {
      // If some instruction between the previous try-range and the end of the
      // function may throw, create a call-site entry with no landing pad for
      // the region following the try-range.
      if (SawPotentiallyThrowing && !IsSJLJ) {
        CallSiteEntry Site = {LastLabel, CallSiteRanges.back().FragmentEndLabel,
                              nullptr, 0};
        CallSites.push_back(Site);
        SawPotentiallyThrowing = false;
      }
      CallSiteRanges.back().CallSiteEndIdx = CallSites.size();
    }
  }
}

/// Emit landing pads and actions.
///
/// The general organization of the table is complex, but the basic concepts are
/// easy.  First there is a header which describes the location and organization
/// of the three components that follow.
///
///  1. The landing pad site information describes the range of code covered by
///     the try.  In our case it's an accumulation of the ranges covered by the
///     invokes in the try.  There is also a reference to the landing pad that
///     handles the exception once processed.  Finally an index into the actions
///     table.
///  2. The action table, in our case, is composed of pairs of type IDs and next
///     action offset.  Starting with the action index from the landing pad
///     site, each type ID is checked for a match to the current exception.  If
///     it matches then the exception and type id are passed on to the landing
///     pad.  Otherwise the next action is looked up.  This chain is terminated
///     with a next action of zero.  If no type id is found then the frame is
///     unwound and handling continues.
///  3. Type ID table contains references to all the C++ typeinfo for all
///     catches in the function.  This tables is reverse indexed base 1.
///
/// Returns the starting symbol of an exception table.
MCSymbol *EHStreamer::emitExceptionTable() {
  const MachineFunction *MF = Asm->MF;
  const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
  const std::vector<unsigned> &FilterIds = MF->getFilterIds();
  const std::vector<LandingPadInfo> &PadInfos = MF->getLandingPads();

  // Sort the landing pads in order of their type ids.  This is used to fold
  // duplicate actions.
  SmallVector<const LandingPadInfo *, 64> LandingPads;
  LandingPads.reserve(PadInfos.size());

  for (const LandingPadInfo &LPI : PadInfos) {
    // If a landing-pad has an associated label, but the label wasn't ever
    // emitted, then skip it.  (This can occur if the landingpad's MBB was
    // deleted).
    if (LPI.LandingPadLabel && !LPI.LandingPadLabel->isDefined())
      continue;
    LandingPads.push_back(&LPI);
  }

  // Order landing pads lexicographically by type id.
  llvm::sort(LandingPads, [](const LandingPadInfo *L, const LandingPadInfo *R) {
    return L->TypeIds < R->TypeIds;
  });

  // Compute the actions table and gather the first action index for each
  // landing pad site.
  SmallVector<ActionEntry, 32> Actions;
  SmallVector<unsigned, 64> FirstActions;
  computeActionsTable(LandingPads, Actions, FirstActions);

  // Compute the call-site table and call-site ranges. Normally, there is only
  // one call-site-range which covers the whole function. With
  // -basic-block-sections, there is one call-site-range per basic block
  // section.
  SmallVector<CallSiteEntry, 64> CallSites;
  SmallVector<CallSiteRange, 4> CallSiteRanges;
  computeCallSiteTable(CallSites, CallSiteRanges, LandingPads, FirstActions);

  bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
  bool IsWasm = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Wasm;
  bool HasLEB128Directives = Asm->MAI->hasLEB128Directives();
  unsigned CallSiteEncoding =
      IsSJLJ ? static_cast<unsigned>(dwarf::DW_EH_PE_udata4) :
               Asm->getObjFileLowering().getCallSiteEncoding();
  bool HaveTTData = !TypeInfos.empty() || !FilterIds.empty();

  // Type infos.
  MCSection *LSDASection = Asm->getObjFileLowering().getSectionForLSDA(
      MF->getFunction(), *Asm->CurrentFnSym, Asm->TM);
  unsigned TTypeEncoding;

  if (!HaveTTData) {
    // If there is no TypeInfo, then we just explicitly say that we're omitting
    // that bit.
    TTypeEncoding = dwarf::DW_EH_PE_omit;
  } else {
    // Okay, we have actual filters or typeinfos to emit.  As such, we need to
    // pick a type encoding for them.  We're about to emit a list of pointers to
    // typeinfo objects at the end of the LSDA.  However, unless we're in static
    // mode, this reference will require a relocation by the dynamic linker.
    //
    // Because of this, we have a couple of options:
    //
    //   1) If we are in -static mode, we can always use an absolute reference
    //      from the LSDA, because the static linker will resolve it.
    //
    //   2) Otherwise, if the LSDA section is writable, we can output the direct
    //      reference to the typeinfo and allow the dynamic linker to relocate
    //      it.  Since it is in a writable section, the dynamic linker won't
    //      have a problem.
    //
    //   3) Finally, if we're in PIC mode and the LDSA section isn't writable,
    //      we need to use some form of indirection.  For example, on Darwin,
    //      we can output a statically-relocatable reference to a dyld stub. The
    //      offset to the stub is constant, but the contents are in a section
    //      that is updated by the dynamic linker.  This is easy enough, but we
    //      need to tell the personality function of the unwinder to indirect
    //      through the dyld stub.
    //
    // FIXME: When (3) is actually implemented, we'll have to emit the stubs
    // somewhere.  This predicate should be moved to a shared location that is
    // in target-independent code.
    //
    TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding();
  }

  // Begin the exception table.
  // Sometimes we want not to emit the data into separate section (e.g. ARM
  // EHABI). In this case LSDASection will be NULL.
  if (LSDASection)
    Asm->OutStreamer->switchSection(LSDASection);
  Asm->emitAlignment(Align(4));

  // Emit the LSDA.
  MCSymbol *GCCETSym =
    Asm->OutContext.getOrCreateSymbol(Twine("GCC_except_table")+
                                      Twine(Asm->getFunctionNumber()));
  Asm->OutStreamer->emitLabel(GCCETSym);
  MCSymbol *CstEndLabel = Asm->createTempSymbol(
      CallSiteRanges.size() > 1 ? "action_table_base" : "cst_end");

  MCSymbol *TTBaseLabel = nullptr;
  if (HaveTTData)
    TTBaseLabel = Asm->createTempSymbol("ttbase");

  const bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();

  // Helper for emitting references (offsets) for type table and the end of the
  // call-site table (which marks the beginning of the action table).
  //  * For Itanium, these references will be emitted for every callsite range.
  //  * For SJLJ and Wasm, they will be emitted only once in the LSDA header.
  auto EmitTypeTableRefAndCallSiteTableEndRef = [&]() {
    Asm->emitEncodingByte(TTypeEncoding, "@TType");
    if (HaveTTData) {
      // N.B.: There is a dependency loop between the size of the TTBase uleb128
      // here and the amount of padding before the aligned type table. The
      // assembler must sometimes pad this uleb128 or insert extra padding
      // before the type table. See PR35809 or GNU as bug 4029.
      MCSymbol *TTBaseRefLabel = Asm->createTempSymbol("ttbaseref");
      Asm->emitLabelDifferenceAsULEB128(TTBaseLabel, TTBaseRefLabel);
      Asm->OutStreamer->emitLabel(TTBaseRefLabel);
    }

    // The Action table follows the call-site table. So we emit the
    // label difference from here (start of the call-site table for SJLJ and
    // Wasm, and start of a call-site range for Itanium) to the end of the
    // whole call-site table (end of the last call-site range for Itanium).
    MCSymbol *CstBeginLabel = Asm->createTempSymbol("cst_begin");
    Asm->emitEncodingByte(CallSiteEncoding, "Call site");
    Asm->emitLabelDifferenceAsULEB128(CstEndLabel, CstBeginLabel);
    Asm->OutStreamer->emitLabel(CstBeginLabel);
  };

  // An alternative path to EmitTypeTableRefAndCallSiteTableEndRef.
  // For some platforms, the system assembler does not accept the form of
  // `.uleb128 label2 - label1`. In those situations, we would need to calculate
  // the size between label1 and label2 manually.
  // In this case, we would need to calculate the LSDA size and the call
  // site table size.
  auto EmitTypeTableOffsetAndCallSiteTableOffset = [&]() {
    assert(CallSiteEncoding == dwarf::DW_EH_PE_udata4 && !HasLEB128Directives &&
           "Targets supporting .uleb128 do not need to take this path.");
    if (CallSiteRanges.size() > 1)
      report_fatal_error(
          "-fbasic-block-sections is not yet supported on "
          "platforms that do not have general LEB128 directive support.");

    uint64_t CallSiteTableSize = 0;
    const CallSiteRange &CSRange = CallSiteRanges.back();
    for (size_t CallSiteIdx = CSRange.CallSiteBeginIdx;
         CallSiteIdx < CSRange.CallSiteEndIdx; ++CallSiteIdx) {
      const CallSiteEntry &S = CallSites[CallSiteIdx];
      // Each call site entry consists of 3 udata4 fields (12 bytes) and
      // 1 ULEB128 field.
      CallSiteTableSize += 12 + getULEB128Size(S.Action);
      assert(isUInt<32>(CallSiteTableSize) && "CallSiteTableSize overflows.");
    }

    Asm->emitEncodingByte(TTypeEncoding, "@TType");
    if (HaveTTData) {
      const unsigned ByteSizeOfCallSiteOffset =
          getULEB128Size(CallSiteTableSize);
      uint64_t ActionTableSize = 0;
      for (const ActionEntry &Action : Actions) {
        // Each action entry consists of two SLEB128 fields.
        ActionTableSize += getSLEB128Size(Action.ValueForTypeID) +
                           getSLEB128Size(Action.NextAction);
        assert(isUInt<32>(ActionTableSize) && "ActionTableSize overflows.");
      }

      const unsigned TypeInfoSize =
          Asm->GetSizeOfEncodedValue(TTypeEncoding) * MF->getTypeInfos().size();

      const uint64_t LSDASizeBeforeAlign =
          1                          // Call site encoding byte.
          + ByteSizeOfCallSiteOffset // ULEB128 encoding of CallSiteTableSize.
          + CallSiteTableSize        // Call site table content.
          + ActionTableSize;         // Action table content.

      const uint64_t LSDASizeWithoutAlign = LSDASizeBeforeAlign + TypeInfoSize;
      const unsigned ByteSizeOfLSDAWithoutAlign =
          getULEB128Size(LSDASizeWithoutAlign);
      const uint64_t DisplacementBeforeAlign =
          2 // LPStartEncoding and TypeTableEncoding.
          + ByteSizeOfLSDAWithoutAlign + LSDASizeBeforeAlign;

      // The type info area starts with 4 byte alignment.
      const unsigned NeedAlignVal = (4 - DisplacementBeforeAlign % 4) % 4;
      uint64_t LSDASizeWithAlign = LSDASizeWithoutAlign + NeedAlignVal;
      const unsigned ByteSizeOfLSDAWithAlign =
          getULEB128Size(LSDASizeWithAlign);

      // The LSDASizeWithAlign could use 1 byte less padding for alignment
      // when the data we use to represent the LSDA Size "needs" to be 1 byte
      // larger than the one previously calculated without alignment.
      if (ByteSizeOfLSDAWithAlign > ByteSizeOfLSDAWithoutAlign)
        LSDASizeWithAlign -= 1;

      Asm->OutStreamer->emitULEB128IntValue(LSDASizeWithAlign,
                                            ByteSizeOfLSDAWithAlign);
    }

    Asm->emitEncodingByte(CallSiteEncoding, "Call site");
    Asm->OutStreamer->emitULEB128IntValue(CallSiteTableSize);
  };

  // SjLj / Wasm Exception handling
  if (IsSJLJ || IsWasm) {
    Asm->OutStreamer->emitLabel(Asm->getMBBExceptionSym(Asm->MF->front()));

    // emit the LSDA header.
    Asm->emitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
    EmitTypeTableRefAndCallSiteTableEndRef();

    unsigned idx = 0;
    for (SmallVectorImpl<CallSiteEntry>::const_iterator
         I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) {
      const CallSiteEntry &S = *I;

      // Index of the call site entry.
      if (VerboseAsm) {
        Asm->OutStreamer->AddComment(">> Call Site " + Twine(idx) + " <<");
        Asm->OutStreamer->AddComment("  On exception at call site "+Twine(idx));
      }
      Asm->emitULEB128(idx);

      // Offset of the first associated action record, relative to the start of
      // the action table. This value is biased by 1 (1 indicates the start of
      // the action table), and 0 indicates that there are no actions.
      if (VerboseAsm) {
        if (S.Action == 0)
          Asm->OutStreamer->AddComment("  Action: cleanup");
        else
          Asm->OutStreamer->AddComment("  Action: " +
                                       Twine((S.Action - 1) / 2 + 1));
      }
      Asm->emitULEB128(S.Action);
    }
    Asm->OutStreamer->emitLabel(CstEndLabel);
  } else {
    // Itanium LSDA exception handling

    // The call-site table is a list of all call sites that may throw an
    // exception (including C++ 'throw' statements) in the procedure
    // fragment. It immediately follows the LSDA header. Each entry indicates,
    // for a given call, the first corresponding action record and corresponding
    // landing pad.
    //
    // The table begins with the number of bytes, stored as an LEB128
    // compressed, unsigned integer. The records immediately follow the record
    // count. They are sorted in increasing call-site address. Each record
    // indicates:
    //
    //   * The position of the call-site.
    //   * The position of the landing pad.
    //   * The first action record for that call site.
    //
    // A missing entry in the call-site table indicates that a call is not
    // supposed to throw.

    assert(CallSiteRanges.size() != 0 && "No call-site ranges!");

    // There should be only one call-site range which includes all the landing
    // pads. Find that call-site range here.
    const CallSiteRange *LandingPadRange = nullptr;
    for (const CallSiteRange &CSRange : CallSiteRanges) {
      if (CSRange.IsLPRange) {
        assert(LandingPadRange == nullptr &&
               "All landing pads must be in a single callsite range.");
        LandingPadRange = &CSRange;
      }
    }

    // The call-site table is split into its call-site ranges, each being
    // emitted as:
    //              [ LPStartEncoding | LPStart ]
    //              [ TypeTableEncoding | TypeTableOffset ]
    //              [ CallSiteEncoding | CallSiteTableEndOffset ]
    // cst_begin -> { call-site entries contained in this range }
    //
    // and is followed by the next call-site range.
    //
    // For each call-site range, CallSiteTableEndOffset is computed as the
    // difference between cst_begin of that range and the last call-site-table's
    // end label. This offset is used to find the action table.

    unsigned Entry = 0;
    for (const CallSiteRange &CSRange : CallSiteRanges) {
      if (CSRange.CallSiteBeginIdx != 0) {
        // Align the call-site range for all ranges except the first. The
        // first range is already aligned due to the exception table alignment.
        Asm->emitAlignment(Align(4));
      }
      Asm->OutStreamer->emitLabel(CSRange.ExceptionLabel);

      // Emit the LSDA header.
      // LPStart is omitted if either we have a single call-site range (in which
      // case the function entry is treated as @LPStart) or if this function has
      // no landing pads (in which case @LPStart is undefined).
      if (CallSiteRanges.size() == 1 || LandingPadRange == nullptr) {
        Asm->emitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
      } else if (!Asm->isPositionIndependent()) {
        // For more than one call-site ranges, LPStart must be explicitly
        // specified.
        // For non-PIC we can simply use the absolute value.
        Asm->emitEncodingByte(dwarf::DW_EH_PE_absptr, "@LPStart");
        Asm->OutStreamer->emitSymbolValue(LandingPadRange->FragmentBeginLabel,
                                          Asm->MAI->getCodePointerSize());
      } else {
        // For PIC mode, we Emit a PC-relative address for LPStart.
        Asm->emitEncodingByte(dwarf::DW_EH_PE_pcrel, "@LPStart");
        MCContext &Context = Asm->OutStreamer->getContext();
        MCSymbol *Dot = Context.createTempSymbol();
        Asm->OutStreamer->emitLabel(Dot);
        Asm->OutStreamer->emitValue(
            MCBinaryExpr::createSub(
                MCSymbolRefExpr::create(LandingPadRange->FragmentBeginLabel,
                                        Context),
                MCSymbolRefExpr::create(Dot, Context), Context),
            Asm->MAI->getCodePointerSize());
      }

      if (HasLEB128Directives)
        EmitTypeTableRefAndCallSiteTableEndRef();
      else
        EmitTypeTableOffsetAndCallSiteTableOffset();

      for (size_t CallSiteIdx = CSRange.CallSiteBeginIdx;
           CallSiteIdx != CSRange.CallSiteEndIdx; ++CallSiteIdx) {
        const CallSiteEntry &S = CallSites[CallSiteIdx];

        MCSymbol *EHFuncBeginSym = CSRange.FragmentBeginLabel;
        MCSymbol *EHFuncEndSym = CSRange.FragmentEndLabel;

        MCSymbol *BeginLabel = S.BeginLabel;
        if (!BeginLabel)
          BeginLabel = EHFuncBeginSym;
        MCSymbol *EndLabel = S.EndLabel;
        if (!EndLabel)
          EndLabel = EHFuncEndSym;

        // Offset of the call site relative to the start of the procedure.
        if (VerboseAsm)
          Asm->OutStreamer->AddComment(">> Call Site " + Twine(++Entry) +
                                       " <<");
        Asm->emitCallSiteOffset(BeginLabel, EHFuncBeginSym, CallSiteEncoding);
        if (VerboseAsm)
          Asm->OutStreamer->AddComment(Twine("  Call between ") +
                                       BeginLabel->getName() + " and " +
                                       EndLabel->getName());
        Asm->emitCallSiteOffset(EndLabel, BeginLabel, CallSiteEncoding);

        // Offset of the landing pad relative to the start of the landing pad
        // fragment.
        if (!S.LPad) {
          if (VerboseAsm)
            Asm->OutStreamer->AddComment("    has no landing pad");
          Asm->emitCallSiteValue(0, CallSiteEncoding);
        } else {
          if (VerboseAsm)
            Asm->OutStreamer->AddComment(Twine("    jumps to ") +
                                         S.LPad->LandingPadLabel->getName());
          Asm->emitCallSiteOffset(S.LPad->LandingPadLabel,
                                  LandingPadRange->FragmentBeginLabel,
                                  CallSiteEncoding);
        }

        // Offset of the first associated action record, relative to the start
        // of the action table. This value is biased by 1 (1 indicates the start
        // of the action table), and 0 indicates that there are no actions.
        if (VerboseAsm) {
          if (S.Action == 0)
            Asm->OutStreamer->AddComment("  On action: cleanup");
          else
            Asm->OutStreamer->AddComment("  On action: " +
                                         Twine((S.Action - 1) / 2 + 1));
        }
        Asm->emitULEB128(S.Action);
      }
    }
    Asm->OutStreamer->emitLabel(CstEndLabel);
  }

  // Emit the Action Table.
  int Entry = 0;
  for (const ActionEntry &Action : Actions) {
    if (VerboseAsm) {
      // Emit comments that decode the action table.
      Asm->OutStreamer->AddComment(">> Action Record " + Twine(++Entry) + " <<");
    }

    // Type Filter
    //
    //   Used by the runtime to match the type of the thrown exception to the
    //   type of the catch clauses or the types in the exception specification.
    if (VerboseAsm) {
      if (Action.ValueForTypeID > 0)
        Asm->OutStreamer->AddComment("  Catch TypeInfo " +
                                     Twine(Action.ValueForTypeID));
      else if (Action.ValueForTypeID < 0)
        Asm->OutStreamer->AddComment("  Filter TypeInfo " +
                                     Twine(Action.ValueForTypeID));
      else
        Asm->OutStreamer->AddComment("  Cleanup");
    }
    Asm->emitSLEB128(Action.ValueForTypeID);

    // Action Record
    if (VerboseAsm) {
      if (Action.Previous == unsigned(-1)) {
        Asm->OutStreamer->AddComment("  No further actions");
      } else {
        Asm->OutStreamer->AddComment("  Continue to action " +
                                     Twine(Action.Previous + 1));
      }
    }
    Asm->emitSLEB128(Action.NextAction);
  }

  if (HaveTTData) {
    Asm->emitAlignment(Align(4));
    emitTypeInfos(TTypeEncoding, TTBaseLabel);
  }

  Asm->emitAlignment(Align(4));
  return GCCETSym;
}

void EHStreamer::emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) {
  const MachineFunction *MF = Asm->MF;
  const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
  const std::vector<unsigned> &FilterIds = MF->getFilterIds();

  const bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();

  int Entry = 0;
  // Emit the Catch TypeInfos.
  if (VerboseAsm && !TypeInfos.empty()) {
    Asm->OutStreamer->AddComment(">> Catch TypeInfos <<");
    Asm->OutStreamer->addBlankLine();
    Entry = TypeInfos.size();
  }

  for (const GlobalValue *GV : llvm::reverse(TypeInfos)) {
    if (VerboseAsm)
      Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--));
    Asm->emitTTypeReference(GV, TTypeEncoding);
  }

  Asm->OutStreamer->emitLabel(TTBaseLabel);

  // Emit the Exception Specifications.
  if (VerboseAsm && !FilterIds.empty()) {
    Asm->OutStreamer->AddComment(">> Filter TypeInfos <<");
    Asm->OutStreamer->addBlankLine();
    Entry = 0;
  }
  for (std::vector<unsigned>::const_iterator
         I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
    unsigned TypeID = *I;
    if (VerboseAsm) {
      --Entry;
      if (isFilterEHSelector(TypeID))
        Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry));
    }

    Asm->emitULEB128(TypeID);
  }
}
