//===-- lib/DebugInfo/Symbolize/MarkupFilter.cpp -------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file defines the implementation of a filter that replaces symbolizer
/// markup with human-readable expressions.
///
/// See https://llvm.org/docs/SymbolizerMarkupFormat.html
///
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/Symbolize/MarkupFilter.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/Symbolize/Markup.h"
#include "llvm/DebugInfo/Symbolize/Symbolize.h"
#include "llvm/Debuginfod/Debuginfod.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>

using namespace llvm;
using namespace llvm::symbolize;

MarkupFilter::MarkupFilter(raw_ostream &OS, LLVMSymbolizer &Symbolizer,
                           std::optional<bool> ColorsEnabled)
    : OS(OS), Symbolizer(Symbolizer),
      ColorsEnabled(
          ColorsEnabled.value_or(WithColor::defaultAutoDetectFunction()(OS))) {}

void MarkupFilter::filter(StringRef Line) {
  this->Line = Line;
  resetColor();

  Parser.parseLine(Line);
  SmallVector<MarkupNode> DeferredNodes;
  // See if the line is a contextual (i.e. contains a contextual element).
  // In this case, anything after the contextual element is elided, or the whole
  // line may be elided.
  while (std::optional<MarkupNode> Node = Parser.nextNode()) {
    // If this was a contextual line, then summarily stop processing.
    if (tryContextualElement(*Node, DeferredNodes))
      return;
    // This node may yet be part of an elided contextual line.
    DeferredNodes.push_back(*Node);
  }

  // This was not a contextual line, so nothing in it should be elided.
  endAnyModuleInfoLine();
  for (const MarkupNode &Node : DeferredNodes)
    filterNode(Node);
}

void MarkupFilter::finish() {
  Parser.flush();
  while (std::optional<MarkupNode> Node = Parser.nextNode())
    filterNode(*Node);
  endAnyModuleInfoLine();
  resetColor();
  Modules.clear();
  MMaps.clear();
}

// See if the given node is a contextual element and handle it if so. This may
// either output or defer the element; in the former case, it will first emit
// any DeferredNodes.
//
// Returns true if the given element was a contextual element. In this case,
// DeferredNodes should be considered handled and should not be emitted. The
// rest of the containing line must also be ignored in case the element was
// deferred to a following line.
bool MarkupFilter::tryContextualElement(
    const MarkupNode &Node, const SmallVector<MarkupNode> &DeferredNodes) {
  if (tryMMap(Node, DeferredNodes))
    return true;
  if (tryReset(Node, DeferredNodes))
    return true;
  return tryModule(Node, DeferredNodes);
}

bool MarkupFilter::tryMMap(const MarkupNode &Node,
                           const SmallVector<MarkupNode> &DeferredNodes) {
  if (Node.Tag != "mmap")
    return false;
  std::optional<MMap> ParsedMMap = parseMMap(Node);
  if (!ParsedMMap)
    return true;

  if (const MMap *M = getOverlappingMMap(*ParsedMMap)) {
    WithColor::error(errs())
        << formatv("overlapping mmap: #{0:x} [{1:x}-{2:x}]\n", M->Mod->ID,
                   M->Addr, M->Addr + M->Size - 1);
    reportLocation(Node.Fields[0].begin());
    return true;
  }

  auto Res = MMaps.emplace(ParsedMMap->Addr, std::move(*ParsedMMap));
  assert(Res.second && "Overlap check should ensure emplace succeeds.");
  MMap &MMap = Res.first->second;

  if (!MIL || MIL->Mod != MMap.Mod) {
    endAnyModuleInfoLine();
    for (const MarkupNode &Node : DeferredNodes)
      filterNode(Node);
    beginModuleInfoLine(MMap.Mod);
    OS << "; adds";
  }
  MIL->MMaps.push_back(&MMap);
  return true;
}

bool MarkupFilter::tryReset(const MarkupNode &Node,
                            const SmallVector<MarkupNode> &DeferredNodes) {
  if (Node.Tag != "reset")
    return false;
  if (!checkNumFields(Node, 0))
    return true;

  if (!Modules.empty() || !MMaps.empty()) {
    endAnyModuleInfoLine();
    for (const MarkupNode &Node : DeferredNodes)
      filterNode(Node);
    highlight();
    OS << "[[[reset]]]" << lineEnding();
    restoreColor();

    Modules.clear();
    MMaps.clear();
  }
  return true;
}

