//===------- BacktraceTools.cpp - Backtrace symbolication tools ----------===//
//
// 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/ExecutionEngine/Orc/BacktraceTools.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MemoryBuffer.h"

namespace llvm::orc {

Expected<std::shared_ptr<SymbolTableDumpPlugin>>
SymbolTableDumpPlugin::Create(StringRef Path) {
  std::error_code EC;
  auto P = std::make_shared<SymbolTableDumpPlugin>(Path, EC);
  if (EC)
    return createFileError(Path, EC);
  return P;
}

SymbolTableDumpPlugin::SymbolTableDumpPlugin(StringRef Path,
                                             std::error_code &EC)
    : OutputStream(Path, EC) {}

void SymbolTableDumpPlugin::modifyPassConfig(
    MaterializationResponsibility &MR, jitlink::LinkGraph &G,
    jitlink::PassConfiguration &Config) {

  Config.PostAllocationPasses.push_back([this](jitlink::LinkGraph &G) -> Error {
    std::scoped_lock<std::mutex> Lock(DumpMutex);

    OutputStream << "\"" << G.getName() << "\"\n";
    for (auto &Sec : G.sections()) {
      // NoAlloc symbols don't exist in the executing process, so can't
      // contribute to symbolication. (Note: We leave Finalize-liftime symbols
      // in for now in case of crashes during finalization, but we should
      // probably make this optional).
      if (Sec.getMemLifetime() == MemLifetime::NoAlloc)
        continue;

      // Write out named symbols. Anonymous symbols are skipped, since they
      // don't add any information for symbolication purposes.
      for (auto *Sym : Sec.symbols()) {
        if (Sym->hasName())
          OutputStream << formatv("{0:x}", Sym->getAddress().getValue()) << " "
                       << Sym->getName() << "\n";
      }
    }

    OutputStream.flush();
    return Error::success();
  });
}

Expected<DumpedSymbolTable> DumpedSymbolTable::Create(StringRef Path) {
  auto MB = MemoryBuffer::getFile(Path);
  if (!MB)
    return createFileError(Path, MB.getError());

  return DumpedSymbolTable(std::move(*MB));
}

DumpedSymbolTable::DumpedSymbolTable(std::unique_ptr<MemoryBuffer> SymtabBuffer)
    : SymtabBuffer(std::move(SymtabBuffer)) {
  parseBuffer();
}

void DumpedSymbolTable::parseBuffer() {
  // Read the symbol table file
  SmallVector<StringRef, 0> Rows;
  SymtabBuffer->getBuffer().split(Rows, '\n');

  StringRef CurGraph = "<unidentified>";
  for (auto Row : Rows) {
    Row = Row.trim();
    if (Row.empty())
      continue;

    // Check for graph name line (enclosed in quotes)
    if (Row.starts_with("\"") && Row.ends_with("\"")) {
      CurGraph = Row.trim('"');
      continue;
    }

    // Parse "address symbol_name" lines, ignoring malformed lines.
    size_t SpacePos = Row.find(' ');
    if (SpacePos == StringRef::npos)
      continue;

    StringRef AddrStr = Row.substr(0, SpacePos);
    StringRef SymName = Row.substr(SpacePos + 1);

    uint64_t Addr;
    if (AddrStr.starts_with("0x"))
      AddrStr = AddrStr.drop_front(2);
    if (AddrStr.getAsInteger(16, Addr))
      continue; // Skip malformed lines

    SymbolInfos[Addr] = {SymName, CurGraph};
  }
}

std::string DumpedSymbolTable::symbolicate(StringRef Backtrace) {
  // Symbolicate the backtrace by replacing rows with empty symbol names
  SmallVector<StringRef, 0> BacktraceRows;
  Backtrace.split(BacktraceRows, '\n');

  std::string Result;
  raw_string_ostream Out(Result);
  for (auto Row : BacktraceRows) {
    // Look for a row ending with a hex number. If there's only one column, or
    // if the last column is not a hex number, then just reproduce the input
    // row.
    auto [RowStart, AddrCol] = Row.rtrim().rsplit(' ');
    auto AddrStr = AddrCol.starts_with("0x") ? AddrCol.drop_front(2) : AddrCol;

    uint64_t Addr;
    if (AddrStr.empty() || AddrStr.getAsInteger(16, Addr)) {
      Out << Row << "\n";
      continue;
    }

    // Search for the address
    auto I = SymbolInfos.upper_bound(Addr);

    // If no JIT symbol entry within 2Gb then skip.
    if (I == SymbolInfos.begin() || (Addr - std::prev(I)->first >= 1U << 31)) {
      Out << Row << "\n";
      continue;
    }

    // Found a symbol. Output modified line.
    auto &[SymAddr, SymInfo] = *std::prev(I);
    Out << RowStart << " " << AddrCol << " " << SymInfo.SymName;
    if (auto Delta = Addr - SymAddr)
      Out << " + " << formatv("{0}", Delta);
    Out << " (" << SymInfo.GraphName << ")\n";
  }

  return Result;
}

} // namespace llvm::orc
