// 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 <inttypes.h>
#include <lib/backtrace-request/backtrace-request-utils.h>
#include <lib/zx/process.h>
#include <lib/zx/thread.h>
#include <string.h>
#include <zircon/assert.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/exception.h>
#include <zircon/syscalls/policy.h>
#include <zircon/types.h>

#include <string>
#include <vector>

#include "inspector/inspector.h"
#include "utils-impl.h"

namespace inspector {

#if defined(__x86_64__)
static const char* kArch = "x86_64";
#elif defined(__aarch64__)
static const char* kArch = "aarch64";
#elif defined(__riscv)
static const char* kArch = "riscv64";
#else
#error unsupported architecture
#endif

static const char* excp_type_to_str(const zx_excp_type_t type) {
  switch (type) {
    case ZX_EXCP_GENERAL:
      return "general fault";
    case ZX_EXCP_FATAL_PAGE_FAULT:
      return "fatal page fault";
    case ZX_EXCP_UNDEFINED_INSTRUCTION:
      return "undefined instruction";
    case ZX_EXCP_SW_BREAKPOINT:
      return "sw breakpoint";
    case ZX_EXCP_HW_BREAKPOINT:
      return "hw breakpoint";
    case ZX_EXCP_UNALIGNED_ACCESS:
      return "alignment fault";
    case ZX_EXCP_POLICY_ERROR:
      return "policy error";
    default:
      // Note: To get a compilation failure when a new exception type has
      // been added without having also updated this function, compile with
      // -Wswitch-enum.
      return "<unknown fault>";
  }
}

static const char* policy_exception_code_to_str(uint32_t policy_exception_code) {
  switch (policy_exception_code) {
    case ZX_EXCP_POLICY_CODE_BAD_HANDLE:
      return "BAD_HANDLE";
    case ZX_EXCP_POLICY_CODE_WRONG_OBJECT:
      return "WRONG_OBJECT";
    case ZX_EXCP_POLICY_CODE_VMAR_WX:
      return "VMAR_WX";
    case ZX_EXCP_POLICY_CODE_NEW_ANY:
      return "NEW_ANY";
    case ZX_EXCP_POLICY_CODE_NEW_VMO:
      return "NEW_VMO";
    case ZX_EXCP_POLICY_CODE_NEW_CHANNEL:
      return "NEW_CHANNEL";
    case ZX_EXCP_POLICY_CODE_NEW_EVENT:
      return "NEW_EVENT";
    case ZX_EXCP_POLICY_CODE_NEW_EVENTPAIR:
      return "NEW_EVENTPAIR";
    case ZX_EXCP_POLICY_CODE_NEW_PORT:
      return "NEW_PORT";
    case ZX_EXCP_POLICY_CODE_NEW_SOCKET:
      return "NEW_SOCKET";
    case ZX_EXCP_POLICY_CODE_NEW_FIFO:
      return "NEW_FIFO";
    case ZX_EXCP_POLICY_CODE_NEW_TIMER:
      return "NEW_TIMER";
    case ZX_EXCP_POLICY_CODE_NEW_PROCESS:
      return "NEW_PROCESS";
    case ZX_EXCP_POLICY_CODE_NEW_PROFILE:
      return "NEW_PROFILE";
    case ZX_EXCP_POLICY_CODE_AMBIENT_MARK_VMO_EXEC:
      return "AMBIENT_MARK_VMO_EXEC";
    case ZX_EXCP_POLICY_CODE_CHANNEL_FULL_WRITE:
      return "CHANNEL_FULL_WRITE";
    case ZX_EXCP_POLICY_CODE_PORT_TOO_MANY_PACKETS:
      return "PORT_TOO_MANY_PACKETS";
    case ZX_EXCP_POLICY_CODE_BAD_SYSCALL:
      return "BAD_SYSCALL";
    default:
      return "<unknown policy code>";
  }
}

// Globs the general registers and the interpretation of them as IP, SP, FP, etc.
typedef struct decoded_registers_t {
  zx_vaddr_t pc = 0;
  zx_vaddr_t sp = 0;
  zx_vaddr_t fp = 0;
} decoded_registers;

decoded_registers_t decode_registers(const zx_thread_state_general_regs* regs) {
  decoded_registers decoded;
#if defined(__x86_64__)
  decoded.pc = regs->rip;
  decoded.sp = regs->rsp;
  decoded.fp = regs->rbp;
#elif defined(__aarch64__)
  decoded.pc = regs->pc;
  decoded.sp = regs->sp;
  decoded.fp = regs->r[29];
#elif defined(__riscv)
#else
#error unsupported architecture
#endif

  return decoded;
}

// How much memory to dump, in bytes.
static constexpr size_t kMemoryDumpSize = 256;

static zx_koid_t get_koid(zx_handle_t handle) {
  zx_info_handle_basic_t info;
  zx_status_t status =
      zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
  if (status != ZX_OK) {
    printf("failed to get koid\n");
    return ZX_HANDLE_INVALID;
  }
  return info.koid;
}

static void get_name(zx_handle_t handle, char* buf, size_t size) {
  zx_status_t status = zx_object_get_property(handle, ZX_PROP_NAME, buf, size);
  if (status != ZX_OK) {
    strlcpy(buf, "<unknown>", size);
  }
}

static void print_exception_report(FILE* out, const zx_exception_report_t& report,
                                   const zx_thread_state_general_regs* regs) {
  inspector::decoded_registers decoded = inspector::decode_registers(regs);

  if (report.header.type == ZX_EXCP_FATAL_PAGE_FAULT) {
    const char* access_type = "<unknown>";
    const char* violation = "<unknown>";
#if defined(__x86_64__)
    static constexpr uint32_t kErrCodeInstrFetch = (1 << 4);
    static constexpr uint32_t kErrCodeWrite = (1 << 1);
    static constexpr uint32_t kErrCodeProtectionViolation = (1 << 0);
    if (report.context.arch.u.x86_64.err_code & kErrCodeInstrFetch) {
      access_type = "execute";
    } else if (report.context.arch.u.x86_64.err_code & kErrCodeWrite) {
      access_type = "write";
    } else {
      access_type = "read";
    }

    if (report.context.arch.u.x86_64.err_code & kErrCodeProtectionViolation) {
      violation = "protection";
    } else {
      violation = "not-present";
    }
#elif defined(__aarch64__)
    // The one ec bit that's different between a data and instruction abort
    static constexpr uint32_t kEcDataAbortBit = (1 << 28);
    static constexpr uint32_t kIssCacheOp = (1 << 8);
    static constexpr uint32_t kIssWrite = (1 << 6);
    static constexpr uint32_t kDccNoLvlMask = 0b111100;
    static constexpr uint32_t kDccPermissionFault = 0b001100;
    static constexpr uint32_t kDccTranslationFault = 0b000100;
    static constexpr uint32_t kDccAddressSizeFault = 0b000000;
    static constexpr uint32_t kDccAccessFlagFault = 0b001000;
    static constexpr uint32_t kDccSynchronousExternalFault = 0b010000;

    if (report.context.arch.u.arm_64.esr & kEcDataAbortBit) {
      if (report.context.arch.u.arm_64.esr & kIssWrite &&
          !(report.context.arch.u.arm_64.esr & kIssCacheOp)) {
        access_type = "write";
      } else {
        access_type = "read";
      }
    } else {
      access_type = "execute";
    }

    switch ((report.context.arch.u.arm_64.esr & kDccNoLvlMask)) {
      case kDccPermissionFault:
        violation = "protection";
        break;
      case kDccTranslationFault:
        violation = "not-present";
        break;
      case kDccAddressSizeFault:
        violation = "address-size";
        break;
      case kDccAccessFlagFault:
        violation = "access-flag";
        break;
      case kDccSynchronousExternalFault:
        violation = "external-abort";
        break;
      default:
        violation = "undecoded";
        break;
    }
#elif defined(__riscv)
#else
#error unsupported architecture
#endif
    fprintf(out, "<== %s %s page fault (error %s), PC at 0x%" PRIxPTR "\n", access_type, violation,
            zx_status_get_string(static_cast<zx_status_t>(report.context.synth_code)), decoded.pc);
  } else if (report.header.type == ZX_EXCP_POLICY_ERROR) {
    switch (report.context.synth_code) {
      case ZX_EXCP_POLICY_CODE_BAD_SYSCALL:
        fprintf(out, "<== policy error: %s (%d, syscall %d), PC at 0x%" PRIxPTR "\n",
                inspector::policy_exception_code_to_str(report.context.synth_code),
                report.context.synth_code, report.context.synth_data, decoded.pc);
        break;

      default:
        fprintf(out, "<== policy error: %s (%d), PC at 0x%" PRIxPTR "\n",
                inspector::policy_exception_code_to_str(report.context.synth_code),
                report.context.synth_code, decoded.pc);
        break;
    }
  } else {
    fprintf(out, "<== %s, PC at 0x%" PRIxPTR "\n", inspector::excp_type_to_str(report.header.type),
            decoded.pc);
  }
}

}  // namespace inspector

