// 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/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 "gwp-asan.h"
#include "src/lib/debug/backtrace-request-utils.h"

namespace {

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

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>";
  }
}

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";
    case ZX_EXCP_POLICY_CODE_PORT_TOO_MANY_OBSERVERS:
      return "PORT_TOO_MANY_OBSERVERS";
    default:
      return "<unknown policy code>";
  }
}

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

decoded_registers_t decode_registers(const zx_thread_state_general_regs_t* regs) {
  decoded_registers_t 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)
  decoded.pc = regs->pc;
  decoded.sp = regs->sp;
  decoded.fp = regs->s0;
#else
#error unsupported architecture
#endif

  return decoded;
}

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

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;
}

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);
  }
}

void print_exception_report(FILE* out, const zx_exception_report_t& report,
                            const zx_thread_state_general_regs_t* regs,
                            const inspector_excp_data_t* excp_data) {
  decoded_registers_t decoded = decode_registers(regs);

  if (report.header.type == ZX_EXCP_FATAL_PAGE_FAULT) {
    const char* access_type;
    const char* violation;
    zx_vaddr_t fault_addr;
#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";
    }
    fault_addr = excp_data->cr2;
#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;
    }

    fault_addr = excp_data->far;
#elif defined(__riscv)
    static constexpr uint32_t RISCV64_EXCEPTION_INS_PAGE_FAULT = 12;
    static constexpr uint32_t RISCV64_EXCEPTION_LOAD_PAGE_FAULT = 13;
    static constexpr uint32_t RISCV64_EXCEPTION_STORE_PAGE_FAULT = 15;

    switch (report.context.arch.u.riscv_64.cause) {
      case RISCV64_EXCEPTION_INS_PAGE_FAULT:
        access_type = "execute";
        violation = "not-present";
        break;
      case RISCV64_EXCEPTION_LOAD_PAGE_FAULT:
        access_type = "read";
        violation = "not-present";
        break;
      case RISCV64_EXCEPTION_STORE_PAGE_FAULT:
        access_type = "write";
        violation = "not-present";
        break;
      default:
        access_type = "unknown";
    }
    switch (static_cast<zx_status_t>(report.context.synth_code)) {
      case ZX_ERR_NOT_FOUND:
        violation = "not-present";
        break;
      case ZX_ERR_ACCESS_DENIED:
        violation = "protection";
        break;
      default:
        violation = "unknown";
    }
    fault_addr = report.context.arch.u.riscv_64.tval;
#else
#error unsupported architecture
#endif
    fprintf(out, "<== %s %s page fault (error %s) at %#" PRIxPTR ", PC at %#" PRIxPTR "\n",
            access_type, violation,
            zx_status_get_string(static_cast<zx_status_t>(report.context.synth_code)), fault_addr,
            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 %#" PRIxPTR "\n",
                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 %#" PRIxPTR "\n",
                policy_exception_code_to_str(report.context.synth_code), report.context.synth_code,
                decoded.pc);
        break;
    }
  } else {
    fprintf(out, "<== %s, PC at %#" PRIxPTR "\n", excp_type_to_str(report.header.type), decoded.pc);
  }
}

// Print the GWP-ASan information if the thread is on a GWP-ASan exception. Do nothing otherwise.
// The process and the thread must be readable.
void print_gwp_asan_info(FILE* out, const zx::process& process,
                         const zx_exception_report_t& exception_report) {
  inspector::GwpAsanInfo info;
  if (inspector_get_gwp_asan_info(process, exception_report, &info) && info.error_type) {
    fprintf(out, "GWP-ASan Error: %s at %#lx\n", info.error_type, info.faulting_addr);
    fprintf(out, "Allocated at %lu with size %lu here:\n", info.allocation_address,
            info.allocation_size);
    for (size_t i = 0; i < info.allocation_trace.size(); i++) {
      fprintf(out, "{{{bt:%lu:%#lx}}}\n", i, info.allocation_trace[i]);
    }
    if (!info.deallocation_trace.empty()) {
      fprintf(out, "Freed here:\n");
      for (size_t i = 0; i < info.deallocation_trace.size(); i++) {
        fprintf(out, "{{{bt:%lu:%#lx}}}\n", i, info.deallocation_trace[i]);
      }
    }
  }
}

