//===- COFFMasmParser.cpp - COFF MASM Assembly Parser ---------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/MC/MCAsmMacro.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbolCOFF.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/SMLoc.h"
#include <cstdint>
#include <utility>

using namespace llvm;

namespace {

class COFFMasmParser : public MCAsmParserExtension {
  template <bool (COFFMasmParser::*HandlerMethod)(StringRef, SMLoc)>
  void addDirectiveHandler(StringRef Directive) {
    MCAsmParser::ExtensionDirectiveHandler Handler =
        std::make_pair(this, HandleDirective<COFFMasmParser, HandlerMethod>);
    getParser().addDirectiveHandler(Directive, Handler);
  }

  bool ParseSectionSwitch(StringRef SectionName, unsigned Characteristics,
                          SectionKind Kind);

  bool ParseSectionSwitch(StringRef SectionName, unsigned Characteristics,
                          SectionKind Kind, StringRef COMDATSymName,
                          COFF::COMDATType Type, Align Alignment);

  bool ParseDirectiveProc(StringRef, SMLoc);
  bool ParseDirectiveEndProc(StringRef, SMLoc);
  bool ParseDirectiveSegment(StringRef, SMLoc);
  bool ParseDirectiveSegmentEnd(StringRef, SMLoc);
  bool ParseDirectiveIncludelib(StringRef, SMLoc);
  bool ParseDirectiveOption(StringRef, SMLoc);

  bool ParseDirectiveAlias(StringRef, SMLoc);

  bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
  bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);

  bool IgnoreDirective(StringRef, SMLoc) {
    while (!getLexer().is(AsmToken::EndOfStatement)) {
      Lex();
    }
    return false;
  }

  void Initialize(MCAsmParser &Parser) override {
    // Call the base implementation.
    MCAsmParserExtension::Initialize(Parser);

    // x64 directives
    addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveAllocStack>(
        ".allocstack");
    addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveEndProlog>(
        ".endprolog");

    // Code label directives
    // label
    // org

    // Conditional control flow directives
    // .break
    // .continue
    // .else
    // .elseif
    // .endif
    // .endw
    // .if
    // .repeat
    // .until
    // .untilcxz
    // .while

    // Data allocation directives
    // align
    // even
    // mmword
    // tbyte
    // xmmword
    // ymmword

    // Listing control directives
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".cref");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".list");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".listall");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".listif");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".listmacro");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".listmacroall");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".nocref");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".nolist");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".nolistif");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".nolistmacro");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>("page");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>("subtitle");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".tfcond");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>("title");

    // Macro directives
    // goto

    // Miscellaneous directives
    addDirectiveHandler<&COFFMasmParser::ParseDirectiveAlias>("alias");
    // assume
    // .fpo
    addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>(
        "includelib");
    addDirectiveHandler<&COFFMasmParser::ParseDirectiveOption>("option");
    // popcontext
    // pushcontext
    // .safeseh

    // Procedure directives
    addDirectiveHandler<&COFFMasmParser::ParseDirectiveEndProc>("endp");
    // invoke (32-bit only)
    addDirectiveHandler<&COFFMasmParser::ParseDirectiveProc>("proc");
    // proto

    // Processor directives; all ignored
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386p");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".387");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".486");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".486p");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".586");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".586p");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".686");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".686p");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".k3d");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".mmx");
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".xmm");

    // Scope directives
    // comm
    // externdef

    // Segment directives
    // .alpha (32-bit only, order segments alphabetically)
    // .dosseg (32-bit only, order segments in DOS convention)
    // .seq (32-bit only, order segments sequentially)
    addDirectiveHandler<&COFFMasmParser::ParseDirectiveSegmentEnd>("ends");
    // group (32-bit only)
    addDirectiveHandler<&COFFMasmParser::ParseDirectiveSegment>("segment");

    // Simplified segment directives
    addDirectiveHandler<&COFFMasmParser::ParseSectionDirectiveCode>(".code");
    // .const
    addDirectiveHandler<
        &COFFMasmParser::ParseSectionDirectiveInitializedData>(".data");
    addDirectiveHandler<
        &COFFMasmParser::ParseSectionDirectiveUninitializedData>(".data?");
    // .exit
    // .fardata
    // .fardata?
    addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".model");
    // .stack
    // .startup

    // String directives, written <name> <directive> <params>
    // catstr (equivalent to <name> TEXTEQU <params>)
    // instr (equivalent to <name> = @InStr(<params>))
    // sizestr (equivalent to <name> = @SizeStr(<params>))
    // substr (equivalent to <name> TEXTEQU @SubStr(<params>))

    // Structure and record directives
    // record
    // typedef
  }

  bool ParseSectionDirectiveCode(StringRef, SMLoc) {
    return ParseSectionSwitch(".text",
                              COFF::IMAGE_SCN_CNT_CODE
                            | COFF::IMAGE_SCN_MEM_EXECUTE
                            | COFF::IMAGE_SCN_MEM_READ,
                              SectionKind::getText());
  }

  bool ParseSectionDirectiveInitializedData(StringRef, SMLoc) {
    return ParseSectionSwitch(".data",
                              COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
                            | COFF::IMAGE_SCN_MEM_READ
                            | COFF::IMAGE_SCN_MEM_WRITE,
                              SectionKind::getData());
  }

  bool ParseSectionDirectiveUninitializedData(StringRef, SMLoc) {
    return ParseSectionSwitch(".bss",
                              COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
                            | COFF::IMAGE_SCN_MEM_READ
                            | COFF::IMAGE_SCN_MEM_WRITE,
                              SectionKind::getBSS());
  }

  /// Stack of active procedure definitions.
  SmallVector<StringRef, 1> CurrentProcedures;
  SmallVector<bool, 1> CurrentProceduresFramed;

