// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include "object/diagnostics.h"

#include <inttypes.h>
#include <lib/console.h>
#include <lib/ktrace.h>
#include <stdio.h>
#include <string.h>
#include <zircon/syscalls/object.h>
#include <zircon/types.h>

#include <fbl/auto_lock.h>
#include <ktl/span.h>
#include <object/handle.h>
#include <object/job_dispatcher.h>
#include <object/process_dispatcher.h>
#include <object/vm_object_dispatcher.h>
#include <pretty/cpp/sizes.h>
#include <vm/fault.h>

using pretty::FormattedBytes;

// Machinery to walk over a job tree and run a callback on each process.
template <typename ProcessCallbackType>
class ProcessWalker final : public JobEnumerator {
 public:
  ProcessWalker(ProcessCallbackType cb) : cb_(cb) {}
  ProcessWalker(const ProcessWalker&) = delete;
  ProcessWalker(ProcessWalker&& other) : cb_(other.cb_) {}

 private:
  bool OnProcess(ProcessDispatcher* process) final {
    cb_(process);
    return true;
  }

  const ProcessCallbackType cb_;
};

template <typename ProcessCallbackType>
static ProcessWalker<ProcessCallbackType> MakeProcessWalker(ProcessCallbackType cb) {
  return ProcessWalker<ProcessCallbackType>(cb);
}

// Machinery to walk over a job tree and run a callback on each job.
template <typename JobCallbackType>
class JobWalker final : public JobEnumerator {
 public:
  JobWalker(JobCallbackType cb) : cb_(cb) {}
  JobWalker(const JobWalker&) = delete;
  JobWalker(JobWalker&& other) : cb_(other.cb_) {}

 private:
  bool OnJob(JobDispatcher* job) final {
    cb_(job);
    return true;
  }

  const JobCallbackType cb_;
};

template <typename JobCallbackType>
static JobWalker<JobCallbackType> MakeJobWalker(JobCallbackType cb) {
  return JobWalker<JobCallbackType>(cb);
}

static void DumpProcessListKeyMap() {
  printf("id  : process id number\n");
  printf("#h  : total number of handles\n");
  printf("#jb : number of job handles\n");
  printf("#pr : number of process handles\n");
  printf("#th : number of thread handles\n");
  printf("#vo : number of vmo handles\n");
  printf("#vm : number of virtual memory address region handles\n");
  printf("#ch : number of channel handles\n");
  printf("#ev : number of event and event pair handles\n");
  printf("#po : number of port handles\n");
  printf("#so: number of sockets\n");
  printf("#tm : number of timers\n");
  printf("#fi : number of fifos\n");
  printf("#?? : number of all other handle types\n");
}

static const char* ObjectTypeToString(zx_obj_type_t type) {
  switch (type) {
    case ZX_OBJ_TYPE_PROCESS:
      return "process";
    case ZX_OBJ_TYPE_THREAD:
      return "thread";
    case ZX_OBJ_TYPE_VMO:
      return "vmo";
    case ZX_OBJ_TYPE_CHANNEL:
      return "channel";
    case ZX_OBJ_TYPE_EVENT:
      return "event";
    case ZX_OBJ_TYPE_PORT:
      return "port";
    case ZX_OBJ_TYPE_INTERRUPT:
      return "interrupt";
    case ZX_OBJ_TYPE_PCI_DEVICE:
      return "pci-device";
    case ZX_OBJ_TYPE_LOG:
      return "log";
    case ZX_OBJ_TYPE_SOCKET:
      return "socket";
    case ZX_OBJ_TYPE_RESOURCE:
      return "resource";
    case ZX_OBJ_TYPE_EVENTPAIR:
      return "event-pair";
    case ZX_OBJ_TYPE_JOB:
      return "job";
    case ZX_OBJ_TYPE_VMAR:
      return "vmar";
    case ZX_OBJ_TYPE_FIFO:
      return "fifo";
    case ZX_OBJ_TYPE_GUEST:
      return "guest";
    case ZX_OBJ_TYPE_VCPU:
      return "vcpu";
    case ZX_OBJ_TYPE_TIMER:
      return "timer";
    case ZX_OBJ_TYPE_IOMMU:
      return "iommu";
    case ZX_OBJ_TYPE_BTI:
      return "bti";
    case ZX_OBJ_TYPE_PROFILE:
      return "profile";
    case ZX_OBJ_TYPE_PMT:
      return "pmt";
    case ZX_OBJ_TYPE_SUSPEND_TOKEN:
      return "suspend-token";
    case ZX_OBJ_TYPE_PAGER:
      return "pager";
    case ZX_OBJ_TYPE_EXCEPTION:
      return "exception";
    default:
      return "???";
  }
}

// Returns the count of a process's handles. For each handle, the corresponding
// zx_obj_type_t-indexed element of |handle_types| is incremented.
using HandleTypeCounts = ktl::span<uint32_t, ZX_OBJ_TYPE_UPPER_BOUND>;
static uint32_t BuildHandleStats(const ProcessDispatcher& pd, HandleTypeCounts handle_types) {
  uint32_t total = 0;
  pd.handle_table().ForEachHandle(
      [&](zx_handle_t handle, zx_rights_t rights, const Dispatcher* disp) {
        uint32_t type = static_cast<uint32_t>(disp->get_type());
        ++handle_types[type];
        ++total;
        return ZX_OK;
      });
  return total;
}