// |skip_markup_context| avoids printing dso list repeatedly for multiple threads in a process.
void inspector_print_debug_info_impl(FILE* out, zx_handle_t process_handle,
                                     zx_handle_t thread_handle, bool skip_markup_context) {
  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 = get_koid(process->get());
  char process_name[ZX_MAX_NAME_LEN];
  get_name(process->get(), process_name, sizeof(process_name));

  zx::unowned<zx::thread> thread(thread_handle);
  zx_koid_t tid = get_koid(thread->get());
  char thread_name[ZX_MAX_NAME_LEN];
  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;
  }
  decoded_registers_t decoded = 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 thread is on an exception.
  zx_exception_report_t report;
  bool on_exception = false;
  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;
    }

    on_exception = true;
    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);

#if defined(__x86_64__)
      inspector_excp_data_t* excp_data = &report.context.arch.u.x86_64;
#elif defined(__aarch64__)
      inspector_excp_data_t* excp_data = &report.context.arch.u.arm_64;
#elif defined(__riscv)
      inspector_excp_data_t* excp_data = &report.context.arch.u.riscv_64;
#else
#error unsupported architecture
#endif

      print_exception_report(out, report, &regs, excp_data);
      inspector_print_general_regs(out, &regs, excp_data);
      // Print the common stack part of the thread.
      fprintf(out, "bottom of user stack:\n");
      inspector_print_memory(out, process->get(), decoded.sp, kMemoryDumpSize,
                             inspector_print_memory_format::Hex32);

      // Print the bytes "around" the PC to assist in debugging "undefined instruction" exceptions
      // or other cases where it's helpful to know what instruction was executed.
      fprintf(out, "memory dump near pc:\n");
      // Try to capture bytes before and after the PC to ensure we get the full instruction.  Round
      // down to the nearest multiple of 16, then back it up by 32.
      zx_vaddr_t dumpAddr = decoded.pc & ~static_cast<zx_vaddr_t>(16);
      if (dumpAddr >= 32) {
        dumpAddr -= 32;
      }
      constexpr size_t kPcDumpSize = 64;
      inspector_print_memory(out, process->get(), dumpAddr, kPcDumpSize,
                             inspector_print_memory_format::Hex8);

      fprintf(out, "arch: %s\n", kArch);
    }
  } else {
    // Print minimal information for threads not on an exception, e.g., other threads in a backtrace
    // request.
    fprintf(out, "<== process %s[%" PRIu64 "] thread %s[%" PRIu64 "]\n", process_name, pid,
            thread_name, tid);
  }

  if (!skip_markup_context)
    inspector_print_markup_context(out, process->get());

  inspector_print_backtrace_markup(out, process->get(), thread->get());

  if (on_exception)
    print_gwp_asan_info(out, *process, report);
}

}  // namespace

__EXPORT void inspector_print_debug_info(FILE* out, zx_handle_t process_handle,
                                         zx_handle_t thread_handle) {
  fprintf(out, "{{{reset:begin}}}\n");
  inspector_print_debug_info_impl(out, process_handle, thread_handle, false);
  fprintf(out, "{{{reset:end}}}\n");
}

// 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];
  get_name(process->get(), process_name, sizeof(process_name));
  zx_koid_t process_koid = 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];
    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);
  }

  // Ensure only the first thread has markup context printed.
  bool skip_markup_context = false;

  fprintf(out, "{{{reset:begin}}}\n");

  // 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_impl(out, process->get(), child.get(), skip_markup_context);
    skip_markup_context = true;
    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_impl(out, process->get(), child.get(), skip_markup_context);
    skip_markup_context = true;
  }

  // Print one last reset to clear all symbolizer contextual state for the process.
  fprintf(out, "{{{reset:end}}}\n");
}