public:
  COFFMasmParser() = default;
};

} // end anonymous namespace.

bool COFFMasmParser::ParseSectionSwitch(StringRef SectionName,
                                        unsigned Characteristics,
                                        SectionKind Kind) {
  return ParseSectionSwitch(SectionName, Characteristics, Kind, "",
                            (COFF::COMDATType)0, Align(16));
}

bool COFFMasmParser::ParseSectionSwitch(
    StringRef SectionName, unsigned Characteristics, SectionKind Kind,
    StringRef COMDATSymName, COFF::COMDATType Type, Align Alignment) {
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in section switching directive");
  Lex();

  MCSection *Section = getContext().getCOFFSection(SectionName, Characteristics,
                                                   Kind, COMDATSymName, Type);
  Section->setAlignment(Alignment);
  getStreamer().switchSection(Section);

  return false;
}

bool COFFMasmParser::ParseDirectiveSegment(StringRef Directive, SMLoc Loc) {
  StringRef SegmentName;
  if (!getLexer().is(AsmToken::Identifier))
    return TokError("expected identifier in directive");
  SegmentName = getTok().getIdentifier();
  Lex();

  StringRef SectionName = SegmentName;
  SmallVector<char, 247> SectionNameVector;

  StringRef Class;
  if (SegmentName == "_TEXT" || SegmentName.startswith("_TEXT$")) {
    if (SegmentName.size() == 5) {
      SectionName = ".text";
    } else {
      SectionName =
          (".text$" + SegmentName.substr(6)).toStringRef(SectionNameVector);
    }
    Class = "CODE";
  }

  // Parse all options to end of statement.
  // Alignment defaults to PARA if unspecified.
  int64_t Alignment = 16;
  // Default flags are used only if no characteristics are set.
  bool DefaultCharacteristics = true;
  unsigned Flags = 0;
  // "obsolete" according to the documentation, but still supported.
  bool Readonly = false;
  while (getLexer().isNot(AsmToken::EndOfStatement)) {
    switch (getTok().getKind()) {
    default:
      break;
    case AsmToken::String: {
      // Class identifier; overrides Kind.
      Class = getTok().getStringContents();
      Lex();
      break;
    }
    case AsmToken::Identifier: {
      SMLoc KeywordLoc = getTok().getLoc();
      StringRef Keyword;
      if (getParser().parseIdentifier(Keyword)) {
        llvm_unreachable("failed to parse identifier at an identifier token");
      }
      if (Keyword.equals_insensitive("byte")) {
        Alignment = 1;
      } else if (Keyword.equals_insensitive("word")) {
        Alignment = 2;
      } else if (Keyword.equals_insensitive("dword")) {
        Alignment = 4;
      } else if (Keyword.equals_insensitive("para")) {
        Alignment = 16;
      } else if (Keyword.equals_insensitive("page")) {
        Alignment = 256;
      } else if (Keyword.equals_insensitive("align")) {
        if (getParser().parseToken(AsmToken::LParen) ||
            getParser().parseIntToken(Alignment,
                                      "Expected integer alignment") ||
            getParser().parseToken(AsmToken::RParen)) {
          return Error(getTok().getLoc(),
                       "Expected (n) following ALIGN in SEGMENT directive");
        }
        if (!isPowerOf2_64(Alignment) || Alignment > 8192) {
          return Error(KeywordLoc,
                       "ALIGN argument must be a power of 2 from 1 to 8192");
        }
      } else if (Keyword.equals_insensitive("alias")) {
        if (getParser().parseToken(AsmToken::LParen) ||
            !getTok().is(AsmToken::String))
          return Error(
              getTok().getLoc(),
              "Expected (string) following ALIAS in SEGMENT directive");
        SectionName = getTok().getStringContents();
        Lex();
        if (getParser().parseToken(AsmToken::RParen))
          return Error(
              getTok().getLoc(),
              "Expected (string) following ALIAS in SEGMENT directive");
      } else if (Keyword.equals_insensitive("readonly")) {
        Readonly = true;
      } else {
        unsigned Characteristic =
            StringSwitch<unsigned>(Keyword)
                .CaseLower("info", COFF::IMAGE_SCN_LNK_INFO)
                .CaseLower("read", COFF::IMAGE_SCN_MEM_READ)
                .CaseLower("write", COFF::IMAGE_SCN_MEM_WRITE)
                .CaseLower("execute", COFF::IMAGE_SCN_MEM_EXECUTE)
                .CaseLower("shared", COFF::IMAGE_SCN_MEM_SHARED)
                .CaseLower("nopage", COFF::IMAGE_SCN_MEM_NOT_PAGED)
                .CaseLower("nocache", COFF::IMAGE_SCN_MEM_NOT_CACHED)
                .CaseLower("discard", COFF::IMAGE_SCN_MEM_DISCARDABLE)
                .Default(-1);
        if (Characteristic == static_cast<unsigned>(-1)) {
          return Error(KeywordLoc,
                       "Expected characteristic in SEGMENT directive; found '" +
                           Keyword + "'");
        }
        Flags |= Characteristic;
        DefaultCharacteristics = false;
      }
    }
    }
  }

  SectionKind Kind = StringSwitch<SectionKind>(Class)
                         .CaseLower("data", SectionKind::getData())
                         .CaseLower("code", SectionKind::getText())
                         .CaseLower("const", SectionKind::getReadOnly())
                         .Default(SectionKind::getData());
  if (Kind.isText()) {
    if (DefaultCharacteristics) {
      Flags |= COFF::IMAGE_SCN_MEM_EXECUTE | COFF::IMAGE_SCN_MEM_READ;
    }
    Flags |= COFF::IMAGE_SCN_CNT_CODE;
  } else {
    if (DefaultCharacteristics) {
      Flags |= COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE;
    }
    Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
  }
  if (Readonly) {
    Flags &= ~COFF::IMAGE_SCN_MEM_WRITE;
  }

  MCSection *Section = getContext().getCOFFSection(SectionName, Flags, Kind, "",
                                                   (COFF::COMDATType)(0));
  if (Alignment != 0) {
    Section->setAlignment(Align(Alignment));
  }
  getStreamer().switchSection(Section);
  return false;
}