__EXPORT void inspector_print_stack_trace(FILE* out, zx_handle_t process, zx_handle_t thread,
                                          const zx_thread_state_general_regs* regs) {
  inspector_dsoinfo_t* dso_list = inspector_dso_fetch_list(process);
  inspector_print_markup_context(out, process);

  inspector::decoded_registers decoded = inspector::decode_registers(regs);
  inspector_print_backtrace_markup(out, process, thread, dso_list, decoded.pc, decoded.sp,
                                   decoded.fp);
  inspector_dso_free_list(dso_list);
}

__EXPORT void inspector_print_debug_info(FILE* out, zx_handle_t process_handle,
                                         zx_handle_t thread_handle) {
  zx_status_t status;
  // If the caller didn't supply |regs| use a local copy.
  zx_thread_state_general_regs_t regs;

  zx::unowned<zx::process> process(process_handle);
  zx_koid_t pid = inspector::get_koid(process->get());
  char process_name[ZX_MAX_NAME_LEN];
  inspector::get_name(process->get(), process_name, sizeof(process_name));

  zx::unowned<zx::thread> thread(thread_handle);
  zx_koid_t tid = inspector::get_koid(thread->get());
  char thread_name[ZX_MAX_NAME_LEN];
  inspector::get_name(thread->get(), thread_name, sizeof(thread_name));

  // Attempt to obtain the registers. If this fails, it means that the thread wasn't provided in a
  // valid state.
  status = inspector_read_general_regs(thread->get(), &regs);
  if (status != ZX_OK) {
    printf("[Process %s, Thread %s] Could not get general registers: %s.\n", process_name,
           thread_name, zx_status_get_string(status));
    return;
  }
  inspector::decoded_registers decoded = inspector::decode_registers(&regs);

  // Backtrace requests are special software breakpoints that get resumed. They need to be clearly
  // differentiable from other exceptions.
  bool backtrace_requested = false;

  // Check if the process is on an exception.
  zx_exception_report_t report;
  if (thread->get_info(ZX_INFO_THREAD_EXCEPTION_REPORT, &report, sizeof(report), nullptr,
                       nullptr) == ZX_OK) {
    // The thread is in a valid exception state.
    if (!ZX_EXCP_IS_ARCH(report.header.type) && report.header.type != ZX_EXCP_POLICY_ERROR) {
      return;
    }

    backtrace_requested = is_backtrace_request(report.header.type, &regs);
    if (backtrace_requested) {
      fprintf(out, "<== BACKTRACE REQUEST: process %s[%" PRIu64 "] thread %s[%" PRIu64 "]\n",
              process_name, pid, thread_name, tid);
    } else {
      // Normal exception.
      fprintf(out, "<== CRASH: process %s[%" PRIu64 "] thread %s[%" PRIu64 "]\n", process_name, pid,
              thread_name, tid);
      inspector::print_exception_report(out, report, &regs);

#if defined(__x86_64__)
      inspector_print_general_regs(out, &regs, &report.context.arch.u.x86_64);
#elif defined(__aarch64__)
      inspector_print_general_regs(out, &regs, &report.context.arch.u.arm_64);

      // Only output the Fault address register and ESR if there's a data or
      // alignment fault.
      if (ZX_EXCP_FATAL_PAGE_FAULT == report.header.type ||
          ZX_EXCP_UNALIGNED_ACCESS == report.header.type) {
        fprintf(out, " far %#18" PRIx64 " esr %#18x\n", report.context.arch.u.arm_64.far,
                report.context.arch.u.arm_64.esr);
      }
#elif defined(__riscv)
#else
#error unsupported architecture
#endif
    }
  } else {
    // The thread is suspended so we can safely print the stack trace.
    fprintf(out, "<== process %s[%" PRIu64 "] thread %s[%" PRIu64 "]\n", process_name, pid,
            thread_name, tid);
    fprintf(out, "<== PC at 0x%" PRIxPTR "\n", decoded.pc);
    inspector_print_general_regs(out, &regs, nullptr);
  }

  if (!backtrace_requested) {
    // Print the common stack part of the thread.
    fprintf(out, "bottom of user stack:\n");
    inspector_print_memory(out, process->get(), decoded.sp, inspector::kMemoryDumpSize);

    fprintf(out, "arch: %s\n", inspector::kArch);
  }

  inspector_print_stack_trace(out, process->get(), thread->get(), &regs);

  if (inspector::verbosity_level >= 1)
    printf("Done handling thread %" PRIu64 ".%" PRIu64 ".\n", pid, tid);
}