bool MarkupFilter::tryModule(const MarkupNode &Node,
                             const SmallVector<MarkupNode> &DeferredNodes) {
  if (Node.Tag != "module")
    return false;
  std::optional<Module> ParsedModule = parseModule(Node);
  if (!ParsedModule)
    return true;

  auto Res = Modules.try_emplace(
      ParsedModule->ID, std::make_unique<Module>(std::move(*ParsedModule)));
  if (!Res.second) {
    WithColor::error(errs()) << "duplicate module ID\n";
    reportLocation(Node.Fields[0].begin());
    return true;
  }
  Module &Module = *Res.first->second;

  endAnyModuleInfoLine();
  for (const MarkupNode &Node : DeferredNodes)
    filterNode(Node);
  beginModuleInfoLine(&Module);
  OS << "; BuildID=";
  printValue(toHex(Module.BuildID, /*LowerCase=*/true));
  return true;
}

void MarkupFilter::beginModuleInfoLine(const Module *M) {
  highlight();
  OS << "[[[ELF module";
  printValue(formatv(" #{0:x} ", M->ID));
  OS << '"';
  printValue(M->Name);
  OS << '"';
  MIL = ModuleInfoLine{M};
}

void MarkupFilter::endAnyModuleInfoLine() {
  if (!MIL)
    return;
  llvm::stable_sort(MIL->MMaps, [](const MMap *A, const MMap *B) {
    return A->Addr < B->Addr;
  });
  for (const MMap *M : MIL->MMaps) {
    OS << (M == MIL->MMaps.front() ? ' ' : ',');
    OS << '[';
    printValue(formatv("{0:x}", M->Addr));
    OS << '-';
    printValue(formatv("{0:x}", M->Addr + M->Size - 1));
    OS << "](";
    printValue(M->Mode);
    OS << ')';
  }
  OS << "]]]" << lineEnding();
  restoreColor();
  MIL.reset();
}

// Handle a node that is known not to be a contextual element.
void MarkupFilter::filterNode(const MarkupNode &Node) {
  if (!checkTag(Node))
    return;
  if (tryPresentation(Node))
    return;
  if (trySGR(Node))
    return;

  OS << Node.Text;
}

bool MarkupFilter::tryPresentation(const MarkupNode &Node) {
  if (trySymbol(Node))
    return true;
  if (tryPC(Node))
    return true;
  if (tryBackTrace(Node))
    return true;
  return tryData(Node);
}

bool MarkupFilter::trySymbol(const MarkupNode &Node) {
  if (Node.Tag != "symbol")
    return false;
  if (!checkNumFields(Node, 1))
    return true;

  highlight();
  OS << llvm::demangle(Node.Fields.front().str());
  restoreColor();
  return true;
}

bool MarkupFilter::tryPC(const MarkupNode &Node) {
  if (Node.Tag != "pc")
    return false;
  if (!checkNumFieldsAtLeast(Node, 1))
    return true;
  if (!checkNumFieldsAtMost(Node, 2))
    return true;

  std::optional<uint64_t> Addr = parseAddr(Node.Fields[0]);
  if (!Addr)
    return true;

  // PC addresses that aren't part of a backtrace are assumed to be precise code
  // locations.
  PCType Type = PCType::PreciseCode;
  if (Node.Fields.size() == 2) {
    std::optional<PCType> ParsedType = parsePCType(Node.Fields[1]);
    if (!ParsedType)
      return true;
    Type = *ParsedType;
  }
  *Addr = adjustAddr(*Addr, Type);

  const MMap *MMap = getContainingMMap(*Addr);
  if (!MMap) {
    WithColor::error() << "no mmap covers address\n";
    reportLocation(Node.Fields[0].begin());
    printRawElement(Node);
    return true;
  }

  Expected<DILineInfo> LI = Symbolizer.symbolizeCode(
      MMap->Mod->BuildID, {MMap->getModuleRelativeAddr(*Addr)});
  if (!LI) {
    WithColor::defaultErrorHandler(LI.takeError());
    printRawElement(Node);
    return true;
  }
  if (!*LI) {
    printRawElement(Node);
    return true;
  }

  highlight();
  printValue(LI->FunctionName);
  OS << '[';
  printValue(LI->FileName);
  OS << ':';
  printValue(Twine(LI->Line));
  OS << ']';
  restoreColor();
  return true;
}