// Counts the process's handles by type and formats them into the provided
// buffer as strings.
static void FormatHandleTypeCount(const ProcessDispatcher& pd, char* buf, size_t buf_len) {
  uint32_t types[ZX_OBJ_TYPE_UPPER_BOUND] = {0};
  uint32_t handle_count = BuildHandleStats(pd, types);

  snprintf(buf, buf_len, "%4u: %4u %3u %3u %3u %3u %3u %3u %3u %3u %3u %3u %3u", handle_count,
           types[ZX_OBJ_TYPE_JOB], types[ZX_OBJ_TYPE_PROCESS], types[ZX_OBJ_TYPE_THREAD],
           types[ZX_OBJ_TYPE_VMO], types[ZX_OBJ_TYPE_VMAR], types[ZX_OBJ_TYPE_CHANNEL],
           types[ZX_OBJ_TYPE_EVENT] + types[ZX_OBJ_TYPE_EVENTPAIR], types[ZX_OBJ_TYPE_PORT],
           types[ZX_OBJ_TYPE_SOCKET], types[ZX_OBJ_TYPE_TIMER], types[ZX_OBJ_TYPE_FIFO],
           types[ZX_OBJ_TYPE_INTERRUPT] + types[ZX_OBJ_TYPE_PCI_DEVICE] + types[ZX_OBJ_TYPE_LOG] +
               types[ZX_OBJ_TYPE_RESOURCE] + types[ZX_OBJ_TYPE_GUEST] + types[ZX_OBJ_TYPE_VCPU] +
               types[ZX_OBJ_TYPE_IOMMU] + types[ZX_OBJ_TYPE_BTI] + types[ZX_OBJ_TYPE_PROFILE] +
               types[ZX_OBJ_TYPE_PMT] + types[ZX_OBJ_TYPE_SUSPEND_TOKEN] +
               types[ZX_OBJ_TYPE_PAGER] + types[ZX_OBJ_TYPE_EXCEPTION]);
}

void DumpProcessList() {
  printf("%7s   #h:  #jb #pr #th #vo #vm #ch #ev #po #so #tm #fi #?? [name]\n", "id");

  auto walker = MakeProcessWalker([](ProcessDispatcher* process) {
    char handle_counts[(ZX_OBJ_TYPE_UPPER_BOUND * 4) + 1 + /*slop*/ 16];
    FormatHandleTypeCount(*process, handle_counts, sizeof(handle_counts));

    char pname[ZX_MAX_NAME_LEN];
    process->get_name(pname);
    printf("%7" PRIu64 " %s [%s]\n", process->get_koid(), handle_counts, pname);
  });
  GetRootJobDispatcher()->EnumerateChildren(&walker, /* recurse */ true);
}

void DumpJobList() {
  printf("All jobs:\n");
  printf("%7s %s\n", "koid", "name");
  auto walker = MakeJobWalker([](JobDispatcher* job) {
    char name[ZX_MAX_NAME_LEN];
    job->get_name(name);
    printf("%7" PRIu64 " '%s'\n", job->get_koid(), name);
  });
  GetRootJobDispatcher()->EnumerateChildren(&walker, /* recurse */ true);
}

void DumpProcessChannels(fbl::RefPtr<ProcessDispatcher> process,
                         zx_koid_t koid_filter = ZX_KOID_INVALID) {
  char pname[ZX_MAX_NAME_LEN];
  bool printed_header = false;

  process->handle_table().ForEachHandle(
      [&](zx_handle_t handle, zx_rights_t rights, const Dispatcher* disp) {
        if (disp->get_type() == ZX_OBJ_TYPE_CHANNEL) {
          auto chan = DownCastDispatcher<const ChannelDispatcher>(disp);
          uint64_t koid, peer_koid, count, max_count;
          {
            Guard<Mutex> guard{chan->get_lock()};
            koid = chan->get_koid();
            peer_koid = chan->get_related_koid();
            count = chan->get_message_count();
            max_count = chan->get_max_message_count();
          }
          if (koid_filter != ZX_KOID_INVALID && koid_filter != koid && koid_filter != peer_koid)
            return ZX_OK;
          if (!printed_header) {
            process->get_name(pname);
            printf("%7" PRIu64 " [%s]\n", process->get_koid(), pname);
            printed_header = true;
          }
          printf("    chan %7" PRIu64 " %7" PRIu64 " count %" PRIu64 " max %" PRIu64 "\n", koid,
                 peer_koid, count, max_count);
        }
        return ZX_OK;
      });
}

void DumpChannelsByKoid(zx_koid_t id) {
  auto pd = ProcessDispatcher::LookupProcessById(id);
  if (pd) {
    DumpProcessChannels(pd);
  } else {
    auto walker = MakeProcessWalker(
        [id](ProcessDispatcher* process) { DumpProcessChannels(fbl::RefPtr(process), id); });
    GetRootJobDispatcher()->EnumerateChildren(&walker, /* recurse */ true);
  }
}

void DumpAllChannels() {
  auto walker = MakeProcessWalker(
      [](ProcessDispatcher* process) { DumpProcessChannels(fbl::RefPtr(process)); });
  GetRootJobDispatcher()->EnumerateChildren(&walker, /* recurse */ true);
}

static const char kRightsHeader[] =
    "dup tr r w x map gpr spr enm des spo gpo sig sigp wt ins mj mp mt ap";
