//===-- llvm-symbolizer.cpp - Simple addr2line-like symbolizer ------------===//
//
// 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 utility works much like "addr2line". It is able of transforming
// tuples (module name, module offset) to code locations (function name,
// file, line number, column number). It is targeted for compiler-rt tools
// (especially AddressSanitizer and ThreadSanitizer) that can use it
// to symbolize stack traces in their error reports.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/Symbolize/DIPrinter.h"
#include "llvm/DebugInfo/Symbolize/Symbolize.h"
#include "llvm/Support/COM.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>

using namespace llvm;
using namespace symbolize;

static cl::opt<bool>
ClUseSymbolTable("use-symbol-table", cl::init(true),
                 cl::desc("Prefer names in symbol table to names "
                          "in debug info"));

static cl::opt<FunctionNameKind> ClPrintFunctions(
    "functions", cl::init(FunctionNameKind::LinkageName),
    cl::desc("Print function name for a given address"), cl::ValueOptional,
    cl::values(clEnumValN(FunctionNameKind::None, "none", "omit function name"),
               clEnumValN(FunctionNameKind::ShortName, "short",
                          "print short function name"),
               clEnumValN(FunctionNameKind::LinkageName, "linkage",
                          "print function linkage name"),
               // Sentinel value for unspecified value.
               clEnumValN(FunctionNameKind::LinkageName, "", "")));
static cl::alias ClPrintFunctionsShort("f", cl::desc("Alias for -functions"),
                                       cl::NotHidden, cl::Grouping,
                                       cl::aliasopt(ClPrintFunctions));

static cl::opt<bool>
    ClUseRelativeAddress("relative-address", cl::init(false),
                         cl::desc("Interpret addresses as relative addresses"),
                         cl::ReallyHidden);

static cl::opt<bool> ClUntagAddresses(
    "untag-addresses", cl::init(true),
    cl::desc("Remove memory tags from addresses before symbolization"));

static cl::opt<bool>
    ClPrintInlining("inlining", cl::init(true),
                    cl::desc("Print all inlined frames for a given address"));
static cl::alias
    ClPrintInliningAliasI("i", cl::desc("Alias for -inlining"),
                          cl::NotHidden, cl::aliasopt(ClPrintInlining),
                          cl::Grouping);
static cl::alias
    ClPrintInliningAliasInlines("inlines", cl::desc("Alias for -inlining"),
                                cl::NotHidden, cl::aliasopt(ClPrintInlining));

// -basenames, -s
static cl::opt<bool> ClBasenames("basenames", cl::init(false),
                                 cl::desc("Strip directory names from paths"));
static cl::alias ClBasenamesShort("s", cl::desc("Alias for -basenames"),
                                  cl::NotHidden, cl::aliasopt(ClBasenames));

// -demangle, -C, -no-demangle
static cl::opt<bool>
ClDemangle("demangle", cl::init(true), cl::desc("Demangle function names"));
static cl::alias
ClDemangleShort("C", cl::desc("Alias for -demangle"),
                cl::NotHidden, cl::aliasopt(ClDemangle), cl::Grouping);
static cl::opt<bool>
ClNoDemangle("no-demangle", cl::init(false),
             cl::desc("Don't demangle function names"));

static cl::opt<std::string> ClDefaultArch("default-arch", cl::init(""),
                                          cl::desc("Default architecture "
                                                   "(for multi-arch objects)"));

// -obj, -exe, -e
static cl::opt<std::string>
ClBinaryName("obj", cl::init(""),
             cl::desc("Path to object file to be symbolized (if not provided, "
                      "object file should be specified for each input line)"));
static cl::alias
ClBinaryNameAliasExe("exe", cl::desc("Alias for -obj"),
                     cl::NotHidden, cl::aliasopt(ClBinaryName));
static cl::alias ClBinaryNameAliasE("e", cl::desc("Alias for -obj"),
                                    cl::NotHidden, cl::Grouping, cl::Prefix,
                                    cl::aliasopt(ClBinaryName));

static cl::opt<std::string>
    ClDwpName("dwp", cl::init(""),
              cl::desc("Path to DWP file to be use for any split CUs"));

static cl::list<std::string>
ClDsymHint("dsym-hint", cl::ZeroOrMore,
           cl::desc("Path to .dSYM bundles to search for debug info for the "
                    "object files"));

// -print-address, -addresses, -a
static cl::opt<bool>
ClPrintAddress("print-address", cl::init(false),
               cl::desc("Show address before line information"));
static cl::alias
ClPrintAddressAliasAddresses("addresses", cl::desc("Alias for -print-address"),
                             cl::NotHidden, cl::aliasopt(ClPrintAddress));