bool MarkupFilter::tryBackTrace(const MarkupNode &Node) {
  if (Node.Tag != "bt")
    return false;
  if (!checkNumFieldsAtLeast(Node, 2))
    return true;
  if (!checkNumFieldsAtMost(Node, 3))
    return true;

  std::optional<uint64_t> FrameNumber = parseFrameNumber(Node.Fields[0]);
  if (!FrameNumber)
    return true;

  std::optional<uint64_t> Addr = parseAddr(Node.Fields[1]);
  if (!Addr)
    return true;

  // Backtrace addresses are assumed to be return addresses by default.
  PCType Type = PCType::ReturnAddress;
  if (Node.Fields.size() == 3) {
    std::optional<PCType> ParsedType = parsePCType(Node.Fields[2]);
    if (!ParsedType)
      return true;
    Type = *ParsedType;
  }
  *Addr = adjustAddr(*Addr, Type);

  const MMap *MMap = getContainingMMap(*Addr);
  if (!MMap) {
    WithColor::error() << "no mmap covers address\n";
    reportLocation(Node.Fields[0].begin());
    printRawElement(Node);
    return true;
  }
  uint64_t MRA = MMap->getModuleRelativeAddr(*Addr);

  Expected<DIInliningInfo> II =
      Symbolizer.symbolizeInlinedCode(MMap->Mod->BuildID, {MRA});
  if (!II) {
    WithColor::defaultErrorHandler(II.takeError());
    printRawElement(Node);
    return true;
  }

  highlight();
  for (unsigned I = 0, E = II->getNumberOfFrames(); I != E; ++I) {
    auto Header = formatv("{0, +6}", formatv("#{0}", FrameNumber)).sstr<16>();
    // Don't highlight the # sign as a value.
    size_t NumberIdx = Header.find("#") + 1;
    OS << Header.substr(0, NumberIdx);
    printValue(Header.substr(NumberIdx));
    if (I == E - 1) {
      OS << "   ";
    } else {
      OS << '.';
      printValue(formatv("{0, -2}", I + 1));
    }
    printValue(formatv(" {0:x16} ", *Addr));

    DILineInfo LI = II->getFrame(I);
    if (LI) {
      printValue(LI.FunctionName);
      OS << ' ';
      printValue(LI.FileName);
      OS << ':';
      printValue(Twine(LI.Line));
      OS << ':';
      printValue(Twine(LI.Column));
      OS << ' ';
    }
    OS << '(';
    printValue(MMap->Mod->Name);
    OS << "+";
    printValue(formatv("{0:x}", MRA));
    OS << ')';
    if (I != E - 1)
      OS << lineEnding();
  }
  restoreColor();
  return true;
}

bool MarkupFilter::tryData(const MarkupNode &Node) {
  if (Node.Tag != "data")
    return false;
  if (!checkNumFields(Node, 1))
    return true;
  std::optional<uint64_t> Addr = parseAddr(Node.Fields[0]);
  if (!Addr)
    return true;

  const MMap *MMap = getContainingMMap(*Addr);
  if (!MMap) {
    WithColor::error() << "no mmap covers address\n";
    reportLocation(Node.Fields[0].begin());
    printRawElement(Node);
    return true;
  }

  Expected<DIGlobal> Symbol = Symbolizer.symbolizeData(
      MMap->Mod->BuildID, {MMap->getModuleRelativeAddr(*Addr)});
  if (!Symbol) {
    WithColor::defaultErrorHandler(Symbol.takeError());
    printRawElement(Node);
    return true;
  }

  highlight();
  OS << Symbol->Name;
  restoreColor();
  return true;
}