static void DumpHandleRightsKeyMap() {
  printf("dup : ZX_RIGHT_DUPLICATE\n");
  printf("tr  : ZX_RIGHT_TRANSFER\n");
  printf("r   : ZX_RIGHT_READ\n");
  printf("w   : ZX_RIGHT_WRITE\n");
  printf("x   : ZX_RIGHT_EXECUTE\n");
  printf("map : ZX_RIGHT_MAP\n");
  printf("gpr : ZX_RIGHT_GET_PROPERTY\n");
  printf("spr : ZX_RIGHT_SET_PROPERTY\n");
  printf("enm : ZX_RIGHT_ENUMERATE\n");
  printf("des : ZX_RIGHT_DESTROY\n");
  printf("spo : ZX_RIGHT_SET_POLICY\n");
  printf("gpo : ZX_RIGHT_GET_POLICY\n");
  printf("sig : ZX_RIGHT_SIGNAL\n");
  printf("sigp: ZX_RIGHT_SIGNAL_PEER\n");
  printf("wt  : ZX_RIGHT_WAIT\n");
  printf("ins : ZX_RIGHT_INSPECT\n");
  printf("mj  : ZX_RIGHT_MANAGE_JOB\n");
  printf("mp  : ZX_RIGHT_MANAGE_PROCESS\n");
  printf("mt  : ZX_RIGHT_MANAGE_THREAD\n");
  printf("ap  : ZX_RIGHT_APPLY_PROFILE\n");
}

static bool HasRights(zx_rights_t rights, zx_rights_t desired) {
  return (rights & desired) == desired;
}

static void FormatHandleRightsMask(zx_rights_t rights, char* buf, size_t buf_len) {
  snprintf(buf, buf_len,
           "%3d %2d %1d %1d %1d %3d %3d %3d %3d %3d %3d %3d %3d %4d %2d %3d %2d %2d %2d %2d",
           HasRights(rights, ZX_RIGHT_DUPLICATE), HasRights(rights, ZX_RIGHT_TRANSFER),
           HasRights(rights, ZX_RIGHT_READ), HasRights(rights, ZX_RIGHT_WRITE),
           HasRights(rights, ZX_RIGHT_EXECUTE), HasRights(rights, ZX_RIGHT_MAP),
           HasRights(rights, ZX_RIGHT_GET_PROPERTY), HasRights(rights, ZX_RIGHT_SET_PROPERTY),
           HasRights(rights, ZX_RIGHT_ENUMERATE), HasRights(rights, ZX_RIGHT_DESTROY),
           HasRights(rights, ZX_RIGHT_SET_POLICY), HasRights(rights, ZX_RIGHT_GET_POLICY),
           HasRights(rights, ZX_RIGHT_SIGNAL), HasRights(rights, ZX_RIGHT_SIGNAL_PEER),
           HasRights(rights, ZX_RIGHT_WAIT), HasRights(rights, ZX_RIGHT_INSPECT),
           HasRights(rights, ZX_RIGHT_MANAGE_JOB), HasRights(rights, ZX_RIGHT_MANAGE_PROCESS),
           HasRights(rights, ZX_RIGHT_MANAGE_THREAD), HasRights(rights, ZX_RIGHT_APPLY_PROFILE));
}

void DumpProcessHandles(zx_koid_t id) {
  auto pd = ProcessDispatcher::LookupProcessById(id);
  if (!pd) {
    printf("process %" PRIu64 " not found!\n", id);
    return;
  }

  char pname[ZX_MAX_NAME_LEN];
  pd->get_name(pname);
  printf("process %" PRIu64 " ('%s') handles:\n", id, pname);
  printf("%7s %10s %10s: {%s} [type]\n", "koid", "handle", "rights", kRightsHeader);

  uint32_t total = 0;
  pd->handle_table().ForEachHandle(
      [&](zx_handle_t handle, zx_rights_t rights, const Dispatcher* disp) {
        char rights_mask[sizeof(kRightsHeader)];
        FormatHandleRightsMask(rights, rights_mask, sizeof(rights_mask));
        printf("%7" PRIu64 " %#10x %#10x: {%s} [%s]\n", disp->get_koid(), handle, rights,
               rights_mask, ObjectTypeToString(disp->get_type()));
        ++total;
        return ZX_OK;
      });
  printf("total: %u handles\n", total);
}

void DumpHandlesForKoid(zx_koid_t id) {
  if (id < ZX_KOID_FIRST) {
    printf("invalid koid, non-reserved koids start at %" PRIu64 "\n", ZX_KOID_FIRST);
    return;
  }

  uint32_t total_proc = 0;
  uint32_t total_handles = 0;
  auto walker = MakeProcessWalker([&](ProcessDispatcher* process) {
    bool found_handle = false;
    process->handle_table().ForEachHandle([&](zx_handle_t handle, zx_rights_t rights,
                                              const Dispatcher* disp) {
      if (disp->get_koid() != id) {
        return ZX_OK;
      }

      if (total_handles == 0) {
        printf("handles for koid %" PRIu64 " (%s):\n", id, ObjectTypeToString(disp->get_type()));
        printf("%7s %10s: {%s} [name]\n", "pid", "rights", kRightsHeader);
      }

      char pname[ZX_MAX_NAME_LEN];
      char rights_mask[sizeof(kRightsHeader)];
      process->get_name(pname);
      FormatHandleRightsMask(rights, rights_mask, sizeof(rights_mask));
      printf("%7" PRIu64 " %#10x: {%s} [%s]\n", process->get_koid(), rights, rights_mask, pname);

      ++total_handles;
      found_handle = true;
      return ZX_OK;
    });
    total_proc += found_handle;
  });
  GetRootJobDispatcher()->EnumerateChildren(&walker, /* recurse */ true);

  if (total_handles > 0) {
    printf("total: %u handles in %u processes\n", total_handles, total_proc);
  } else {
    printf("no handles found for koid %" PRIu64 "\n", id);
  }
}

void ktrace_report_live_processes() {
  auto walker = MakeProcessWalker([](ProcessDispatcher* process) {
    char name[ZX_MAX_NAME_LEN];
    process->get_name(name);
    ktrace_name(TAG_PROC_NAME, (uint32_t)process->get_koid(), 0, name, /*always*/ true);
  });
  GetRootJobDispatcher()->EnumerateChildren(&walker, /* recurse */ true);
}

