// 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 <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zircon/compiler.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/types.h>

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

// Reads the zx_info_maps_t entries for the process.
// Caller is responsible for the |out_maps| pointer.
zx_status_t get_maps(zx_koid_t koid, zx_handle_t process, zx_info_maps_t** out_maps,
                     size_t* out_count, size_t* out_avail) {
  size_t count = 4096;  // Should be more than enough.
  zx_info_maps_t* maps = NULL;
  int pass = 3;
  while (true) {
    maps = (zx_info_maps_t*)realloc(maps, count * sizeof(zx_info_maps_t));

    size_t actual;
    size_t avail;
    zx_status_t s = zx_object_get_info(process, ZX_INFO_PROCESS_MAPS, maps,
                                       count * sizeof(zx_info_maps_t), &actual, &avail);
    if (s != ZX_OK) {
      fprintf(stderr, "ERROR: couldn't get maps for process with koid %" PRIu64 ": %s (%d)\n", koid,
              zx_status_get_string(s), s);
      free(maps);
      return s;
    }
    if (actual < avail && pass-- > 0) {
      count = (avail * 10) / 9;
      continue;
    }
    *out_maps = maps;
    *out_count = actual;
    *out_avail = avail;
    return ZX_OK;
  }
}

void print_ptr(zx_vaddr_t addr) {
  if (addr <= UINT32_MAX) {
    printf("________%08" PRIx32, (uint32_t)addr);
  } else {
    printf("%016" PRIx64, addr);
  }
}

void print_range(zx_vaddr_t addr, size_t size) {
  print_ptr(addr);
  printf("-");
  print_ptr(addr + size);
}

void print_mmu_flags(unsigned int mmu_flags) {
  if (mmu_flags & ZX_VM_PERM_READ) {
    printf("r");
  } else {
    printf("-");
  }
  if (mmu_flags & ZX_VM_PERM_WRITE) {
    printf("w");
  } else {
    printf("-");
  }
  if (mmu_flags & ZX_VM_PERM_EXECUTE) {
    printf("x");
  } else {
    printf("-");
  }
}

// Pretty-prints the contents of |maps| to stdout.
zx_status_t print_maps(zx_info_maps_t* maps, size_t count, size_t avail) {
  size_t max_depth = 2;
  for (size_t i = 0; i < count; i++) {
    zx_info_maps_t* e = maps + i;
    if (e->depth > max_depth) {
      max_depth = e->depth;
    }
  }

  char size_str[MAX_FORMAT_SIZE_LEN];
  for (size_t i = 0; i < count; i++) {
    zx_info_maps_t* e = maps + i;
    char tc = 0;
    switch (e->type) {
      case ZX_INFO_MAPS_TYPE_ASPACE:
        tc = 'A';
        break;
      case ZX_INFO_MAPS_TYPE_VMAR:
        tc = 'R';
        break;
      case ZX_INFO_MAPS_TYPE_MAPPING:
        tc = 'M';
        break;
      default:
        break;
    }
    if (tc == 0) {
      continue;
    }

    // Print the type character, indented to show its place in the tree.
    if (e->depth < 2) {
      // This is the aspace or root vmar.
      // They'll always exist and always be the parents of everything.
      printf("/%c%*s", tc, (int)(max_depth - 3), "");
    } else {
      printf("%*s%c%*s", (int)(e->depth - 2), "", tc, (int)(max_depth - e->depth), "");
    }

    printf(" ");
    print_range(e->base, e->size);

    int size_width;
    if (e->type == ZX_INFO_MAPS_TYPE_MAPPING) {
      printf(" ");
      print_mmu_flags(e->u.mapping.mmu_flags);
      size_width = 5;
    } else {
      size_width = 9;
    }

    format_size(size_str, sizeof(size_str), e->size);
    printf(" %*s:sz", size_width, size_str);
    if (e->type == ZX_INFO_MAPS_TYPE_MAPPING) {
      const zx_info_maps_mapping_t* u = &e->u.mapping;
      format_size(size_str, sizeof(size_str), u->committed_pages * zx_system_get_page_size());
      printf(" %4s:res", size_str);
      printf(" %5" PRIu64 ":vmo", u->vmo_koid);
    } else {
      printf("%19s", "");
    }

    printf(" '%s'\n", e->name);
  }
  if (avail > count) {
    printf("[%zd entries truncated]\n", avail - count);
  }
  return ZX_OK;
}

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 memory maps to stdout.\n");
  printf("\n");
  printf("First column:\n");
  printf("  \"/A\" -- Process address space\n");
  printf("  \"/R\" -- Root VMAR\n");
  printf("  \"R\"  -- VMAR (R for Region)\n");
  printf("  \"M\"  -- Mapping\n");
  printf("\n");
  printf("  Indentation indicates parent/child relationship.\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_maps_t* maps;
  size_t count;
  size_t avail;
  s = get_maps(koid, process, &maps, &count, &avail);
  zx_handle_close(process);
  if (s != ZX_OK) {
    return 1;
  }
  s = print_maps(maps, count, avail);
  free(maps);
  return s == ZX_OK ? 0 : 1;
}
