// 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";
#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];
#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;
    const char* violation;
#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;
    }
#else
#error unsupported architecture
#endif
    fprintf(out, "<== %s %s page fault, PC at 0x%" PRIxPTR "\n", access_type, violation,
            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) {
  // Whether to use libunwind or not.
  // If not then we use a simple algorithm that assumes ABI-specific
  // frame pointers are present.
  const bool use_libunwind = true;

  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, use_libunwind);
  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);
      }
#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());
  }
}