// Returns a string representation of VMO-related rights.
static constexpr size_t kRightsStrLen = 8;
static const char* VmoRightsToString(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;
}

// Prints a header for the columns printed by DumpVmObject.
// If |handles| is true, the dumped objects are expected to have handle info.
static void PrintVmoDumpHeader(bool handles) {
  printf("%s koid obj                parent #chld #map #shr    size   alloc name\n",
         handles ? "      handle rights " : "           -      - ");
}

static void DumpVmObject(const VmObject& vmo, pretty::SizeUnit format_unit, zx_handle_t handle,
                         uint32_t rights, zx_koid_t koid) {
  char handle_str[11];
  if (handle != ZX_HANDLE_INVALID) {
    snprintf(handle_str, sizeof(handle_str), "%u", static_cast<uint32_t>(handle));
  } else {
    handle_str[0] = '-';
    handle_str[1] = '\0';
  }

  char rights_str[kRightsStrLen];
  if (rights != 0) {
    VmoRightsToString(rights, rights_str);
  } else {
    rights_str[0] = '-';
    rights_str[1] = '\0';
  }

  FormattedBytes size_str(vmo.size(), format_unit);

  FormattedBytes alloc_size;
  const char* alloc_str = "phys";
  if (vmo.is_paged()) {
    alloc_size.SetSize(vmo.AttributedPages() * PAGE_SIZE, format_unit);
    alloc_str = alloc_size.c_str();
  }

  char child_str[21];
  if (vmo.child_type() != VmObject::kNotChild) {
    snprintf(child_str, sizeof(child_str), "%" PRIu64, vmo.parent_user_id());
  } else {
    child_str[0] = '-';
    child_str[1] = '\0';
  }

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

  printf(
      "  %10s "  // handle
      "%6s "     // rights
      "%5" PRIu64
      " "     // koid
      "%p "   // vm_object
      "%6s "  // child parent koid
      "%5" PRIu32
      " "  // number of children
      "%4" PRIu32
      " "  // map count
      "%4" PRIu32
      " "      // share count
      "%7s "   // size in bytes
      "%7s "   // allocated bytes
      "%s\n",  // name
      handle_str, rights_str, koid, &vmo, child_str, vmo.num_children(), vmo.num_mappings(),
      vmo.share_count(), size_str.c_str(), alloc_str, name);
}

// If |hidden_only| is set, will only dump VMOs that are not mapped
// into any process:
// - VMOs that userspace has handles to but does not map
// - VMOs that are mapped only into kernel space
// - Kernel-only, unmapped VMOs that have no handles
static void DumpAllVmObjects(bool hidden_only, pretty::SizeUnit format_unit) {
  if (hidden_only) {
    printf("\"Hidden\" VMOs, oldest to newest:\n");
  } else {
    printf("All VMOs, oldest to newest:\n");
  }
  PrintVmoDumpHeader(/* handles */ false);
  VmObject::ForEach([=](const VmObject& vmo) {
    if (hidden_only && vmo.IsMappedByUser()) {
      return ZX_OK;
    }
    DumpVmObject(vmo, format_unit, ZX_HANDLE_INVALID,
                 /* rights */ 0u,
                 /* koid */ vmo.user_id());
    // TODO(dbort): Dump the VmAspaces (processes) that map the VMO.
    // TODO(dbort): Dump the processes that hold handles to the VMO.
    //     This will be a lot harder to gather.
    return ZX_OK;
  });
  PrintVmoDumpHeader(/* handles */ false);
}

namespace {
// Dumps VMOs under a VmAspace.
class AspaceVmoDumper final : public VmEnumerator {
 public:
  explicit AspaceVmoDumper(pretty::SizeUnit format_unit) : format_unit_(format_unit) {}
  bool OnVmMapping(const VmMapping* map, const VmAddressRegion* vmar, uint depth) final {
    auto vmo = map->vmo_locked();
    DumpVmObject(*vmo, format_unit_, ZX_HANDLE_INVALID,
                 /* rights */ 0u,
                 /* koid */ vmo->user_id());
    return true;
  }

 private:
  pretty::SizeUnit format_unit_;
};

// Dumps all VMOs associated with a process.
void DumpProcessVmObjects(zx_koid_t id, pretty::SizeUnit format_unit) {
  auto pd = ProcessDispatcher::LookupProcessById(id);
  if (!pd) {
    printf("process not found!\n");
    return;
  }

  printf("process [%" PRIu64 "]:\n", id);
  printf("Handles to VMOs:\n");
  PrintVmoDumpHeader(/* handles */ true);
  int count = 0;
  uint64_t total_size = 0;
  uint64_t total_alloc = 0;
  pd->handle_table().ForEachHandle(
      [&](zx_handle_t handle, zx_rights_t rights, const Dispatcher* disp) {
        auto vmod = DownCastDispatcher<const VmObjectDispatcher>(disp);
        if (vmod == nullptr) {
          return ZX_OK;
        }
        auto vmo = vmod->vmo();
        DumpVmObject(*vmo, format_unit, handle, rights, vmod->get_koid());

        // TODO: Doesn't handle the case where a process has multiple
        // handles to the same VMO; will double-count all of these totals.
        count++;
        total_size += vmo->size();
        // TODO: Doing this twice (here and in DumpVmObject) is a waste of
        // work, and can get out of sync.
        total_alloc += vmo->AttributedPages() * PAGE_SIZE;
        return ZX_OK;
      });
  printf("  total: %d VMOs, size %s, alloc %s\n", count,
         FormattedBytes(total_size, format_unit).c_str(),
         FormattedBytes(total_alloc, format_unit).c_str());

  // Call DumpVmObject() on all VMOs under the process's VmAspace.
  printf("Mapped VMOs:\n");
  PrintVmoDumpHeader(/* handles */ false);
  AspaceVmoDumper avd(format_unit);
  pd->aspace()->EnumerateChildren(&avd);
  PrintVmoDumpHeader(/* handles */ false);
}

}  // namespace