/// ParseDirectiveSegmentEnd
///  ::= identifier "ends"
bool COFFMasmParser::ParseDirectiveSegmentEnd(StringRef Directive, SMLoc Loc) {
  StringRef SegmentName;
  if (!getLexer().is(AsmToken::Identifier))
    return TokError("expected identifier in directive");
  SegmentName = getTok().getIdentifier();

  // Ignore; no action necessary.
  Lex();
  return false;
}

/// ParseDirectiveIncludelib
///  ::= "includelib" identifier
bool COFFMasmParser::ParseDirectiveIncludelib(StringRef Directive, SMLoc Loc) {
  StringRef Lib;
  if (getParser().parseIdentifier(Lib))
    return TokError("expected identifier in includelib directive");

  unsigned Flags = COFF::IMAGE_SCN_MEM_PRELOAD | COFF::IMAGE_SCN_MEM_16BIT;
  SectionKind Kind = SectionKind::getData();
  getStreamer().pushSection();
  getStreamer().switchSection(getContext().getCOFFSection(
      ".drectve", Flags, Kind, "", (COFF::COMDATType)(0)));
  getStreamer().emitBytes("/DEFAULTLIB:");
  getStreamer().emitBytes(Lib);
  getStreamer().emitBytes(" ");
  getStreamer().popSection();
  return false;
}

