//===-- CodeGen/AsmPrinter/Win64Exception.cpp - Dwarf Exception Impl ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing Win64 exception info into asm files.
//
//===----------------------------------------------------------------------===//

#include "Win64Exception.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/WinEHFuncInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;

Win64Exception::Win64Exception(AsmPrinter *A)
  : EHStreamer(A), shouldEmitPersonality(false), shouldEmitLSDA(false),
    shouldEmitMoves(false) {}

Win64Exception::~Win64Exception() {}

/// endModule - Emit all exception information that should come after the
/// content.
void Win64Exception::endModule() {
}

void Win64Exception::beginFunction(const MachineFunction *MF) {
  shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;

  // If any landing pads survive, we need an EH table.
  bool hasLandingPads = !MMI->getLandingPads().empty();

  shouldEmitMoves = Asm->needsSEHMoves();

  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
  unsigned PerEncoding = TLOF.getPersonalityEncoding();
  const Function *Per = MF->getMMI().getPersonality();

  shouldEmitPersonality = hasLandingPads &&
    PerEncoding != dwarf::DW_EH_PE_omit && Per;

  unsigned LSDAEncoding = TLOF.getLSDAEncoding();
  shouldEmitLSDA = shouldEmitPersonality &&
    LSDAEncoding != dwarf::DW_EH_PE_omit;


  // If this was an outlined handler, we need to define the label corresponding
  // to the offset of the parent frame relative to the stack pointer after the
  // prologue.
  const Function *F = MF->getFunction();
  const Function *ParentF = MMI->getWinEHParent(F);
  if (F != ParentF) {
    WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF);
    auto I = FuncInfo.CatchHandlerParentFrameObjOffset.find(F);
    if (I != FuncInfo.CatchHandlerParentFrameObjOffset.end()) {
      MCSymbol *HandlerTypeParentFrameOffset =
          Asm->OutContext.getOrCreateParentFrameOffsetSymbol(
              GlobalValue::getRealLinkageName(F->getName()));

      // Emit a symbol assignment.
      Asm->OutStreamer.EmitAssignment(
          HandlerTypeParentFrameOffset,
          MCConstantExpr::Create(I->second, Asm->OutContext));
    }
  }

  if (!shouldEmitPersonality && !shouldEmitMoves)
    return;

  Asm->OutStreamer.EmitWinCFIStartProc(Asm->CurrentFnSym);

  if (!shouldEmitPersonality)
    return;

  const MCSymbol *PersHandlerSym =
      TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
  Asm->OutStreamer.EmitWinEHHandler(PersHandlerSym, true, true);
}

/// endFunction - Gather and emit post-function exception information.
///
void Win64Exception::endFunction(const MachineFunction *MF) {
  if (!shouldEmitPersonality && !shouldEmitMoves)
    return;

  EHPersonality Per = MMI->getPersonalityType();

  // Get rid of any dead landing pads if we're not using a Windows EH scheme. In
  // Windows EH schemes, the landing pad is not actually reachable. It only
  // exists so that we can emit the right table data.
  if (!isMSVCEHPersonality(Per))
    MMI->TidyLandingPads();

  if (shouldEmitPersonality) {
    Asm->OutStreamer.PushSection();

    // Emit an UNWIND_INFO struct describing the prologue.
    Asm->OutStreamer.EmitWinEHHandlerData();

    // Emit the tables appropriate to the personality function in use. If we
    // don't recognize the personality, assume it uses an Itanium-style LSDA.
    if (Per == EHPersonality::MSVC_Win64SEH)
      emitCSpecificHandlerTable();
    else if (Per == EHPersonality::MSVC_CXX)
      emitCXXFrameHandler3Table(MF);
    else
      emitExceptionTable();

    Asm->OutStreamer.PopSection();
  }
  Asm->OutStreamer.EmitWinCFIEndProc();
}

const MCExpr *Win64Exception::createImageRel32(const MCSymbol *Value) {
  if (!Value)
    return MCConstantExpr::Create(0, Asm->OutContext);
  return MCSymbolRefExpr::Create(Value, MCSymbolRefExpr::VK_COFF_IMGREL32,
                                 Asm->OutContext);
}

const MCExpr *Win64Exception::createImageRel32(const GlobalValue *GV) {
  if (!GV)
    return MCConstantExpr::Create(0, Asm->OutContext);
  return createImageRel32(Asm->getSymbol(GV));
}

