// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/performance/insntrace/control.h"

#include <fcntl.h>
#include <fuchsia/hardware/cpu/insntrace/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zircon-internal/device/cpu-trace/intel-pt.h>
#include <lib/zircon-internal/ktrace.h>
#include <lib/zx/handle.h>
#include <lib/zx/vmo.h>
#include <link.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <zircon/syscalls.h>

#include <cinttypes>
#include <iostream>

#include <fbl/unique_fd.h>

#include "src/lib/debugger_utils/util.h"
#include "src/lib/debugger_utils/x86_cpuid.h"
#include "src/lib/debugger_utils/x86_pt.h"
#include "src/lib/fxl/strings/string_printf.h"
#include "src/performance/insntrace/config.h"
#include "src/performance/insntrace/ktrace_controller.h"
#include "src/performance/insntrace/utils.h"

namespace insntrace {

using Allocation = ::fuchsia::hardware::cpu::insntrace::Allocation;
using BufferConfig = ::fuchsia::hardware::cpu::insntrace::BufferConfig;
using BufferState = ::fuchsia::hardware::cpu::insntrace::BufferState;
using ControllerSyncPtr = ::fuchsia::hardware::cpu::insntrace::ControllerSyncPtr;

// This isn't emitted by the fidl compiler.
using BufferDescriptor = uint32_t;

static constexpr char ipt_device_path[] = "/dev/sys/cpu-trace/insntrace";

static constexpr char buffer_output_path_suffix[] = "pt";
static constexpr char ktrace_output_path_suffix[] = "ktrace";
static constexpr char cpuid_output_path_suffix[] = "cpuid";
static constexpr char pt_list_output_path_suffix[] = "ptlist";

static constexpr uint32_t kKtraceGroupMask = KTRACE_GRP_ARCH | KTRACE_GRP_TASKS;

// Wrapper that ensures device is closed on the server side.
// insntrace only allows a single client at a time, so without it's possible for the device to
// observe a future open call before observing the close call from this connection.
class ControllerClient {
 public:
  ControllerClient(ControllerSyncPtr client) : client_(std::move(client)) {}

  ~ControllerClient() {
    int fd;
    zx_status_t status = fdio_fd_create(client_.Unbind().TakeChannel().release(), &fd);
    if (status == ZX_OK) {
      close(fd);
    }
  }

  ControllerSyncPtr& operator->() { return client_; }
  const ControllerSyncPtr& operator*() const { return client_; }

  operator bool() { return client_ ? true : false; }

 private:
  ControllerSyncPtr client_;
};

static ControllerClient OpenDevice() {
  ControllerSyncPtr controller_ptr;
  zx_status_t status =
      fdio_service_connect(ipt_device_path, controller_ptr.NewRequest().TakeChannel().release());
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Error connecting to " << ipt_device_path << ": " << status;
    return ControllerSyncPtr();
  }
  return controller_ptr;
}

bool AllocTrace(const IptConfig& config) {
  FX_LOGS(INFO) << "AllocTrace called";

  ControllerClient ipt{OpenDevice()};
  if (!ipt) {
    return false;
  }

  Allocation allocation;
  // TODO(61706): memset is done as the padding is set to 0xAA in release builds and encoding of the
  // FIDL request fails as the non-zero padding is also copied to the FIDL message.
  // Remove this once the bug is fixed.
  memset(&allocation, 0x0, sizeof(Allocation));
  allocation.mode = config.mode;
  allocation.num_traces =
      static_cast<uint16_t>(config.mode == Mode::CPU ? config.num_cpus : config.max_threads);
  FX_VLOGS(2) << fxl::StringPrintf("mode=%u, num_traces=0x%x",
                                   static_cast<unsigned>(allocation.mode), allocation.num_traces);

  ::fuchsia::hardware::cpu::insntrace::Controller_Initialize_Result result;
  zx_status_t status = ipt->Initialize(allocation, &result);
  if (status != ZX_OK || result.is_err()) {
    LogFidlFailure("Initialize", status, result.err());
    return false;
  }

  return true;
}

static void InitIptBufferConfig(BufferConfig* ipt_config, const IptConfig& config) {
  memset(ipt_config, 0, sizeof(*ipt_config));
  ipt_config->num_chunks = static_cast<uint32_t>(config.num_chunks);
  ipt_config->chunk_order = static_cast<uint32_t>(config.chunk_order);
  ipt_config->is_circular = config.is_circular;
  ipt_config->ctl = config.CtlMsr();
  ipt_config->address_space_match = config.cr3_match;
  ipt_config->address_range_0.start = config.AddrBegin(0);
  ipt_config->address_range_0.end = config.AddrEnd(0);
  ipt_config->address_range_1.start = config.AddrBegin(1);
  ipt_config->address_range_1.end = config.AddrEnd(1);
}