/// ParseDirectiveOption
///  ::= "option" option-list
bool COFFMasmParser::ParseDirectiveOption(StringRef Directive, SMLoc Loc) {
  auto parseOption = [&]() -> bool {
    StringRef Option;
    if (getParser().parseIdentifier(Option))
      return TokError("expected identifier for option name");
    if (Option.equals_insensitive("prologue")) {
      StringRef MacroId;
      if (parseToken(AsmToken::Colon) || getParser().parseIdentifier(MacroId))
        return TokError("expected :macroId after OPTION PROLOGUE");
      if (MacroId.equals_insensitive("none")) {
        // Since we currently don't implement prologues/epilogues, NONE is our
        // default.
        return false;
      }
      return TokError("OPTION PROLOGUE is currently unsupported");
    }
    if (Option.equals_insensitive("epilogue")) {
      StringRef MacroId;
      if (parseToken(AsmToken::Colon) || getParser().parseIdentifier(MacroId))
        return TokError("expected :macroId after OPTION EPILOGUE");
      if (MacroId.equals_insensitive("none")) {
        // Since we currently don't implement prologues/epilogues, NONE is our
        // default.
        return false;
      }
      return TokError("OPTION EPILOGUE is currently unsupported");
    }
    return TokError("OPTION '" + Option + "' is currently unsupported");
  };

  if (parseMany(parseOption))
    return addErrorSuffix(" in OPTION directive");
  return false;
}

/// ParseDirectiveProc
/// TODO(epastor): Implement parameters and other attributes.
///  ::= label "proc" [[distance]]
///          statements
///      label "endproc"
bool COFFMasmParser::ParseDirectiveProc(StringRef Directive, SMLoc Loc) {
  StringRef Label;
  if (getParser().parseIdentifier(Label))
    return Error(Loc, "expected identifier for procedure");
  if (getLexer().is(AsmToken::Identifier)) {
    StringRef nextVal = getTok().getString();
    SMLoc nextLoc = getTok().getLoc();
    if (nextVal.equals_insensitive("far")) {
      // TODO(epastor): Handle far procedure definitions.
      Lex();
      return Error(nextLoc, "far procedure definitions not yet supported");
    } else if (nextVal.equals_insensitive("near")) {
      Lex();
      nextVal = getTok().getString();
      nextLoc = getTok().getLoc();
    }
  }
  MCSymbolCOFF *Sym = cast<MCSymbolCOFF>(getContext().getOrCreateSymbol(Label));

  // Define symbol as simple external function
  Sym->setExternal(true);
  Sym->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT);

  bool Framed = false;
  if (getLexer().is(AsmToken::Identifier) &&
      getTok().getString().equals_insensitive("frame")) {
    Lex();
    Framed = true;
    getStreamer().emitWinCFIStartProc(Sym, Loc);
  }
  getStreamer().emitLabel(Sym, Loc);

  CurrentProcedures.push_back(Label);
  CurrentProceduresFramed.push_back(Framed);
  return false;
}
bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
  StringRef Label;
  SMLoc LabelLoc = getTok().getLoc();
  if (getParser().parseIdentifier(Label))
    return Error(LabelLoc, "expected identifier for procedure end");

  if (CurrentProcedures.empty())
    return Error(Loc, "endp outside of procedure block");
  else if (!CurrentProcedures.back().equals_insensitive(Label))
    return Error(LabelLoc, "endp does not match current procedure '" +
                               CurrentProcedures.back() + "'");

  if (CurrentProceduresFramed.back()) {
    getStreamer().emitWinCFIEndProc(Loc);
  }
  CurrentProcedures.pop_back();
  CurrentProceduresFramed.pop_back();
  return false;
}

bool COFFMasmParser::ParseDirectiveAlias(StringRef Directive, SMLoc Loc) {
  std::string AliasName, ActualName;
  if (getTok().isNot(AsmToken::Less) ||
      getParser().parseAngleBracketString(AliasName))
    return Error(getTok().getLoc(), "expected <aliasName>");
  if (getParser().parseToken(AsmToken::Equal))
    return addErrorSuffix(" in " + Directive + " directive");
  if (getTok().isNot(AsmToken::Less) ||
      getParser().parseAngleBracketString(ActualName))
    return Error(getTok().getLoc(), "expected <actualName>");

  MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
  MCSymbol *Actual = getContext().getOrCreateSymbol(ActualName);

  getStreamer().emitWeakReference(Alias, Actual);

  return false;
}

bool COFFMasmParser::ParseSEHDirectiveAllocStack(StringRef Directive,
                                                 SMLoc Loc) {
  int64_t Size;
  SMLoc SizeLoc = getTok().getLoc();
  if (getParser().parseAbsoluteExpression(Size))
    return Error(SizeLoc, "expected integer size");
  if (Size % 8 != 0)
    return Error(SizeLoc, "stack size must be a multiple of 8");
  getStreamer().emitWinCFIAllocStack(static_cast<unsigned>(Size), Loc);
  return false;
}

bool COFFMasmParser::ParseSEHDirectiveEndProlog(StringRef Directive,
                                                SMLoc Loc) {
  getStreamer().emitWinCFIEndProlog(Loc);
  return false;
}

namespace llvm {

MCAsmParserExtension *createCOFFMasmParser() { return new COFFMasmParser; }

} // end namespace llvm