bool MarkupFilter::trySGR(const MarkupNode &Node) {
  if (Node.Text == "\033[0m") {
    resetColor();
    return true;
  }
  if (Node.Text == "\033[1m") {
    Bold = true;
    if (ColorsEnabled)
      OS.changeColor(raw_ostream::Colors::SAVEDCOLOR, Bold);
    return true;
  }
  auto SGRColor = StringSwitch<std::optional<raw_ostream::Colors>>(Node.Text)
                      .Case("\033[30m", raw_ostream::Colors::BLACK)
                      .Case("\033[31m", raw_ostream::Colors::RED)
                      .Case("\033[32m", raw_ostream::Colors::GREEN)
                      .Case("\033[33m", raw_ostream::Colors::YELLOW)
                      .Case("\033[34m", raw_ostream::Colors::BLUE)
                      .Case("\033[35m", raw_ostream::Colors::MAGENTA)
                      .Case("\033[36m", raw_ostream::Colors::CYAN)
                      .Case("\033[37m", raw_ostream::Colors::WHITE)
                      .Default(std::nullopt);
  if (SGRColor) {
    Color = *SGRColor;
    if (ColorsEnabled)
      OS.changeColor(*Color);
    return true;
  }

  return false;
}

// Begin highlighting text by picking a different color than the current color
// state.
void MarkupFilter::highlight() {
  if (!ColorsEnabled)
    return;
  OS.changeColor(Color == raw_ostream::Colors::BLUE ? raw_ostream::Colors::CYAN
                                                    : raw_ostream::Colors::BLUE,
                 Bold);
}

// Begin highlighting a field within a highlighted markup string.
void MarkupFilter::highlightValue() {
  if (!ColorsEnabled)
    return;
  OS.changeColor(raw_ostream::Colors::GREEN, Bold);
}

// Set the output stream's color to the current color and bold state of the SGR
// abstract machine.
void MarkupFilter::restoreColor() {
  if (!ColorsEnabled)
    return;
  if (Color) {
    OS.changeColor(*Color, Bold);
  } else {
    OS.resetColor();
    if (Bold)
      OS.changeColor(raw_ostream::Colors::SAVEDCOLOR, Bold);
  }
}

// Set the SGR and output stream's color and bold states back to the default.
void MarkupFilter::resetColor() {
  if (!Color && !Bold)
    return;
  Color.reset();
  Bold = false;
  if (ColorsEnabled)
    OS.resetColor();
}

void MarkupFilter::printRawElement(const MarkupNode &Element) {
  highlight();
  OS << "[[[";
  printValue(Element.Tag);
  for (StringRef Field : Element.Fields) {
    OS << ':';
    printValue(Field);
  }
  OS << "]]]";
  restoreColor();
}

void MarkupFilter::printValue(Twine Value) {
  highlightValue();
  OS << Value;
  highlight();
}