bool InitTrace(const IptConfig& config) {
  FX_LOGS(INFO) << "InitTrace called";
  FX_DCHECK(config.mode == Mode::CPU);

  ControllerClient ipt{OpenDevice()};
  if (!ipt) {
    return false;
  }

  for (uint32_t cpu = 0; cpu < config.num_cpus; ++cpu) {
    BufferConfig ipt_config;
    InitIptBufferConfig(&ipt_config, config);

    ::fuchsia::hardware::cpu::insntrace::Controller_AllocateBuffer_Result result;
    zx_status_t status = ipt->AllocateBuffer(ipt_config, &result);
    if (status != ZX_OK || result.is_err()) {
      LogFidlFailure("AllocateBuffer", status, result.err());
      return false;
    }
    // Buffers are automagically assigned to cpus, descriptor == cpu#,
    // so we can just ignore descriptor here.
  }

  return true;
}

// This must be called before a process is started so we emit a ktrace
// process start record for it.

bool InitProcessTrace(const IptConfig& config) {
  FX_LOGS(INFO) << "InitProcessTrace called";

  fuchsia::tracing::kernel::ControllerSyncPtr ktrace;
  if (OpenKtraceControllerChannel(&ktrace) != ZX_OK) {
    return false;
  }

  // If tracing cpus we may want all the records for processes that were
  // started during boot, so don't reset ktrace here. If tracing threads it
  // doesn't much matter other than hopefully the necessary records don't get
  // over run, which is handled below by only enabling the collection groups
  // we need. So for now leave existing records alone.
  // A better solution would be to collect the data we need at the time we
  // need it.
#if 0  // TODO(dje)
  if (config.mode == Mode::THREAD) {
    RequestKtraceStop(ktrace);
    RequestKtraceRewind(ktrace);
  }
#endif

  // We definitely need ktrace turned on in order to get cr3->pid mappings,
  // which we need to map trace cr3 values to ld.so mappings, which we need in
  // order to be able to find the ELFs, which are required by the decoder.
  // So this isn't a nice-to-have, we need it. It's possible ktrace is
  // currently off, so ensure it's turned on.
  // For now just include arch info in the ktrace - we need it, and we don't
  // want to risk the ktrace buffer filling without it.
  // Also include task info to get process exit records - we need to know when
  // a cr3 value becomes invalid. Hopefully this won't cause the buffer to
  // overrun. It it does we could consider having special ktrace records just
  // for this, but that's a last resort kind of thing.
  if (RequestKtraceStart(ktrace, kKtraceGroupMask)) {
    return true;
  }

  // TODO(dje): Resume original ktracing? Need ability to get old value.
  RequestKtraceStop(ktrace);
  return false;
}

bool StartTrace(const IptConfig& config) {
  FX_LOGS(INFO) << "StartTrace called";
  FX_DCHECK(config.mode == Mode::CPU);

  ControllerClient ipt{OpenDevice()};
  if (!ipt) {
    return false;
  }

  zx_status_t status = ipt->Start();
  if (status != ZX_OK) {
    LogFidlFailure("Start", status);
    return false;
  }

  return true;
}

void StopTrace(const IptConfig& config) {
  FX_LOGS(INFO) << "StopTrace called";
  FX_DCHECK(config.mode == Mode::CPU);

  ControllerClient ipt{OpenDevice()};
  if (!ipt) {
    return;
  }

  [[maybe_unused]] zx_status_t status = ipt->Stop();
  FX_DCHECK(status == ZX_OK);
}

void StopSidebandDataCollection(const IptConfig& config) {
  FX_LOGS(INFO) << "StopSidebandDataCollection called";

  fuchsia::tracing::kernel::ControllerSyncPtr ktrace;
  if (OpenKtraceControllerChannel(&ktrace) != ZX_OK) {
    return;
  }

  // Avoid having the records we need overrun by the time we collect them by
  // stopping ktrace here. It will get turned back on by "reset".
  RequestKtraceStop(ktrace);
}

static std::string GetCpuPtFileName(const std::string& output_path_prefix, uint64_t id) {
  const char* name_prefix = "cpu";
  return fxl::StringPrintf("%s.%s%" PRIu64 ".%s", output_path_prefix.c_str(), name_prefix, id,
                           buffer_output_path_suffix);
}