static cl::alias
ClPrintAddressAliasA("a", cl::desc("Alias for -print-address"),
                     cl::NotHidden, cl::aliasopt(ClPrintAddress), cl::Grouping);

// -pretty-print, -p
static cl::opt<bool>
    ClPrettyPrint("pretty-print", cl::init(false),
                  cl::desc("Make the output more human friendly"));
static cl::alias ClPrettyPrintShort("p", cl::desc("Alias for -pretty-print"),
                                    cl::NotHidden,
                                    cl::aliasopt(ClPrettyPrint), cl::Grouping);

static cl::opt<int> ClPrintSourceContextLines(
    "print-source-context-lines", cl::init(0),
    cl::desc("Print N number of source file context"));

static cl::opt<bool> ClVerbose("verbose", cl::init(false),
                               cl::desc("Print verbose line info"));

// -adjust-vma
static cl::opt<uint64_t>
    ClAdjustVMA("adjust-vma", cl::init(0), cl::value_desc("offset"),
                cl::desc("Add specified offset to object file addresses"));

static cl::list<std::string> ClInputAddresses(cl::Positional,
                                              cl::desc("<input addresses>..."),
                                              cl::ZeroOrMore);

static cl::opt<std::string>
    ClFallbackDebugPath("fallback-debug-path", cl::init(""),
                        cl::desc("Fallback path for debug binaries."));

static cl::list<std::string>
    ClDebugFileDirectory("debug-file-directory", cl::ZeroOrMore,
                         cl::value_desc("dir"),
                         cl::desc("Path to directory where to look for debug "
                                  "files."));

static cl::opt<DIPrinter::OutputStyle>
    ClOutputStyle("output-style", cl::init(DIPrinter::OutputStyle::LLVM),
                  cl::desc("Specify print style"),
                  cl::values(clEnumValN(DIPrinter::OutputStyle::LLVM, "LLVM",
                                        "LLVM default style"),
                             clEnumValN(DIPrinter::OutputStyle::GNU, "GNU",
                                        "GNU addr2line style")));

static cl::extrahelp
    HelpResponse("\nPass @FILE as argument to read options from FILE.\n");

template<typename T>
static bool error(Expected<T> &ResOrErr) {
  if (ResOrErr)
    return false;
  logAllUnhandledErrors(ResOrErr.takeError(), errs(),
                        "LLVMSymbolizer: error reading file: ");
  return true;
}

enum class Command {
  Code,
  Data,
  Frame,
};

static bool parseCommand(StringRef InputString, Command &Cmd,
                         std::string &ModuleName, uint64_t &ModuleOffset) {
  const char kDelimiters[] = " \n\r";
  ModuleName = "";
  if (InputString.consume_front("CODE ")) {
    Cmd = Command::Code;
  } else if (InputString.consume_front("DATA ")) {
    Cmd = Command::Data;
  } else if (InputString.consume_front("FRAME ")) {
    Cmd = Command::Frame;
  } else {
    // If no cmd, assume it's CODE.
    Cmd = Command::Code;
  }
  const char *pos = InputString.data();
  // Skip delimiters and parse input filename (if needed).
  if (ClBinaryName.empty()) {
    pos += strspn(pos, kDelimiters);
    if (*pos == '"' || *pos == '\'') {
      char quote = *pos;
      pos++;
      const char *end = strchr(pos, quote);
      if (!end)
        return false;
      ModuleName = std::string(pos, end - pos);
      pos = end + 1;
    } else {
      int name_length = strcspn(pos, kDelimiters);
      ModuleName = std::string(pos, name_length);
      pos += name_length;
    }
  } else {
    ModuleName = ClBinaryName;
  }
  // Skip delimiters and parse module offset.
  pos += strspn(pos, kDelimiters);
  int offset_length = strcspn(pos, kDelimiters);
  return !StringRef(pos, offset_length).getAsInteger(0, ModuleOffset);
}