void KillProcess(zx_koid_t id) {
  // search the process list and send a kill if found
  auto pd = ProcessDispatcher::LookupProcessById(id);
  if (!pd) {
    printf("process not found!\n");
    return;
  }
  // if found, outside of the lock hit it with kill
  printf("killing process %" PRIu64 "\n", id);
  pd->Kill(ZX_TASK_RETCODE_SYSCALL_KILL);
}

namespace {
// Counts memory usage under a VmAspace.
class VmCounter final : public VmEnumerator {
 public:
  bool OnVmMapping(const VmMapping* map, const VmAddressRegion* vmar, uint depth)
      TA_REQ(map->lock()) TA_REQ(vmar->lock()) override {
    usage.mapped_pages += map->size() / PAGE_SIZE;

    auto vmo = map->vmo_locked();
    size_t committed_pages = vmo->AttributedPagesInRange(map->object_offset_locked(), map->size());
    uint32_t share_count = vmo->share_count();
    if (share_count == 1) {
      usage.private_pages += committed_pages;
    } else {
      usage.shared_pages += committed_pages;
      usage.scaled_shared_bytes += committed_pages * PAGE_SIZE / share_count;
    }
    return true;
  }

  VmAspace::vm_usage_t usage = {};
};
}  // namespace

zx_status_t VmAspace::GetMemoryUsage(vm_usage_t* usage) {
  VmCounter vc;
  if (!EnumerateChildren(&vc)) {
    *usage = {};
    return ZX_ERR_INTERNAL;
  }
  *usage = vc.usage;
  return ZX_OK;
}

namespace {
unsigned int arch_mmu_flags_to_vm_flags(unsigned int arch_mmu_flags) {
  if (arch_mmu_flags & ARCH_MMU_FLAG_INVALID) {
    return 0;
  }
  unsigned int ret = 0;
  if (arch_mmu_flags & ARCH_MMU_FLAG_PERM_READ) {
    ret |= ZX_VM_PERM_READ;
  }
  if (arch_mmu_flags & ARCH_MMU_FLAG_PERM_WRITE) {
    ret |= ZX_VM_PERM_WRITE;
  }
  if (arch_mmu_flags & ARCH_MMU_FLAG_PERM_EXECUTE) {
    ret |= ZX_VM_PERM_EXECUTE;
  }
  return ret;
}

// This provides a generic way to perform VmAspace::EnumerateChildren in scenarios where the
// enumeration may need to be retried due to page faults for user copies needing to be handled.
// Mostly it serves to reduce the duplication in logic between the VmMapBuilder and the
// AspaceVmoEnumerator and so the template options exist to handle precisely those two cases.
// IMPL is the object type that the Make* methods will be called on if the respective Enumerate*
// options are true.
template <typename ENTRY, typename IMPL, bool EnumerateVmar, bool EnumerateMapping,
          size_t FirstEntry>
class RestartableVmEnumerator {
 public:
  // max is the total number of elements that entries can support, with FirstEntry being the first
  // of these entries that this enumerator will store to. This means we can write at most
  // max-FirstEntry entries.
  RestartableVmEnumerator(size_t max) : max_(max) {}

  zx_status_t Enumerate(VmAspace* target) {
    nelem_ = FirstEntry;
    available_ = FirstEntry;
    start_ = 0;
    faults_ = 0;
    visited_ = 0;

    // EnumerateChildren only fails if copying to the user hit a fault. We redo the copy outside
    // of the enumeration so that we're not holding the aspace lock. If it still fails then we
    // consider it an error, otherwise we restart the enumeration skipping any entries with a
    // virtual address in the segment we already processed. A segment is represented by an address
    // and a depth pair, as vmars/mappings can exist at the same base address due to them being
    // hierarchical, but they will have a higher depth.
    Enumerator enumerator{this};
    while (!target->EnumerateChildren(&enumerator)) {
      DEBUG_ASSERT(nelem_ < max_);
      zx_status_t result = WriteEntry(entry_, nelem_);
      if (result != ZX_OK) {
        return result;
      }
      nelem_++;
    }

    // This aims to ensure that the logic of skipping already processed segments does not cause us
    // to miss any segments. Guards against the VmAspace failing to correctly enumerate in depth
    // first order.
    DEBUG_ASSERT(faults_ > 0 || visited_ + FirstEntry == available_);

    return ZX_OK;
  }

  size_t nelem() const { return nelem_; }
  size_t available() const { return available_; }

 protected:
  virtual zx_status_t WriteEntry(const ENTRY& entry, size_t offset) = 0;
  virtual UserCopyCaptureFaultsResult WriteEntryCaptureFaults(const ENTRY& entry,
                                                              size_t offset) = 0;

 private:
  class Enumerator : public VmEnumerator {
   public:
    Enumerator(RestartableVmEnumerator* parent) : parent_(parent) {}

    bool OnVmAddressRegion([[maybe_unused]] const VmAddressRegion* vmar,
                           [[maybe_unused]] uint depth) override {
      if constexpr (EnumerateVmar) {
        return parent_->DoEntry(
            [vmar, depth, this] { IMPL::MakeVmarEntry(vmar, depth, &parent_->entry_); },
            vmar->base(), depth);
      }
      return true;
    }