static std::string GetThreadPtFileName(const std::string& output_path_prefix, uint64_t id) {
  const char* name_prefix = "thr";
  return fxl::StringPrintf("%s.%s%" PRIu64 ".%s", output_path_prefix.c_str(), name_prefix, id,
                           buffer_output_path_suffix);
}

// Write the contents of buffer |descriptor| to a file.
// The file's name is $output_path_prefix.$name_prefix$id.pt.

static zx_status_t WriteBufferData(const IptConfig& config, const ControllerSyncPtr& ipt,
                                   uint32_t descriptor, uint64_t id) {
  std::string output_path;
  if (config.mode == Mode::CPU)
    output_path = GetCpuPtFileName(config.output_path_prefix, id);
  else
    output_path = GetThreadPtFileName(config.output_path_prefix, id);
  const char* c_path = output_path.c_str();

  // Refetch the buffer config as we can be invoked in a separate process,
  // after tracing has started, and shouldn't rely on what the user thinks
  // the config is.
  std::unique_ptr<BufferConfig> buffer_config;
  zx_status_t status = ipt->GetBufferConfig(descriptor, &buffer_config);
  if (status != ZX_OK) {
    LogFidlFailure("GetBufferConfig", status);
    return status;
  }
  if (!buffer_config) {
    FX_LOGS(ERROR) << "Failed getting buffer config";
    return ZX_ERR_INTERNAL;
  }

  std::unique_ptr<BufferState> buffer_state;
  status = ipt->GetBufferState(descriptor, &buffer_state);
  if (status != ZX_OK) {
    LogFidlFailure("GetBufferState", status);
    return status;
  }
  if (!buffer_state) {
    FX_LOGS(ERROR) << "Failed getting buffer state";
    return ZX_ERR_INTERNAL;
  }

  fbl::unique_fd fd(open(c_path, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR));
  if (!fd.is_valid()) {
    FX_LOGS(ERROR) << fxl::StringPrintf("Failed writing file: %s", c_path) << ", "
                   << debugger_utils::ErrnoString(errno);
    return ZX_ERR_BAD_PATH;
  }

  // TODO(dje): Fetch from vmo?
  size_t chunk_size = (1 << buffer_config->chunk_order) * zx_system_get_page_size();
  uint32_t num_chunks = buffer_config->num_chunks;

  // If using a circular buffer there's (currently) no way to know if
  // tracing wrapped, so for now we just punt and always dump the entire
  // buffer. It's highly likely it wrapped anyway.
  size_t bytes_left;
  if (buffer_config->is_circular)
    bytes_left = num_chunks * chunk_size;
  else
    bytes_left = buffer_state->capture_end;

  FX_LOGS(INFO) << fxl::StringPrintf("Writing %zu bytes to %s", bytes_left, c_path);

  char buf[4096];

  for (uint32_t i = 0; i < num_chunks && bytes_left > 0; ++i) {
    zx::vmo vmo;
    status = ipt->GetChunkHandle(descriptor, i, &vmo);
    if (status != ZX_OK) {
      LogFidlFailure("GetChunkHandle", status);
      FX_LOGS(ERROR) << "Buffer " << descriptor << ", chunk " << i;
      goto Fail;
    }

    size_t buffer_remaining = chunk_size;
    size_t offset = 0;
    while (buffer_remaining && bytes_left) {
      size_t to_write = sizeof(buf);
      if (to_write > buffer_remaining)
        to_write = buffer_remaining;
      if (to_write > bytes_left)
        to_write = bytes_left;
      // TODO(dje): Mapping into process and reading directly from that
      // left for another day.
      status = vmo.read(buf, offset, to_write);
      if (status != ZX_OK) {
        FX_LOGS(ERROR) << fxl::StringPrintf("zx_vmo_read: buffer %u, buffer %u, offset %zu: ",
                                            descriptor, i, offset)
                       << debugger_utils::ZxErrorString(status);
        goto Fail;
      }
      if (write(fd.get(), buf, to_write) != (ssize_t)to_write) {
        FX_LOGS(ERROR) << fxl::StringPrintf("Short write, file: %s\n", c_path);
        status = ZX_ERR_IO;
        goto Fail;
      }
      offset += to_write;
      buffer_remaining -= to_write;
      bytes_left -= to_write;
    }
  }

  assert(bytes_left == 0);
  status = ZX_OK;
  // fallthrough

Fail:
  // We don't delete the file on failure on purpose, it is kept for
  // debugging purposes.
  return status;
}

