// Copyright 2017 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 <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>

#include <pretty/sizes.h>
#include <task-utils/get.h>

#include "vmo-utils.h"

static constexpr size_t kRightsStrLen = sizeof("rwxmdt");

static const char* handle_rights_to_string(uint32_t rights, char str[kRightsStrLen]) {
  char* c = str;
  *c++ = (rights & ZX_RIGHT_READ) ? 'r' : '-';
  *c++ = (rights & ZX_RIGHT_WRITE) ? 'w' : '-';
  *c++ = (rights & ZX_RIGHT_EXECUTE) ? 'x' : '-';
  *c++ = (rights & ZX_RIGHT_MAP) ? 'm' : '-';
  *c++ = (rights & ZX_RIGHT_DUPLICATE) ? 'd' : '-';
  *c++ = (rights & ZX_RIGHT_TRANSFER) ? 't' : '-';
  *c = '\0';
  return str;
}

static void print_vmo(const zx_info_vmo_t* vmo) {
  char rights_str[kRightsStrLen];
  if (vmo->flags & ZX_INFO_VMO_VIA_HANDLE) {
    handle_rights_to_string(vmo->handle_rights, rights_str);
  } else {
    rights_str[0] = '-';
    rights_str[1] = '\0';
  }

  char size_str[MAX_FORMAT_SIZE_LEN];
  format_size(size_str, sizeof(size_str), vmo->size_bytes);

  char alloc_str[MAX_FORMAT_SIZE_LEN];
  switch (ZX_INFO_VMO_TYPE(vmo->flags)) {
    case ZX_INFO_VMO_TYPE_PAGED:
      format_size(alloc_str, sizeof(alloc_str), vmo->committed_bytes);
      break;
    case ZX_INFO_VMO_TYPE_PHYSICAL:
      strlcpy(alloc_str, "phys", sizeof(alloc_str));
      break;
    default:
      // Unexpected: all VMOs should be one of the above types.
      snprintf(alloc_str, sizeof(alloc_str), "?0x%" PRIx32 "?", vmo->flags);
      break;
  }

  char parent_str[21];
  if (vmo->flags & ZX_INFO_VMO_IS_COW_CLONE) {
    snprintf(parent_str, sizeof(parent_str), "%" PRIu64, vmo->parent_koid);
  } else {
    parent_str[0] = '-';
    parent_str[1] = '\0';
  }

  char name[ZX_MAX_NAME_LEN];
  strlcpy(name, vmo->name, sizeof(name));
  if (name[0] == '\0') {
    name[0] = '-';
    name[1] = '\0';
  }

  printf(
      "%6s "  // rights
      "%5" PRIu64
      " "      // koid
      "%6s "   // parent koid
      "%5zu "  // number of children
      "%4zu "  // map count
      "%4zu "  // share count
      "%7s "   // size in bytes
      "%7s "   // allocated bytes
      "%s\n",  // name
      rights_str, vmo->koid, parent_str, vmo->num_children, vmo->num_mappings, vmo->share_count,
      size_str, alloc_str, name);
}

static void print_header() { printf("rights  koid parent #chld #map #shr    size   alloc name\n"); }

// Pretty-prints the contents of |vmos| to stdout.
void print_vmos(const zx_info_vmo_t* vmos, size_t count, size_t avail) {
  print_header();
  for (size_t i = 0; i < count; i++) {
    print_vmo(vmos + i);
  }
  if (avail > count) {
    printf("[%zd entries truncated]\n", avail - count);
  }
  print_header();
}

void try_help(char** argv) {
  const char* c = argv[1];
  while (*c == '-') {
    c++;
  }
  if (strcmp(c, "help") != 0) {
    return;
  }

  printf("Usage: %s <process-koid>\n", argv[0]);
  printf("\n");
  printf("Dumps a process's VMOs to stdout.\n");
  printf("\n");
  printf("The process either maps or has a handle to every VMO in this list (or both).\n");
  printf("The same VMO may appear multiple times: the process could map the same VMO\n");
  printf("twice, or have two handles to it, or both map it and have a handle to it.\n");
  // TODO(dbort): Consider de-duping the entries.
  printf("\n");
  printf("Columns:\n");
  printf("  rights: If the process points to the VMO via a handle, this column\n");
  printf("      shows the rights that the handle has, zero or more of:\n");
  printf("          r: ZX_RIGHT_READ\n");
  printf("          w: ZX_RIGHT_WRITE\n");
  printf("          x: ZX_RIGHT_EXECUTE\n");
  printf("          m: ZX_RIGHT_MAP\n");
  printf("          d: ZX_RIGHT_DUPLICATE\n");
  printf("          t: ZX_RIGHT_TRANSFER\n");
  printf("      NOTE: Non-handle entries will have a single '-' in this column.\n");
  printf("  koid: The koid of the VMO, if it has one. Zero otherwise. A VMO without a\n");
  printf("      koid was created by the kernel, and has never had a userspace handle.\n");
  printf("  parent: The koid of the VMO's parent, if it's a clone.\n");
  printf("  #chld: The number of active clones (children) of the VMO.\n");
  printf("  #map: The number of times the VMO is currently mapped into VMARs.\n");
  printf("  #shr: The number of processes that map (share) the VMO.\n");
  printf("  size: The VMO's current size, in bytes.\n");
  printf("  alloc: The amount of physical memory allocated to the VMO, in bytes.\n");
  printf("      NOTE: If this column contains the value 'phys', it means that the\n");
  printf("      VMO points to a raw physical address range like a memory-mapped\n");
  printf("      device. 'phys' VMOs do not consume RAM.\n");
  printf("  name: The name of the VMO, or - if its name is empty.\n");
  exit(0);
}

__NO_RETURN void usage(const char* argv0) {
  fprintf(stderr, "Usage: %s <process-koid>|help\n", argv0);
  exit(1);
}

int main(int argc, char** argv) {
  if (argc != 2) {
    usage(argv[0]);
  }
  try_help(argv);
  char* end;
  zx_koid_t koid = strtoull(argv[1], &end, 0);
  if (argv[1][0] == '\0' || *end != '\0') {
    fprintf(stderr, "ERROR: \"%s\" is not a number\n", argv[1]);
    usage(argv[0]);
  }

  zx_handle_t process;
  zx_obj_type_t type;
  zx_status_t s = get_task_by_koid(koid, &type, &process);
  if (s == ZX_OK && type != ZX_OBJ_TYPE_PROCESS) {
    zx_handle_close(process);
    s = ZX_ERR_WRONG_TYPE;
  }
  if (s != ZX_OK) {
    fprintf(stderr, "ERROR: couldn't find process with koid %" PRIu64 ": %s (%d)\n", koid,
            zx_status_get_string(s), s);
    usage(argv[0]);
  }

  zx_info_vmo_t* vmos;
  size_t count;
  size_t avail;
  s = get_vmos(process, &vmos, &count, &avail);
  zx_handle_close(process);
  if (s != ZX_OK) {
    fprintf(stderr, "ERROR: couldn't get vmos for process with koid %" PRIu64 ": %s (%d)\n", koid,
            zx_status_get_string(s), s);
    return 1;
  }
  print_vmos(vmos, count, avail);
  free(vmos);
  return 0;
}
