//===-- xray_utils.cpp ------------------------------------------*- C++ -*-===//
//
// 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 file is a part of XRay, a dynamic runtime instrumentation system.
//
//===----------------------------------------------------------------------===//
#include "xray_utils.h"

#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_common.h"
#include "xray_allocator.h"
#include "xray_defs.h"
#include "xray_flags.h"
#include <cstdio>
#include <errno.h>
#include <fcntl.h>
#include <iterator>
#include <new>
#include <stdlib.h>
#include <sys/types.h>
#include <tuple>
#include <unistd.h>
#include <utility>

#if SANITIZER_FUCHSIA
#include "sanitizer_common/sanitizer_symbolizer_fuchsia.h"

#include <inttypes.h>
#include <zircon/process.h>
#include <zircon/sanitizer.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#endif

namespace __xray {

#if SANITIZER_FUCHSIA
constexpr const char* ProfileSinkName = "llvm-xray";

LogWriter::~LogWriter() {
  _zx_handle_close(Vmo);
}

void LogWriter::WriteAll(const char *Begin, const char *End) XRAY_NEVER_INSTRUMENT {
  if (Begin == End)
    return;
  auto TotalBytes = std::distance(Begin, End);

  const size_t PageSize = flags()->xray_page_size_override > 0
                              ? flags()->xray_page_size_override
                              : GetPageSizeCached();
  if (RoundUpTo(Offset, PageSize) != RoundUpTo(Offset + TotalBytes, PageSize)) {
    // Resize the VMO to ensure there's sufficient space for the data.
    zx_status_t Status = _zx_vmo_set_size(Vmo, Offset + TotalBytes);
    if (Status != ZX_OK) {
      Report("Failed to resize VMO: %s\n", _zx_status_get_string(Status));
      return;
    }
  }

  // Write the data into VMO.
  zx_status_t Status = _zx_vmo_write(Vmo, Begin, Offset, TotalBytes);
  if (Status != ZX_OK) {
    Report("Failed to write: %s\n", _zx_status_get_string(Status));
    return;
  }
  Offset += TotalBytes;

  // Record the data size as a property of the VMO.
  _zx_object_set_property(Vmo, ZX_PROP_VMO_CONTENT_SIZE,
                          &Offset, sizeof(Offset));
}

void LogWriter::Flush() XRAY_NEVER_INSTRUMENT {
  // Nothing to do here since WriteAll writes directly into the VMO.
}

LogWriter *LogWriter::Open() XRAY_NEVER_INSTRUMENT {
  // Create VMO to hold the profile data.
  zx_handle_t Vmo;
  zx_status_t Status = _zx_vmo_create(0, ZX_VMO_RESIZABLE, &Vmo);
  if (Status != ZX_OK) {
    Report("XRay: cannot create VMO: %s\n", _zx_status_get_string(Status));
    return nullptr;
  }

  // Get the KOID of the current process to use in the VMO name.
  zx_info_handle_basic_t Info;
  Status = _zx_object_get_info(_zx_process_self(), ZX_INFO_HANDLE_BASIC, &Info,
                               sizeof(Info), NULL, NULL);
  if (Status != ZX_OK) {
    Report("XRay: cannot get basic info about current process handle: %s\n",
           _zx_status_get_string(Status));
    return nullptr;
  }

  // Give the VMO a name including our process KOID so it's easy to spot.
  char VmoName[ZX_MAX_NAME_LEN];
  internal_snprintf(VmoName, sizeof(VmoName), "%s.%zu", ProfileSinkName,
                    Info.koid);
  _zx_object_set_property(Vmo, ZX_PROP_NAME, VmoName, strlen(VmoName));

  // Duplicate the handle since __sanitizer_publish_data consumes it and
  // LogWriter needs to hold onto it.
  zx_handle_t Handle;
  Status =_zx_handle_duplicate(Vmo, ZX_RIGHT_SAME_RIGHTS, &Handle);
  if (Status != ZX_OK) {
    Report("XRay: cannot duplicate VMO handle: %s\n",
           _zx_status_get_string(Status));
    return nullptr;
  }

  // Publish the VMO that receives the logging. Note the VMO's contents can
  // grow and change after publication. The contents won't be read out until
  // after the process exits.
  __sanitizer_publish_data(ProfileSinkName, Handle);

  // Use the dumpfile symbolizer markup element to write the name of the VMO.
  Report("XRay: " FORMAT_DUMPFILE "\n", ProfileSinkName, VmoName);

  LogWriter *LW = reinterpret_cast<LogWriter *>(InternalAlloc(sizeof(LogWriter)));
  new (LW) LogWriter(Vmo);
  return LW;
}

void LogWriter::Close(LogWriter *LW) {
  LW->~LogWriter();
  InternalFree(LW);
}
#else // SANITIZER_FUCHSIA
LogWriter::~LogWriter() {
  internal_close(Fd);
}

void LogWriter::WriteAll(const char *Begin, const char *End) XRAY_NEVER_INSTRUMENT {
  if (Begin == End)
    return;
  auto TotalBytes = std::distance(Begin, End);
  while (auto Written = write(Fd, Begin, TotalBytes)) {
    if (Written < 0) {
      if (errno == EINTR)
        continue; // Try again.
      Report("Failed to write; errno = %d\n", errno);
      return;
    }
    TotalBytes -= Written;
    if (TotalBytes == 0)
      break;
    Begin += Written;
  }
}

void LogWriter::Flush() XRAY_NEVER_INSTRUMENT {
  fsync(Fd);
}

LogWriter *LogWriter::Open() XRAY_NEVER_INSTRUMENT {
  // Open a temporary file once for the log.
  char TmpFilename[256] = {};
  char TmpWildcardPattern[] = "XXXXXX";
  auto **Argv = GetArgv();
  const char *Progname = !Argv ? "(unknown)" : Argv[0];
  const char *LastSlash = internal_strrchr(Progname, '/');

  if (LastSlash != nullptr)
    Progname = LastSlash + 1;

  int NeededLength = internal_snprintf(
      TmpFilename, sizeof(TmpFilename), "%s%s.%s",
      flags()->xray_logfile_base, Progname, TmpWildcardPattern);
  if (NeededLength > int(sizeof(TmpFilename))) {
    Report("XRay log file name too long (%d): %s\n", NeededLength, TmpFilename);
    return nullptr;
  }
  int Fd = mkstemp(TmpFilename);
  if (Fd == -1) {
    Report("XRay: Failed opening temporary file '%s'; not logging events.\n",
           TmpFilename);
    return nullptr;
  }
  if (Verbosity())
    Report("XRay: Log file in '%s'\n", TmpFilename);

  LogWriter *LW = allocate<LogWriter>();
  new (LW) LogWriter(Fd);
  return LW;
}

void LogWriter::Close(LogWriter *LW) {
  LW->~LogWriter();
  deallocate(LW);
}
#endif // SANITIZER_FUCHSIA

} // namespace __xray