/// 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;  // One 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->getFunctionBegin();
  MCSymbol *EHFuncEndSym = Asm->getFunctionEnd();

  // 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;
    }
    NumEntries += CSE.LPad->SEHHandlers.size();
  }
  Asm->OutStreamer.EmitIntValue(NumEntries, 4);

  // If there are no actions, we don't need to iterate again.
  if (NumEntries == 0)
    return;

  // 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);
    }

    // Emit an entry for each action.
    for (SEHHandler Handler : LPad->SEHHandlers) {
      Asm->OutStreamer.EmitValue(Begin, 4);
      Asm->OutStreamer.EmitValue(End, 4);

      // Emit the filter or finally function pointer, if present. Otherwise,
      // emit '1' to indicate a catch-all.
      const Function *F = Handler.FilterOrFinally;
      if (F)
        Asm->OutStreamer.EmitValue(createImageRel32(Asm->getSymbol(F)), 4);
      else
        Asm->OutStreamer.EmitIntValue(1, 4);

      // Emit the recovery address, if present. Otherwise, this must be a
      // finally.
      const BlockAddress *BA = Handler.RecoverBA;
      if (BA)
        Asm->OutStreamer.EmitValue(
            createImageRel32(Asm->GetBlockAddressSymbol(BA)), 4);
      else
        Asm->OutStreamer.EmitIntValue(0, 4);
    }
    if (!LPad->SEHHandlers.empty())
      continue;

    // 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.
    size_t NextClauseLabel = 0;
    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];

      // 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(1, 4);
      }
      MCSymbol *ClauseLabel = LPad->ClauseLabels[NextClauseLabel++];
      Asm->OutStreamer.EmitValue(createImageRel32(ClauseLabel), 4);
    }
  }
}