    bool OnVmMapping([[maybe_unused]] const VmMapping* map,
                     [[maybe_unused]] const VmAddressRegion* vmar, [[maybe_unused]] uint depth)
        TA_REQ(map->lock()) TA_REQ(vmar->lock()) override {
      if constexpr (EnumerateMapping) {
        return parent_->DoEntry(
            [map, vmar, depth, this]() {
              // These are true as they are required for calling OnVmMapping, but we cannot pass
              // the capabilities easily via DoEntry to this callback.
              AssertHeld(map->lock_ref());
              AssertHeld(vmar->lock_ref());
              IMPL::MakeMappingEntry(map, vmar, depth, &parent_->entry_);
            },
            map->base(), depth);
      }
      return true;
    }

   private:
    RestartableVmEnumerator* parent_;
  };
  friend Enumerator;

  // This helper is templated to allow the maximum code sharing between the two On* callbacks.
  template <typename F>
  bool DoEntry(F&& make_entry, zx_vaddr_t base, uint depth) {
    visited_++;
    // Skip anything that is at an earlier address or depth to prevent us double processing any
    // segments.
    if (base < start_ || (base == start_ && depth < start_depth_)) {
      return true;
    }
    // Whatever happens we never want to process this again. We set this *always*, and not just on
    // faults so that the logic of skipping above is consistently applied helping catch any bugs in
    // changes to enumeration order.
    start_ = base;
    start_depth_ = depth + 1;

    available_++;
    if (nelem_ >= max_) {
      return true;
    }
    ktl::forward<F>(make_entry)();

    UserCopyCaptureFaultsResult res = WriteEntryCaptureFaults(entry_, nelem_);
    if (res.status != ZX_OK) {
      // This entry will get written out by the main loop, so return false to break all the way out.
      faults_++;
      return false;
    }

    nelem_++;
    return true;
  }

  const size_t max_;

  // Use a single ENTRY stashed here and pass it by reference anywhere as this can be a large
  // structure and we want to avoid multiple stack allocations from occurring.
  ENTRY entry_{};
  static_assert(sizeof(ENTRY) < 512);
  size_t nelem_ = 0;
  size_t available_ = 0;

  zx_vaddr_t start_ = 0;
  uint start_depth_ = 0;

  // Count some statistics so we can do some lightweight sanity checking that we correctly process
  // everything.
  size_t faults_ = 0;
  size_t visited_ = 0;
};

// Builds a description of an apsace/vmar/mapping hierarchy. Entries start at 1 as the user must
// write an entry for the root VmAspace at index 0.
class VmMapBuilder final
    : public RestartableVmEnumerator<zx_info_maps_t, VmMapBuilder, true, true, 1> {
 public:
  // NOTE: Code outside of the syscall layer should not typically know about
  // user_ptrs; do not use this pattern as an example.
  VmMapBuilder(user_out_ptr<zx_info_maps_t> maps, size_t max)
      : RestartableVmEnumerator(max), entries_(maps) {}

  static void MakeVmarEntry(const VmAddressRegion* vmar, uint depth, zx_info_maps_t* entry) {
    *entry = {};
    strlcpy(entry->name, vmar->name(), sizeof(entry->name));
    entry->base = vmar->base();
    entry->size = vmar->size();
    entry->depth = depth + 1;  // The root aspace is depth 0.
    entry->type = ZX_INFO_MAPS_TYPE_VMAR;
  }

  static void MakeMappingEntry(const VmMapping* map, const VmAddressRegion* vmar, uint depth,
                               zx_info_maps_t* entry) TA_REQ(map->lock_ref())
      TA_REQ(vmar->lock_ref()) {
    *entry = {};
    auto vmo = map->vmo_locked();
    vmo->get_name(entry->name, sizeof(entry->name));
    entry->base = map->base();
    entry->size = map->size();
    entry->depth = depth + 1;  // The root aspace is depth 0.
    entry->type = ZX_INFO_MAPS_TYPE_MAPPING;
    zx_info_maps_mapping_t* u = &entry->u.mapping;
    u->mmu_flags = arch_mmu_flags_to_vm_flags(map->arch_mmu_flags_locked());
    u->vmo_koid = vmo->user_id();
    u->committed_pages = vmo->AttributedPagesInRange(map->object_offset_locked(), map->size());
    u->vmo_offset = map->object_offset_locked();
  }

 protected:
  zx_status_t WriteEntry(const zx_info_maps_t& entry, size_t offset) {
    return entries_.element_offset(offset).copy_to_user(entry);
  }
  UserCopyCaptureFaultsResult WriteEntryCaptureFaults(const zx_info_maps_t& entry, size_t offset) {
    return entries_.element_offset(offset).copy_to_user_capture_faults(entry);
  }
  const user_out_ptr<zx_info_maps_t> entries_;
};
}  // namespace

// NOTE: Code outside of the syscall layer should not typically know about
// user_ptrs; do not use this pattern as an example.
zx_status_t GetVmAspaceMaps(VmAspace* current_aspace, fbl::RefPtr<VmAspace> target_aspace,
                            user_out_ptr<zx_info_maps_t> maps, size_t max, size_t* actual,
                            size_t* available) {
  DEBUG_ASSERT(target_aspace != nullptr);
  *actual = 0;
  *available = 0;
  if (target_aspace->is_destroyed()) {
    return ZX_ERR_BAD_STATE;
  }
  if (max > 0) {
    zx_info_maps_t entry = {};
    strlcpy(entry.name, target_aspace->name(), sizeof(entry.name));
    entry.base = target_aspace->base();
    entry.size = target_aspace->size();
    entry.depth = 0;
    entry.type = ZX_INFO_MAPS_TYPE_ASPACE;
    if (maps.copy_array_to_user(&entry, 1, 0) != ZX_OK) {
      return ZX_ERR_INVALID_ARGS;
    }
  }

  VmMapBuilder b(maps, max);

  zx_status_t status = b.Enumerate(target_aspace.get());
  if (status != ZX_OK) {
    return status;
  }

  *actual = max > 0 ? b.nelem() : 0;
  *available = b.available();
  return ZX_OK;
}