// This macro helps reduce the amount of indirection done through Optional
// below, since the usual case upon returning a std::nullopt Optional is to
// return std::nullopt.
#define ASSIGN_OR_RETURN_NONE(TYPE, NAME, EXPR)                                \
  auto NAME##Opt = (EXPR);                                                     \
  if (!NAME##Opt)                                                              \
    return std::nullopt;                                                       \
  TYPE NAME = std::move(*NAME##Opt)

std::optional<MarkupFilter::Module>
MarkupFilter::parseModule(const MarkupNode &Element) const {
  if (!checkNumFieldsAtLeast(Element, 3))
    return std::nullopt;
  ASSIGN_OR_RETURN_NONE(uint64_t, ID, parseModuleID(Element.Fields[0]));
  StringRef Name = Element.Fields[1];
  StringRef Type = Element.Fields[2];
  if (Type != "elf") {
    WithColor::error() << "unknown module type\n";
    reportLocation(Type.begin());
    return std::nullopt;
  }
  if (!checkNumFields(Element, 4))
    return std::nullopt;
  ASSIGN_OR_RETURN_NONE(SmallVector<uint8_t>, BuildID,
                        parseBuildID(Element.Fields[3]));
  return Module{ID, Name.str(), std::move(BuildID)};
}

std::optional<MarkupFilter::MMap>
MarkupFilter::parseMMap(const MarkupNode &Element) const {
  if (!checkNumFieldsAtLeast(Element, 3))
    return std::nullopt;
  ASSIGN_OR_RETURN_NONE(uint64_t, Addr, parseAddr(Element.Fields[0]));
  ASSIGN_OR_RETURN_NONE(uint64_t, Size, parseSize(Element.Fields[1]));
  StringRef Type = Element.Fields[2];
  if (Type != "load") {
    WithColor::error() << "unknown mmap type\n";
    reportLocation(Type.begin());
    return std::nullopt;
  }
  if (!checkNumFields(Element, 6))
    return std::nullopt;
  ASSIGN_OR_RETURN_NONE(uint64_t, ID, parseModuleID(Element.Fields[3]));
  ASSIGN_OR_RETURN_NONE(std::string, Mode, parseMode(Element.Fields[4]));
  auto It = Modules.find(ID);
  if (It == Modules.end()) {
    WithColor::error() << "unknown module ID\n";
    reportLocation(Element.Fields[3].begin());
    return std::nullopt;
  }
  ASSIGN_OR_RETURN_NONE(uint64_t, ModuleRelativeAddr,
                        parseAddr(Element.Fields[5]));
  return MMap{Addr, Size, It->second.get(), std::move(Mode),
              ModuleRelativeAddr};
}

// Parse an address (%p in the spec).
std::optional<uint64_t> MarkupFilter::parseAddr(StringRef Str) const {
  if (Str.empty()) {
    reportTypeError(Str, "address");
    return std::nullopt;
  }
  if (all_of(Str, [](char C) { return C == '0'; }))
    return 0;
  if (!Str.startswith("0x")) {
    reportTypeError(Str, "address");
    return std::nullopt;
  }
  uint64_t Addr;
  if (Str.drop_front(2).getAsInteger(16, Addr)) {
    reportTypeError(Str, "address");
    return std::nullopt;
  }
  return Addr;
}

// Parse a module ID (%i in the spec).
std::optional<uint64_t> MarkupFilter::parseModuleID(StringRef Str) const {
  uint64_t ID;
  if (Str.getAsInteger(0, ID)) {
    reportTypeError(Str, "module ID");
    return std::nullopt;
  }
  return ID;
}

// Parse a size (%i in the spec).
std::optional<uint64_t> MarkupFilter::parseSize(StringRef Str) const {
  uint64_t ID;
  if (Str.getAsInteger(0, ID)) {
    reportTypeError(Str, "size");
    return std::nullopt;
  }
  return ID;
}

// Parse a frame number (%i in the spec).
std::optional<uint64_t> MarkupFilter::parseFrameNumber(StringRef Str) const {
  uint64_t ID;
  if (Str.getAsInteger(10, ID)) {
    reportTypeError(Str, "frame number");
    return std::nullopt;
  }
  return ID;
}

// Parse a build ID (%x in the spec).
std::optional<SmallVector<uint8_t>>
MarkupFilter::parseBuildID(StringRef Str) const {
  std::string Bytes;
  if (Str.empty() || Str.size() % 2 || !tryGetFromHex(Str, Bytes)) {
    reportTypeError(Str, "build ID");
    return std::nullopt;
  }
  ArrayRef<uint8_t> BuildID(reinterpret_cast<const uint8_t *>(Bytes.data()),
                            Bytes.size());
  return SmallVector<uint8_t>(BuildID.begin(), BuildID.end());
}

// Parses the mode string for an mmap element.
std::optional<std::string> MarkupFilter::parseMode(StringRef Str) const {
  if (Str.empty()) {
    reportTypeError(Str, "mode");
    return std::nullopt;
  }

  // Pop off each of r/R, w/W, and x/X from the front, in that order.
  StringRef Remainder = Str;
  if (!Remainder.empty() && tolower(Remainder.front()) == 'r')
    Remainder = Remainder.drop_front();
  if (!Remainder.empty() && tolower(Remainder.front()) == 'w')
    Remainder = Remainder.drop_front();
  if (!Remainder.empty() && tolower(Remainder.front()) == 'x')
    Remainder = Remainder.drop_front();

  // If anything remains, then the string wasn't a mode.
  if (!Remainder.empty()) {
    reportTypeError(Str, "mode");
    return std::nullopt;
  }

  // Normalize the mode.
  return Str.lower();
}

std::optional<MarkupFilter::PCType>
MarkupFilter::parsePCType(StringRef Str) const {
  std::optional<MarkupFilter::PCType> Type =
      StringSwitch<std::optional<MarkupFilter::PCType>>(Str)
          .Case("ra", MarkupFilter::PCType::ReturnAddress)
          .Case("pc", MarkupFilter::PCType::PreciseCode)
          .Default(std::nullopt);
  if (!Type)
    reportTypeError(Str, "PC type");
  return Type;
}

bool MarkupFilter::checkTag(const MarkupNode &Node) const {
  if (any_of(Node.Tag, [](char C) { return C < 'a' || C > 'z'; })) {
    WithColor::error(errs()) << "tags must be all lowercase characters\n";
    reportLocation(Node.Tag.begin());
    return false;
  }
  return true;
}

bool MarkupFilter::checkNumFields(const MarkupNode &Element,
                                  size_t Size) const {
  if (Element.Fields.size() != Size) {
    WithColor::error(errs()) << "expected " << Size << " field(s); found "
                             << Element.Fields.size() << "\n";
    reportLocation(Element.Tag.end());
    return false;
  }
  return true;
}

bool MarkupFilter::checkNumFieldsAtLeast(const MarkupNode &Element,
                                         size_t Size) const {
  if (Element.Fields.size() < Size) {
    WithColor::error(errs())
        << "expected at least " << Size << " field(s); found "
        << Element.Fields.size() << "\n";
    reportLocation(Element.Tag.end());
    return false;
  }
  return true;
}

bool MarkupFilter::checkNumFieldsAtMost(const MarkupNode &Element,
                                        size_t Size) const {
  if (Element.Fields.size() > Size) {
    WithColor::error(errs())
        << "expected at most " << Size << " field(s); found "
        << Element.Fields.size() << "\n";
    reportLocation(Element.Tag.end());
    return false;
  }
  return true;
}

void MarkupFilter::reportTypeError(StringRef Str, StringRef TypeName) const {
  WithColor::error(errs()) << "expected " << TypeName << "; found '" << Str
                           << "'\n";
  reportLocation(Str.begin());
}

// Prints two lines that point out the given location in the current Line using
// a caret. The iterator must be within the bounds of the most recent line
// passed to beginLine().
void MarkupFilter::reportLocation(StringRef::iterator Loc) const {
  errs() << Line;
  WithColor(errs().indent(Loc - Line.begin()), HighlightColor::String) << '^';
  errs() << '\n';
}

// Checks for an existing mmap that overlaps the given one and returns a
// pointer to one of them.
const MarkupFilter::MMap *
MarkupFilter::getOverlappingMMap(const MMap &Map) const {
  // If the given map contains the start of another mmap, they overlap.
  auto I = MMaps.upper_bound(Map.Addr);
  if (I != MMaps.end() && Map.contains(I->second.Addr))
    return &I->second;

  // If no element starts inside the given mmap, the only possible overlap would
  // be if the preceding mmap contains the start point of the given mmap.
  if (I != MMaps.begin()) {
    --I;
    if (I->second.contains(Map.Addr))
      return &I->second;
  }
  return nullptr;
}

// Returns the MMap that contains the given address or nullptr if none.
const MarkupFilter::MMap *MarkupFilter::getContainingMMap(uint64_t Addr) const {
  // Find the first mmap starting >= Addr.
  auto I = MMaps.lower_bound(Addr);
  if (I != MMaps.end() && I->second.contains(Addr))
    return &I->second;

  // The previous mmap is the last one starting < Addr.
  if (I == MMaps.begin())
    return nullptr;
  --I;
  return I->second.contains(Addr) ? &I->second : nullptr;
}

uint64_t MarkupFilter::adjustAddr(uint64_t Addr, PCType Type) const {
  // Decrementing return addresses by one moves them into the call instruction.
  // The address doesn't have to be the start of the call instruction, just some
  // byte on the inside. Subtracting one avoids needing detailed instruction
  // length information here.
  return Type == MarkupFilter::PCType::ReturnAddress ? Addr - 1 : Addr;
}

StringRef MarkupFilter::lineEnding() const {
  return Line.endswith("\r\n") ? "\r\n" : "\n";
}

bool MarkupFilter::MMap::contains(uint64_t Addr) const {
  return this->Addr <= Addr && Addr < this->Addr + Size;
}

// Returns the module-relative address for a given virtual address.
uint64_t MarkupFilter::MMap::getModuleRelativeAddr(uint64_t Addr) const {
  return Addr - this->Addr + ModuleRelativeAddr;
}