void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) {
  const Function *F = MF->getFunction();
  const Function *ParentF = MMI->getWinEHParent(F);
  auto &OS = Asm->OutStreamer;
  WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF);

  StringRef ParentLinkageName =
      GlobalValue::getRealLinkageName(ParentF->getName());

  MCSymbol *FuncInfoXData =
      Asm->OutContext.GetOrCreateSymbol(Twine("$cppxdata$", ParentLinkageName));
  OS.EmitValue(createImageRel32(FuncInfoXData), 4);

  // 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;
  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
  LandingPads.reserve(PadInfos.size());
  for (const auto &LP : PadInfos)
    LandingPads.push_back(&LP);

  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;

  int LastEHState = -2;

  // The parent function and the catch handlers contribute to the 'ip2state'
  // table.
  for (const auto &MBB : *MF) {
    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!");

      if (SawPotentiallyThrowing) {
        FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1));
        SawPotentiallyThrowing = false;
        LastEHState = -1;
      }

      if (LandingPad->WinEHState != LastEHState)
        FuncInfo.IPToStateList.push_back(
            std::make_pair(BeginLabel, LandingPad->WinEHState));
      LastEHState = LandingPad->WinEHState;
      LastLabel = LandingPad->EndLabels[P.RangeIndex];
    }
  }

  // Defer emission until we've visited the parent function and all the catch
  // handlers.  Cleanups don't contribute to the ip2state table yet, so don't
  // count them.
  if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F))
    return;
  ++FuncInfo.NumIPToStateFuncsVisited;
  if (FuncInfo.NumIPToStateFuncsVisited != FuncInfo.CatchHandlerMaxState.size())
    return;

  MCSymbol *UnwindMapXData = nullptr;
  MCSymbol *TryBlockMapXData = nullptr;
  MCSymbol *IPToStateXData = nullptr;
  if (!FuncInfo.UnwindMap.empty())
    UnwindMapXData = Asm->OutContext.GetOrCreateSymbol(
        Twine("$stateUnwindMap$", ParentLinkageName));
  if (!FuncInfo.TryBlockMap.empty())
    TryBlockMapXData = Asm->OutContext.GetOrCreateSymbol(
        Twine("$tryMap$", ParentLinkageName));
  if (!FuncInfo.IPToStateList.empty())
    IPToStateXData = Asm->OutContext.GetOrCreateSymbol(
        Twine("$ip2state$", ParentLinkageName));

  // FuncInfo {
  //   uint32_t           MagicNumber
  //   int32_t            MaxState;
  //   UnwindMapEntry    *UnwindMap;
  //   uint32_t           NumTryBlocks;
  //   TryBlockMapEntry  *TryBlockMap;
  //   uint32_t           IPMapEntries;
  //   IPToStateMapEntry *IPToStateMap;
  //   uint32_t           UnwindHelp; // (x64/ARM only)
  //   ESTypeList        *ESTypeList;
  //   int32_t            EHFlags;
  // }
  // EHFlags & 1 -> Synchronous exceptions only, no async exceptions.
  // EHFlags & 2 -> ???
  // EHFlags & 4 -> The function is noexcept(true), unwinding can't continue.
  OS.EmitLabel(FuncInfoXData);
  OS.EmitIntValue(0x19930522, 4);                      // MagicNumber
  OS.EmitIntValue(FuncInfo.UnwindMap.size(), 4);       // MaxState
  OS.EmitValue(createImageRel32(UnwindMapXData), 4);   // UnwindMap
  OS.EmitIntValue(FuncInfo.TryBlockMap.size(), 4);     // NumTryBlocks
  OS.EmitValue(createImageRel32(TryBlockMapXData), 4); // TryBlockMap
  OS.EmitIntValue(FuncInfo.IPToStateList.size(), 4);   // IPMapEntries
  OS.EmitValue(createImageRel32(IPToStateXData), 4);   // IPToStateMap
  OS.EmitIntValue(FuncInfo.UnwindHelpFrameOffset, 4);  // UnwindHelp
  OS.EmitIntValue(0, 4);                               // ESTypeList
  OS.EmitIntValue(1, 4);                               // EHFlags

  // UnwindMapEntry {
  //   int32_t ToState;
  //   void  (*Action)();
  // };
  if (UnwindMapXData) {
    OS.EmitLabel(UnwindMapXData);
    for (const WinEHUnwindMapEntry &UME : FuncInfo.UnwindMap) {
      OS.EmitIntValue(UME.ToState, 4);                // ToState
      OS.EmitValue(createImageRel32(UME.Cleanup), 4); // Action
    }
  }

  // TryBlockMap {
  //   int32_t      TryLow;
  //   int32_t      TryHigh;
  //   int32_t      CatchHigh;
  //   int32_t      NumCatches;
  //   HandlerType *HandlerArray;
  // };
  if (TryBlockMapXData) {
    OS.EmitLabel(TryBlockMapXData);
    SmallVector<MCSymbol *, 1> HandlerMaps;
    for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
      WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
      MCSymbol *HandlerMapXData = nullptr;

      if (!TBME.HandlerArray.empty())
        HandlerMapXData =
            Asm->OutContext.GetOrCreateSymbol(Twine("$handlerMap$")
                                                  .concat(Twine(I))
                                                  .concat("$")
                                                  .concat(ParentLinkageName));

      HandlerMaps.push_back(HandlerMapXData);

      int CatchHigh = -1;
      for (WinEHHandlerType &HT : TBME.HandlerArray)
        CatchHigh =
            std::max(CatchHigh, FuncInfo.CatchHandlerMaxState[HT.Handler]);

      assert(TBME.TryLow <= TBME.TryHigh);
      OS.EmitIntValue(TBME.TryLow, 4);                    // TryLow
      OS.EmitIntValue(TBME.TryHigh, 4);                   // TryHigh
      OS.EmitIntValue(CatchHigh, 4);                      // CatchHigh
      OS.EmitIntValue(TBME.HandlerArray.size(), 4);       // NumCatches
      OS.EmitValue(createImageRel32(HandlerMapXData), 4); // HandlerArray
    }

    for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
      WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
      MCSymbol *HandlerMapXData = HandlerMaps[I];
      if (!HandlerMapXData)
        continue;
      // HandlerType {
      //   int32_t         Adjectives;
      //   TypeDescriptor *Type;
      //   int32_t         CatchObjOffset;
      //   void          (*Handler)();
      //   int32_t         ParentFrameOffset; // x64 only
      // };
      OS.EmitLabel(HandlerMapXData);
      for (const WinEHHandlerType &HT : TBME.HandlerArray) {
        MCSymbol *ParentFrameOffset =
            Asm->OutContext.getOrCreateParentFrameOffsetSymbol(
                GlobalValue::getRealLinkageName(HT.Handler->getName()));
        const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::Create(
            ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);

        // Get the frame escape label with the offset of the catch object. If
        // the index is -1, then there is no catch object, and we should emit an
        // offset of zero, indicating that no copy will occur.
        const MCExpr *FrameAllocOffsetRef = nullptr;
        if (HT.CatchObjRecoverIdx >= 0) {
          MCSymbol *FrameAllocOffset =
              Asm->OutContext.getOrCreateFrameAllocSymbol(
                  GlobalValue::getRealLinkageName(ParentF->getName()),
                  HT.CatchObjRecoverIdx);
          FrameAllocOffsetRef = MCSymbolRefExpr::Create(
              FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
        } else {
          FrameAllocOffsetRef = MCConstantExpr::Create(0, Asm->OutContext);
        }

        OS.EmitIntValue(HT.Adjectives, 4);                    // Adjectives
        OS.EmitValue(createImageRel32(HT.TypeDescriptor), 4); // Type
        OS.EmitValue(FrameAllocOffsetRef, 4);                 // CatchObjOffset
        OS.EmitValue(createImageRel32(HT.Handler), 4);        // Handler
        OS.EmitValue(ParentFrameOffsetRef, 4);                // ParentFrameOffset
      }
    }
  }

  // IPToStateMapEntry {
  //   void   *IP;
  //   int32_t State;
  // };
  if (IPToStateXData) {
    OS.EmitLabel(IPToStateXData);
    for (auto &IPStatePair : FuncInfo.IPToStateList) {
      OS.EmitValue(createImageRel32(IPStatePair.first), 4); // IP
      OS.EmitIntValue(IPStatePair.second, 4);               // State
    }
  }
}