static void symbolizeInput(StringRef InputString, LLVMSymbolizer &Symbolizer,
                           DIPrinter &Printer) {
  Command Cmd;
  std::string ModuleName;
  uint64_t Offset = 0;
  if (!parseCommand(StringRef(InputString), Cmd, ModuleName, Offset)) {
    outs() << InputString << "\n";
    return;
  }

  if (ClPrintAddress) {
    outs() << "0x";
    outs().write_hex(Offset);
    StringRef Delimiter = ClPrettyPrint ? ": " : "\n";
    outs() << Delimiter;
  }
  Offset -= ClAdjustVMA;
  if (Cmd == Command::Data) {
    auto ResOrErr = Symbolizer.symbolizeData(
        ModuleName, {Offset, object::SectionedAddress::UndefSection});
    Printer << (error(ResOrErr) ? DIGlobal() : ResOrErr.get());
  } else if (Cmd == Command::Frame) {
    auto ResOrErr = Symbolizer.symbolizeFrame(
        ModuleName, {Offset, object::SectionedAddress::UndefSection});
    if (!error(ResOrErr)) {
      for (DILocal Local : *ResOrErr)
        Printer << Local;
      if (ResOrErr->empty())
        outs() << "??\n";
    }
  } else if (ClPrintInlining) {
    auto ResOrErr = Symbolizer.symbolizeInlinedCode(
        ModuleName, {Offset, object::SectionedAddress::UndefSection});
    Printer << (error(ResOrErr) ? DIInliningInfo() : ResOrErr.get());
  } else if (ClOutputStyle == DIPrinter::OutputStyle::GNU) {
    // With ClPrintFunctions == FunctionNameKind::LinkageName (default)
    // and ClUseSymbolTable == true (also default), Symbolizer.symbolizeCode()
    // may override the name of an inlined function with the name of the topmost
    // caller function in the inlining chain. This contradicts the existing
    // behavior of addr2line. Symbolizer.symbolizeInlinedCode() overrides only
    // the topmost function, which suits our needs better.
    auto ResOrErr = Symbolizer.symbolizeInlinedCode(
        ModuleName, {Offset, object::SectionedAddress::UndefSection});
    Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get().getFrame(0));
  } else {
    auto ResOrErr = Symbolizer.symbolizeCode(
        ModuleName, {Offset, object::SectionedAddress::UndefSection});
    Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get());
  }
  if (ClOutputStyle == DIPrinter::OutputStyle::LLVM)
    outs() << "\n";
}

int main(int argc, char **argv) {
  InitLLVM X(argc, argv);

  bool IsAddr2Line = sys::path::stem(argv[0]).contains("addr2line");

  if (IsAddr2Line) {
    ClDemangle.setInitialValue(false);
    ClPrintFunctions.setInitialValue(FunctionNameKind::None);
    ClPrintInlining.setInitialValue(false);
    ClUntagAddresses.setInitialValue(false);
    ClOutputStyle.setInitialValue(DIPrinter::OutputStyle::GNU);
  }

  llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);
  cl::ParseCommandLineOptions(
      argc, argv, IsAddr2Line ? "llvm-addr2line\n" : "llvm-symbolizer\n",
      /*Errs=*/nullptr,
      IsAddr2Line ? "LLVM_ADDR2LINE_OPTS" : "LLVM_SYMBOLIZER_OPTS");

  // If both --demangle and --no-demangle are specified then pick the last one.
  if (ClNoDemangle.getPosition() > ClDemangle.getPosition())
    ClDemangle = !ClNoDemangle;

  LLVMSymbolizer::Options Opts;
  Opts.PrintFunctions = ClPrintFunctions;
  Opts.UseSymbolTable = ClUseSymbolTable;
  Opts.Demangle = ClDemangle;
  Opts.RelativeAddresses = ClUseRelativeAddress;
  Opts.UntagAddresses = ClUntagAddresses;
  Opts.DefaultArch = ClDefaultArch;
  Opts.FallbackDebugPath = ClFallbackDebugPath;
  Opts.DWPName = ClDwpName;
  Opts.DebugFileDirectory = ClDebugFileDirectory;

  for (const auto &hint : ClDsymHint) {
    if (sys::path::extension(hint) == ".dSYM") {
      Opts.DsymHints.push_back(hint);
    } else {
      errs() << "Warning: invalid dSYM hint: \"" << hint <<
                "\" (must have the '.dSYM' extension).\n";
    }
  }
  LLVMSymbolizer Symbolizer(Opts);

  DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None,
                    ClPrettyPrint, ClPrintSourceContextLines, ClVerbose,
                    ClBasenames, ClOutputStyle);

  if (ClInputAddresses.empty()) {
    const int kMaxInputStringLength = 1024;
    char InputString[kMaxInputStringLength];

    while (fgets(InputString, sizeof(InputString), stdin)) {
      // Strip newline characters.
      std::string StrippedInputString(InputString);
      StrippedInputString.erase(
          std::remove_if(StrippedInputString.begin(), StrippedInputString.end(),
                         [](char c) { return c == '\r' || c == '\n'; }),
          StrippedInputString.end());
      symbolizeInput(StrippedInputString, Symbolizer, Printer);
      outs().flush();
    }
  } else {
    for (StringRef Address : ClInputAddresses)
      symbolizeInput(Address, Symbolizer, Printer);
  }

  return 0;
}