// Write all output files.
// This assumes tracing has already been stopped.

void DumpTrace(const IptConfig& config) {
  FX_LOGS(INFO) << "DumpTrace called";
  FX_DCHECK(config.mode == Mode::CPU);

  ControllerClient ipt{OpenDevice()};
  if (!ipt) {
    return;
  }

  for (uint32_t cpu = 0; cpu < config.num_cpus; ++cpu) {
    // Buffer descriptors for cpus is the cpu number.
    auto status = WriteBufferData(config, *ipt, cpu, cpu);
    if (status != ZX_OK) {
      FX_LOGS(ERROR) << fxl::StringPrintf("Dump perf of cpu %u: ", cpu)
                     << debugger_utils::ZxErrorString(status);
      // Keep trying to dump other cpu's data.
    }
  }
}

void DumpSidebandData(const IptConfig& config) {
  FX_LOGS(INFO) << "DumpSidebandData called";

  DumpKtraceBuffer(config.output_path_prefix.c_str(), ktrace_output_path_suffix);

  // TODO(dje): UniqueFILE?
  {
    std::string cpuid_output_path =
        fxl::StringPrintf("%s.%s", config.output_path_prefix.c_str(), cpuid_output_path_suffix);
    const char* cpuid_c_path = cpuid_output_path.c_str();

    FILE* f = fopen(cpuid_c_path, "w");
    if (f != nullptr) {
      debugger_utils::x86_feature_debug(f);
      // Also put the mtc_freq value in the cpuid file, it's as good a place
      // for it as any. See intel-pt.h:pt_config.
      // Alternatively this could be added to the ktrace record.
      // TODO(dje): Put constants in zircon/device/intel-pt.h.
      unsigned mtc_freq = config.mtc_freq;
      fprintf(f, "mtc_freq: %u\n", mtc_freq);
      // TODO(dje): verify writes succeed
      fclose(f);
    } else {
      FX_LOGS(ERROR) << "unable to write PT config to " << cpuid_c_path;
    }
  }

  // TODO(dje): UniqueFILE?
  // TODO(dje): Handle Mode::THREAD
  if (config.mode == Mode::CPU) {
    std::string pt_list_output_path =
        fxl::StringPrintf("%s.%s", config.output_path_prefix.c_str(), pt_list_output_path_suffix);
    const char* pt_list_c_path = pt_list_output_path.c_str();

    FILE* f = fopen(pt_list_c_path, "w");
    if (f != nullptr) {
      for (uint32_t cpu = 0; cpu < config.num_cpus; ++cpu) {
        std::string pt_file = GetCpuPtFileName(config.output_path_prefix, cpu);
        fprintf(f, "%u %s\n", cpu, pt_file.c_str());
      }
      // TODO(dje): verify writes succeed
      fclose(f);
    } else {
      FX_LOGS(ERROR) << "unable to write PT list to " << pt_list_c_path;
    }
  }
}

void ResetTrace(const IptConfig& config) {
  FX_LOGS(INFO) << "ResetTrace called";
  FX_DCHECK(config.mode == Mode::CPU);

  // TODO(dje): Nothing to do currently. There use to be. So keep this
  // function around for a bit.
}

// Free all resources associated with the true.
// This means restoring ktrace to its original state.
// This assumes tracing has already been stopped.

void FreeTrace(const IptConfig& config) {
  FX_LOGS(INFO) << "FreeTrace called";

  ControllerClient ipt{OpenDevice()};
  if (!ipt) {
    return;
  }

  ::fuchsia::hardware::cpu::insntrace::Controller_Terminate_Result result;
  zx_status_t status = ipt->Terminate(&result);
  if (status != ZX_OK || result.is_err()) {
    LogFidlFailure("Terminate", status, result.err());
  }

  // TODO(dje): Resume original ktracing? Need ability to get old value.
  // For now set the values to what we need: A later run might still need
  // the boot time records.

  fuchsia::tracing::kernel::ControllerSyncPtr ktrace;
  if (OpenKtraceControllerChannel(&ktrace) != ZX_OK) {
    return;
  }

  RequestKtraceStop(ktrace);
#if 0  // TODO(dje): See rewind comments in InitProcessTrace.
  RequestKtraceRewind(ktrace);
#endif
  RequestKtraceStart(ktrace, kKtraceGroupMask);
}

}  // namespace insntrace