namespace {
// Builds a list of all VMOs mapped into a VmAspace.
class AspaceVmoEnumerator final
    : public RestartableVmEnumerator<zx_info_vmo_t, AspaceVmoEnumerator, false, true, 0> {
 public:
  // NOTE: Code outside of the syscall layer should not typically know about
  // user_ptrs; do not use this pattern as an example.
  AspaceVmoEnumerator(VmoInfoWriter& vmos, size_t max)
      : RestartableVmEnumerator(max), vmos_(vmos) {}

  static void MakeMappingEntry(const VmMapping* map, const VmAddressRegion* vmar, uint depth,
                               zx_info_vmo_t* entry) {
    // We're likely to see the same VMO a couple times in a given
    // address space (e.g., somelib.so mapped as r--, r-x), but leave it
    // to userspace to do deduping.
    *entry = VmoToInfoEntry(map->vmo_locked().get(),
                            /*is_handle=*/false,
                            /*handle_rights=*/0);
  }

 protected:
  zx_status_t WriteEntry(const zx_info_vmo_t& entry, size_t offset) {
    return vmos_.Write(entry, offset);
  }
  UserCopyCaptureFaultsResult WriteEntryCaptureFaults(const zx_info_vmo_t& entry, size_t offset) {
    return vmos_.WriteCaptureFaults(entry, offset);
  }
  VmoInfoWriter& vmos_;
};
}  // namespace

// NOTE: Code outside of the syscall layer should not typically know about
// user_ptrs; do not use this pattern as an example.
zx_status_t GetVmAspaceVmos(VmAspace* current_aspace, fbl::RefPtr<VmAspace> target_aspace,
                            VmoInfoWriter& vmos, size_t max, size_t* actual, size_t* available) {
  DEBUG_ASSERT(target_aspace != nullptr);
  DEBUG_ASSERT(actual != nullptr);
  DEBUG_ASSERT(available != nullptr);
  *actual = 0;
  *available = 0;
  if (target_aspace->is_destroyed()) {
    return ZX_ERR_BAD_STATE;
  }

  AspaceVmoEnumerator ave(vmos, max);

  zx_status_t status = ave.Enumerate(target_aspace.get());
  if (status != ZX_OK) {
    return status;
  }

  *actual = ave.nelem();
  *available = ave.available();
  return ZX_OK;
}

// NOTE: Code outside of the syscall layer should not typically know about
// user_ptrs; do not use this pattern as an example.
zx_status_t GetProcessVmos(ProcessDispatcher* process, VmoInfoWriter& vmos, size_t max,
                           size_t* actual_out, size_t* available_out) {
  DEBUG_ASSERT(process != nullptr);
  DEBUG_ASSERT(actual_out != nullptr);
  DEBUG_ASSERT(available_out != nullptr);
  size_t actual = 0;
  size_t available = 0;
  // We may see multiple handles to the same VMO, but leave it to userspace to
  // do deduping.
  zx_status_t s = process->handle_table().ForEachHandleBatched(
      [&](zx_handle_t handle, zx_rights_t rights, const Dispatcher* disp) {
        auto vmod = DownCastDispatcher<const VmObjectDispatcher>(disp);
        if (vmod == nullptr) {
          // This handle isn't a VMO; skip it.
          return ZX_OK;
        }
        available++;
        if (actual < max) {
          zx_info_vmo_t entry = VmoToInfoEntry(vmod->vmo().get(),
                                               /*is_handle=*/true, rights);
          if (vmos.Write(entry, actual) != ZX_OK) {
            return ZX_ERR_INVALID_ARGS;
          }
          actual++;
        }
        return ZX_OK;
      });
  if (s != ZX_OK) {
    return s;
  }
  *actual_out = actual;
  *available_out = available;
  return ZX_OK;
}

void DumpProcessAddressSpace(zx_koid_t id) {
  auto pd = ProcessDispatcher::LookupProcessById(id);
  if (!pd) {
    printf("process %" PRIu64 " not found!\n", id);
    return;
  }

  pd->aspace()->Dump(true);
}

// Dumps an address space based on the arg.
static void DumpAddressSpace(const cmd_args* arg) {
  if (strncmp(arg->str, "kernel", strlen(arg->str)) == 0) {
    // The arg is a prefix of "kernel".
    VmAspace::kernel_aspace()->Dump(true);
  } else {
    DumpProcessAddressSpace(arg->u);
  }
}

static void DumpHandleTable() {
  printf("outstanding handles: %zu\n", Handle::diagnostics::OutstandingHandles());
  Handle::diagnostics::DumpTableInfo();
}

static size_t mwd_limit = 32 * 256;
static bool mwd_running;

static size_t hwd_limit = 1024;
static bool hwd_running;

static int hwd_thread(void* arg) {
  static size_t previous_handle_count = 0u;

  for (;;) {
    auto handle_count = Handle::diagnostics::OutstandingHandles();
    if (handle_count != previous_handle_count) {
      if (handle_count > hwd_limit) {
        printf("HandleWatchdog! %zu handles outstanding (greater than limit %zu)\n", handle_count,
               hwd_limit);
      } else if (previous_handle_count > hwd_limit) {
        printf("HandleWatchdog! %zu handles outstanding (dropping below limit %zu)\n", handle_count,
               hwd_limit);
      }
    }

    previous_handle_count = handle_count;

    Thread::Current::SleepRelative(ZX_SEC(1));
  }
}

