//===- xray-extract.cpp: XRay Instrumentation Map Extraction --------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Implementation of the xray-extract.h interface.
//
// FIXME: Support other XRay-instrumented binary formats other than ELF.
//
//===----------------------------------------------------------------------===//


#include "func-id-helper.h"
#include "xray-registry.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/XRay/InstrumentationMap.h"

using namespace llvm;
using namespace llvm::xray;
using namespace llvm::yaml;

// llvm-xray extract
// ----------------------------------------------------------------------------
static cl::SubCommand Extract("extract", "Extract instrumentation maps");
static cl::opt<std::string> ExtractInput(cl::Positional,
                                         cl::desc("<input file>"), cl::Required,
                                         cl::sub(Extract));
static cl::opt<std::string>
    ExtractOutput("output", cl::value_desc("output file"), cl::init("-"),
                  cl::desc("output file; use '-' for stdout"),
                  cl::sub(Extract));
static cl::alias ExtractOutput2("o", cl::aliasopt(ExtractOutput),
                                cl::desc("Alias for -output"));
static cl::opt<bool> ExtractSymbolize("symbolize", cl::value_desc("symbolize"),
                                      cl::init(false),
                                      cl::desc("symbolize functions"),
                                      cl::sub(Extract));
static cl::alias ExtractSymbolize2("s", cl::aliasopt(ExtractSymbolize),
                                   cl::desc("alias for -symbolize"));
static cl::opt<bool> ExtractNoDemangle("no-demangle",
                                       cl::value_desc("no-demangle"),
                                       cl::init(false),
                                       cl::desc("don't demangle symbols"),
                                       cl::sub(Extract));

namespace {

void exportAsYAML(const InstrumentationMap &Map, raw_ostream &OS,
                  FuncIdConversionHelper &FH) {
  // First we translate the sleds into the YAMLXRaySledEntry objects in a deque.
  std::vector<YAMLXRaySledEntry> YAMLSleds;
  auto Sleds = Map.sleds();
  YAMLSleds.reserve(std::distance(Sleds.begin(), Sleds.end()));
  for (const auto &Sled : Sleds) {
    auto FuncId = Map.getFunctionId(Sled.Function);
    if (!FuncId)
      return;
    YAMLSleds.push_back(
        {*FuncId, Sled.Address, Sled.Function, Sled.Kind, Sled.AlwaysInstrument,
         ExtractSymbolize ? FH.SymbolOrNumber(*FuncId) : "", Sled.Version});
  }
  Output Out(OS, nullptr, 0);
  Out << YAMLSleds;
}

} // namespace

static CommandRegistration Unused(&Extract, []() -> Error {
  auto InstrumentationMapOrError = loadInstrumentationMap(ExtractInput);
  if (!InstrumentationMapOrError)
    return joinErrors(make_error<StringError>(
                          Twine("Cannot extract instrumentation map from '") +
                              ExtractInput + "'.",
                          std::make_error_code(std::errc::invalid_argument)),
                      InstrumentationMapOrError.takeError());

  std::error_code EC;
  raw_fd_ostream OS(ExtractOutput, EC, sys::fs::OpenFlags::OF_TextWithCRLF);
  if (EC)
    return make_error<StringError>(
        Twine("Cannot open file '") + ExtractOutput + "' for writing.", EC);
  const auto &FunctionAddresses =
      InstrumentationMapOrError->getFunctionAddresses();
  symbolize::LLVMSymbolizer::Options opts;
  if (ExtractNoDemangle)
    opts.Demangle = false;
  symbolize::LLVMSymbolizer Symbolizer(opts);
  llvm::xray::FuncIdConversionHelper FuncIdHelper(ExtractInput, Symbolizer,
                                                  FunctionAddresses);
  exportAsYAML(*InstrumentationMapOrError, OS, FuncIdHelper);
  return Error::success();
});