// The approach of |inspector_print_debug_info_for_all_threads| is to suspend the process, obtain
// all threads, go over the ones in an exception first and print them and only then print all the
// other threads. This permits to have a clearer view between logs and the crash report.
__EXPORT void inspector_print_debug_info_for_all_threads(FILE* out, zx_handle_t process_handle) {
  zx_status_t status = ZX_ERR_NOT_SUPPORTED;

  zx::unowned<zx::process> process(process_handle);
  char process_name[ZX_MAX_NAME_LEN];
  inspector::get_name(process->get(), process_name, sizeof(process_name));
  zx_koid_t process_koid = inspector::get_koid(process->get());

  // Suspend the process so that each thread is suspended and no more threads get spawned.
  // NOTE: A process cannot suspend itself, so this could fail on some environments (like calling
  //       this function on your process). To support that usecase, this logic will also try to
  //       suspend each thread individually.
  //
  //       The advantages of suspending the process vs each thread individually are:
  //       1. Threads get suspended at a single point in time, which gives a more accurate
  //          representation of what the process is doing at the moment of printing.
  //       2. When a process is suspended, no more threads will be spawned.
  zx::suspend_token process_suspend_token;
  status = process->suspend(&process_suspend_token);
  if (status != ZX_OK) {
    printf("[Process %s (%" PRIu64 ")] Could not suspend process: %s. Continuing anyway.\n ",
           process_name, process_koid, zx_status_get_string(status));
  }

  // Get the thread list.
  // NOTE: This could be skipping threads being created at the moment of this call.
  //       This is an inherent race between suspending a process and a thread being created.
  size_t actual, avail;
  // This is an outrageous amount of threads to output. We mark them all as invalid first.
  constexpr size_t kMaxThreadHandles = 128;
  std::vector<zx_koid_t> thread_koids(kMaxThreadHandles);
  status = process->get_info(ZX_INFO_PROCESS_THREADS, thread_koids.data(),
                             thread_koids.size() * sizeof(zx_koid_t), &actual, &avail);
  if (status != ZX_OK) {
    printf("[Process %s (%" PRIu64 ")] Could not get list of threads: %s.\n", process_name,
           process_koid, zx_status_get_string(status));
    return;
  }

  std::vector<zx::thread> thread_handles(actual);
  std::vector<std::string> thread_names(actual);
  std::vector<zx_info_thread_t> thread_infos(actual);

  // Get the thread associated data.
  for (size_t i = 0; i < actual; i++) {
    // Get the handles.
    zx::thread& child = thread_handles[i];
    status = process->get_child(thread_koids[i], ZX_RIGHT_SAME_RIGHTS, &child);
    if (status != ZX_OK) {
      printf("[Process %s (%" PRIu64 ")] Could not obtain thread handle: %s.\n", process_name,
             process_koid, zx_status_get_string(status));
      continue;
    }

    // Get the name.
    char thread_name[ZX_MAX_NAME_LEN];
    inspector::get_name(child.get(), thread_name, sizeof(thread_name));
    thread_names[i] = thread_name;

    // Get the thread infos.
    zx_info_thread_t thread_info = {};
    status = child.get_info(ZX_INFO_THREAD, &thread_info, sizeof(thread_info), nullptr, nullptr);
    if (status != ZX_OK) {
      printf("[Process %s (%" PRIu64 "), Thread %s (%" PRIu64 ")] Could not obtain info: %s\n",
             process_name, process_koid, thread_names[i].c_str(), thread_koids[i],
             zx_status_get_string(status));
      continue;
    }

    thread_infos[i] = std::move(thread_info);
  }

  // Print the threads in an exception first.
  for (size_t i = 0; i < actual; i++) {
    zx::thread& child = thread_handles[i];
    if (!child.is_valid())
      continue;

    // If the thread is not in an exception, it will be printed on the next loop.
    if (thread_infos[i].state != ZX_THREAD_STATE_BLOCKED_EXCEPTION)
      continue;

    // We print the thread and then mark this koid as empty, so that it won't be printed on the
    // suspended pass. This means we can free the handle after this.
    inspector_print_debug_info(out, process->get(), child.get());
    thread_handles[i].reset();
  }

  // Go over each thread and print them.
  for (size_t i = 0; i < actual; i++) {
    if (!thread_handles[i].is_valid())
      continue;

    // If the thread is in an exception, it was already printed by the previous loop.
    if (thread_infos[i].state == ZX_THREAD_STATE_BLOCKED_EXCEPTION) {
      continue;
    }

    zx::thread& child = thread_handles[i];

    // Wait for the thread to be suspended.
    // We do this regardless of the process suspension. There are legitimate cases where the process
    // suspension would fail, like trying to suspend one's own process. If the process suspension
    // was successful, this is a no-op.
    zx::suspend_token suspend_token;
    status = child.suspend(&suspend_token);
    if (status != ZX_OK) {
      printf("[Process %s (%" PRIu64 "), Thread %s (%" PRIu64 ")] Could not suspend thread: %s.\n",
             process_name, process_koid, thread_names[i].c_str(), thread_koids[i],
             zx_status_get_string(status));
      continue;
    }

    status = child.wait_one(ZX_THREAD_SUSPENDED, zx::deadline_after(zx::msec(100)), nullptr);
    if (status != ZX_OK) {
      printf("[Process %s (%" PRIu64 "), Thread %s (%" PRIu64 ")] Didn't get suspend signal: %s.\n",
             process_name, process_koid, thread_names[i].c_str(), thread_koids[i],
             zx_status_get_string(status));
      continue;
    }

    // We can now print the thread.
    inspector_print_debug_info(out, process->get(), child.get());
  }
}