void DumpProcessMemoryUsage(const char* prefix, size_t min_pages) {
  auto walker = MakeProcessWalker([&](ProcessDispatcher* process) {
    size_t pages = process->PageCount();
    if (pages >= min_pages) {
      char pname[ZX_MAX_NAME_LEN];
      process->get_name(pname);
      printf("%sproc %5" PRIu64 " %4zuM '%s'\n", prefix, process->get_koid(), pages / 256, pname);
    }
  });
  GetRootJobDispatcher()->EnumerateChildren(&walker, /* recurse */ true);
}

static int mwd_thread(void* arg) {
  for (;;) {
    Thread::Current::SleepRelative(ZX_SEC(1));
    DumpProcessMemoryUsage("MemoryHog! ", mwd_limit);
  }
}

static int cmd_diagnostics(int argc, const cmd_args* argv, uint32_t flags) {
  int rc = 0;

  if (argc < 2) {
    printf("not enough arguments:\n");
  usage:
    printf("%s ps                : list processes\n", argv[0].str);
    printf("%s ps help           : print header label descriptions for 'ps'\n", argv[0].str);
    printf("%s jobs              : list jobs\n", argv[0].str);
    printf("%s mwd  <mb>         : memory watchdog\n", argv[0].str);
    printf("%s ht   <pid>        : dump process handles\n", argv[0].str);
    printf("%s ch   <koid>       : dump channels for pid or for all processes,\n", argv[0].str);
    printf("                       or processes for channel koid\n");
    printf("%s hwd  <count>      : handle watchdog\n", argv[0].str);
    printf("%s vmos <pid>|all|hidden [-u?]\n", argv[0].str);
    printf("                     : dump process/all/hidden VMOs\n");
    printf("                 -u? : fix all sizes to the named unit\n");
    printf("                       where ? is one of [BkMGTPE]\n");
    printf("%s kill <pid>        : kill process\n", argv[0].str);
    printf("%s asd  <pid>|kernel : dump process/kernel address space\n", argv[0].str);
    printf("%s htinfo            : handle table info\n", argv[0].str);
    printf("%s koid <koid>       : list all handles for a koid\n", argv[0].str);
    printf("%s koid help         : print header label descriptions for 'koid'\n", argv[0].str);
    return -1;
  }

  if (strcmp(argv[1].str, "mwd") == 0) {
    if (argc == 3) {
      mwd_limit = argv[2].u * 256;
    }
    if (!mwd_running) {
      Thread* t = Thread::Create("mwd", mwd_thread, nullptr, DEFAULT_PRIORITY);
      if (t) {
        mwd_running = true;
        t->Resume();
      }
    }
  } else if (strcmp(argv[1].str, "ps") == 0) {
    if ((argc == 3) && (strcmp(argv[2].str, "help") == 0)) {
      DumpProcessListKeyMap();
    } else {
      DumpProcessList();
    }
  } else if (strcmp(argv[1].str, "jobs") == 0) {
    DumpJobList();
  } else if (strcmp(argv[1].str, "hwd") == 0) {
    if (argc == 3) {
      hwd_limit = argv[2].u;
    }
    if (!hwd_running) {
      Thread* t = Thread::Create("hwd", hwd_thread, nullptr, DEFAULT_PRIORITY);
      if (t) {
        hwd_running = true;
        t->Resume();
      }
    }
  } else if (strcmp(argv[1].str, "ht") == 0) {
    if (argc < 3)
      goto usage;
    DumpProcessHandles(argv[2].u);
  } else if (strcmp(argv[1].str, "ch") == 0) {
    if (argc == 3) {
      DumpChannelsByKoid(argv[2].u);
    } else {
      DumpAllChannels();
    }
  } else if (strcmp(argv[1].str, "vmos") == 0) {
    if (argc < 3)
      goto usage;
    pretty::SizeUnit format_unit = pretty::SizeUnit::kAuto;
    if (argc >= 4) {
      if (!strncmp(argv[3].str, "-u", sizeof("-u") - 1)) {
        format_unit = static_cast<pretty::SizeUnit>(argv[3].str[sizeof("-u") - 1]);
      } else {
        printf("dunno '%s'\n", argv[3].str);
        goto usage;
      }
    }
    if (strcmp(argv[2].str, "all") == 0) {
      DumpAllVmObjects(/*hidden_only=*/false, format_unit);
    } else if (strcmp(argv[2].str, "hidden") == 0) {
      DumpAllVmObjects(/*hidden_only=*/true, format_unit);
    } else {
      DumpProcessVmObjects(argv[2].u, format_unit);
    }
  } else if (strcmp(argv[1].str, "kill") == 0) {
    if (argc < 3)
      goto usage;
    KillProcess(argv[2].u);
  } else if (strcmp(argv[1].str, "asd") == 0) {
    if (argc < 3)
      goto usage;
    DumpAddressSpace(&argv[2]);
  } else if (strcmp(argv[1].str, "htinfo") == 0) {
    if (argc != 2)
      goto usage;
    DumpHandleTable();
  } else if (strcmp(argv[1].str, "koid") == 0) {
    if (argc < 3)
      goto usage;

    if (strcmp(argv[2].str, "help") == 0) {
      DumpHandleRightsKeyMap();
    } else {
      DumpHandlesForKoid(argv[2].u);
    }
  } else {
    printf("unrecognized subcommand '%s'\n", argv[1].str);
    goto usage;
  }
  return rc;
}

STATIC_COMMAND_START
STATIC_COMMAND("zx", "kernel object diagnostics", &cmd_diagnostics)
STATIC_COMMAND_END(zx)
