//===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===//
//
// 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 DWARF exception info into asm files.
//
//===----------------------------------------------------------------------===//

#include "DwarfException.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;

DwarfCFIException::DwarfCFIException(AsmPrinter *A) : EHStreamer(A) {}

DwarfCFIException::~DwarfCFIException() = default;

void DwarfCFIException::addPersonality(const GlobalValue *Personality) {
  if (!llvm::is_contained(Personalities, Personality))
    Personalities.push_back(Personality);
}

/// endModule - Emit all exception information that should come after the
/// content.
void DwarfCFIException::endModule() {
  // SjLj uses this pass and it doesn't need this info.
  if (!Asm->MAI.usesCFIForEH())
    return;

  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();

  unsigned PerEncoding = TLOF.getPersonalityEncoding();

  if ((PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect)
    return;

  // Emit indirect reference table for all used personality functions
  for (const GlobalValue *Personality : Personalities) {
    MCSymbol *Sym = Asm->getSymbol(Personality);
    TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->getDataLayout(), Sym,
                              Asm->MMI);
  }
  Personalities.clear();
}

void DwarfCFIException::beginFunction(const MachineFunction *MF) {
  shouldEmitPersonality = shouldEmitLSDA = false;
  const Function &F = MF->getFunction();

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

  // See if we need frame move info.
  bool shouldEmitMoves =
      Asm->getFunctionCFISectionType(*MF) != AsmPrinter::CFISection::None;

  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
  unsigned PerEncoding = TLOF.getPersonalityEncoding();
  const GlobalValue *Per = nullptr;
  if (F.hasPersonalityFn())
    Per = dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());

  // Emit a personality function even when there are no landing pads
  forceEmitPersonality =
      // ...if a personality function is explicitly specified
      F.hasPersonalityFn() &&
      // ... and it's not known to be a noop in the absence of invokes
      !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
      // ... and we're not explicitly asked not to emit it
      F.needsUnwindTableEntry();

  shouldEmitPersonality =
      (forceEmitPersonality ||
       (hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) &&
      Per;

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

  const MCAsmInfo &MAI = MF->getContext().getAsmInfo();
  if (MAI.getExceptionHandlingType() != ExceptionHandling::None)
    shouldEmitCFI =
        MAI.usesCFIForEH() && (shouldEmitPersonality || shouldEmitMoves);
  else
    shouldEmitCFI = Asm->usesCFIWithoutEH() && shouldEmitMoves;
}

void DwarfCFIException::beginBasicBlockSection(const MachineBasicBlock &MBB) {
  if (!shouldEmitCFI)
    return;

  if (!hasEmittedCFISections) {
    AsmPrinter::CFISection CFISecType = Asm->getModuleCFISectionType();
    // If we don't say anything it implies `.cfi_sections .eh_frame`, so we
    // chose not to be verbose in that case. And with `ForceDwarfFrameSection`,
    // we should always emit .debug_frame.
    if (CFISecType == AsmPrinter::CFISection::Debug ||
        Asm->TM.Options.ForceDwarfFrameSection ||
        Asm->TM.Options.MCOptions.EmitSFrameUnwind)
      Asm->OutStreamer->emitCFISections(
          CFISecType == AsmPrinter::CFISection::EH, true,
          Asm->TM.Options.MCOptions.EmitSFrameUnwind);
    hasEmittedCFISections = true;
  }

  Asm->OutStreamer->emitCFIStartProc(/*IsSimple=*/false);

  // Indicate personality routine, if any.
  if (!shouldEmitPersonality)
    return;

  auto &F = MBB.getParent()->getFunction();
  auto *P = dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
  assert(P && "Expected personality function");
  // Record the personality function.
  addPersonality(P);

  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
  unsigned PerEncoding = TLOF.getPersonalityEncoding();
  const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(P, Asm->TM, MMI);
  Asm->OutStreamer->emitCFIPersonality(Sym, PerEncoding);

  // Provide LSDA information.
  if (shouldEmitLSDA)
    Asm->OutStreamer->emitCFILsda(Asm->getMBBExceptionSym(MBB),
                                  TLOF.getLSDAEncoding());
}

void DwarfCFIException::endBasicBlockSection(const MachineBasicBlock &MBB) {
  if (shouldEmitCFI)
    Asm->OutStreamer->emitCFIEndProc();
}

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

  emitExceptionTable();
}
