// 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 <assert.h>
#include <inttypes.h>
#include <lib/backtrace-request/backtrace-request.h>
#include <lib/zx/exception.h>
#include <lib/zx/thread.h>
#include <link.h>
#include <stdlib.h>
#include <string.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/debug.h>
#include <zircon/syscalls/exception.h>
#include <zircon/syscalls/object.h>
#include <zircon/syscalls/port.h>
#include <zircon/threads.h>

#include <atomic>

#include <test-utils/test-utils.h>
#include <zxtest/zxtest.h>

#include "crash-and-recover.h"
#include "debugger.h"
#include "inferior-control.h"
#include "inferior.h"
#include "utils.h"

namespace {

// These are "call-saved" registers used in the test.
#if defined(__x86_64__)
#define REG_ACCESS_TEST_REG r15
#define REG_ACCESS_TEST_REG_NAME "r15"
#elif defined(__aarch64__)
#define REG_ACCESS_TEST_REG r[28]
#define REG_ACCESS_TEST_REG_NAME "x28"
#endif

// Note: Neither of these can be zero.
const uint64_t reg_access_initial_value = 0xee112233445566eeull;
const uint64_t reg_access_write_test_value = 0xee665544332211eeull;

struct suspended_reg_access_arg_t {
  zx_handle_t channel;
  uint64_t initial_value;
  uint64_t result;
  uint64_t pc, sp;
};

int reg_access_thread_func(void* arg_) {
  auto arg = reinterpret_cast<suspended_reg_access_arg_t*>(arg_);

  send_simple_response(arg->channel, RESP_PONG);

  // The loop has to be written in assembler as we cannot control what
  // the compiler does with our "reserved" registers outside of the asm;
  // they're not really reserved in the way we need them to be: the compiler
  // is free to do with them whatever it wants outside of the assembler.
  // We do make the assumption that test_reg will not contain
  // |reg_access_initial_value| until it is set by the assembler.

  uint64_t initial_value = arg->initial_value;
  uint64_t result = 0;
  uint64_t pc = 0;
  uint64_t sp = 0;

// The maximum number of bytes in the assembly.
// This doesn't have to be perfect. It's used to verify the value read for
// $pc is within some reasonable range.
#define REG_ACCESS_MAX_LOOP_SIZE 64

#ifdef __x86_64__
  __asm__(
      "\
        lea .(%%rip), %[pc]\n\
        mov %%rsp, %[sp]\n\
        mov %[initial_value], %%" REG_ACCESS_TEST_REG_NAME
      "\n\
      2:\n\
        pause\n\
        cmp %[initial_value], %%" REG_ACCESS_TEST_REG_NAME
      "\n\
        je 2b\n\
        mov %%" REG_ACCESS_TEST_REG_NAME ", %[result]"
      : [result] "=r"(result), [pc] "=&r"(pc), [sp] "=&r"(sp)
      : [initial_value] "r"(initial_value)
      : REG_ACCESS_TEST_REG_NAME);
#endif

#ifdef __aarch64__
  __asm__(
      "\
        adr %[pc], .\n\
        mov %[sp], sp\n\
        mov " REG_ACCESS_TEST_REG_NAME
      ", %[initial_value]\n\
      1:\n\
        yield\n\
        cmp %[initial_value], " REG_ACCESS_TEST_REG_NAME
      "\n\
        b.eq 1b\n\
        mov %[result], " REG_ACCESS_TEST_REG_NAME
      : [result] "=r"(result), [pc] "=&r"(pc), [sp] "=&r"(sp)
      : [initial_value] "r"(initial_value)
      : REG_ACCESS_TEST_REG_NAME);
#endif

  arg->result = result;
  arg->pc = pc;
  arg->sp = sp;

  zx_handle_close(arg->channel);

  return 0;
}

TEST(SuspendedTests, SuspendedRegAccessTest) {
  zx_handle_t self_proc = zx_process_self();

  thrd_t thread_c11;
  suspended_reg_access_arg_t arg = {};
  arg.initial_value = reg_access_initial_value;
  zx_handle_t channel;
  ASSERT_EQ(zx_channel_create(0, &channel, &arg.channel), ZX_OK);
  int ret = thrd_create_with_name(&thread_c11, reg_access_thread_func, &arg, "reg-access thread");
  ASSERT_EQ(ret, thrd_success);
  // Get our own copy of the thread handle to avoid lifetime issues of
  // thrd's copy.
  zx_handle_t thread = ZX_HANDLE_INVALID;
  ASSERT_EQ(zx_handle_duplicate(thrd_get_zx_handle(thread_c11), ZX_RIGHT_SAME_RIGHTS, &thread),
            ZX_OK);

  // KISS: Don't attach until the thread is up and running so we don't see
  // ZX_EXCP_THREAD_STARTING.
  recv_simple_response(channel, RESP_PONG);

  zx_handle_t port = ZX_HANDLE_INVALID;
  EXPECT_EQ(zx_port_create(0, &port), ZX_OK);

  // Keep looping until we know the thread is stopped in the assembler.
  // This is the only place we can guarantee particular registers have
  // particular values.
  zx_handle_t suspend_token = ZX_HANDLE_INVALID;
  zx_thread_state_general_regs_t regs;
  uint64_t test_reg = 0;
  while (true) {
    zx_nanosleep(zx_deadline_after(ZX_USEC(1)));
    ASSERT_EQ(zx_task_suspend_token(thread, &suspend_token), ZX_OK);
    ASSERT_NO_FATAL_FAILURE(wait_thread_state(self_proc, thread, port, ZX_THREAD_SUSPENDED));

    read_inferior_gregs(thread, &regs);
    test_reg = regs.REG_ACCESS_TEST_REG;

    if (test_reg == reg_access_initial_value)
      break;  // Keep thread suspended.

    // Resume and try again. Wait for the thread to actually resume before trying again to avoid
    // race conditions on notifications about thread state transitions.
    zx_handle_close(suspend_token);
    ASSERT_NO_FATAL_FAILURE(wait_thread_state(self_proc, thread, port, ZX_THREAD_RUNNING));
  }

  uint64_t pc_value = extract_pc_reg(&regs);
  uint64_t sp_value = extract_sp_reg(&regs);
  regs.REG_ACCESS_TEST_REG = reg_access_write_test_value;
  write_inferior_gregs(thread, &regs);

  ASSERT_EQ(zx_handle_close(suspend_token), ZX_OK);
  thrd_join(thread_c11, NULL);
  zx_handle_close(thread);

  // We can't test the pc value exactly as we don't know on which instruction
  // the thread will be suspended. But we can verify it is within some
  // minimal range.
  EXPECT_GE(pc_value, arg.pc);
  EXPECT_LE(pc_value, arg.pc + REG_ACCESS_MAX_LOOP_SIZE);

  EXPECT_EQ(sp_value, arg.sp);

  EXPECT_EQ(reg_access_write_test_value, arg.result);

  zx_handle_close(channel);
  zx_handle_close(port);
}

struct suspended_in_syscall_reg_access_arg_t {
  bool do_channel_call;
  zx_handle_t syscall_handle;
  std::atomic<uintptr_t> sp;
};

// "zx_channel_call treats the leading bytes of the payload as
// a transaction id of type zx_txid_t"
static_assert(sizeof(zx_txid_t) == sizeof(uint32_t), "");
#define CHANNEL_CALL_PACKET_SIZE (sizeof(zx_txid_t) + sizeof("x"))

// A helper function for |suspended_in_syscall_reg_access_thread_func()|
// so we can use ASSERT_*/EXPECT_*.

void suspended_in_syscall_reg_access_thread_func_helper(
    suspended_in_syscall_reg_access_arg_t* arg) {
  if (arg->do_channel_call) {
    uint8_t send_buf[CHANNEL_CALL_PACKET_SIZE] = "TXIDx";
    uint8_t recv_buf[CHANNEL_CALL_PACKET_SIZE];
    uint32_t actual_bytes, actual_handles;
    zx_channel_call_args_t call_args = {
        .wr_bytes = send_buf,
        .wr_handles = NULL,
        .rd_bytes = recv_buf,
        .rd_handles = NULL,
        .wr_num_bytes = sizeof(send_buf),
        .wr_num_handles = 0,
        .rd_num_bytes = sizeof(recv_buf),
        .rd_num_handles = 0,
    };
    zx_status_t call_status = zx_channel_call(arg->syscall_handle, 0, ZX_TIME_INFINITE, &call_args,
                                              &actual_bytes, &actual_handles);
    ASSERT_EQ(call_status, ZX_OK);
    EXPECT_EQ(actual_bytes, sizeof(recv_buf));
    EXPECT_EQ(memcmp(recv_buf + sizeof(zx_txid_t), "y", sizeof(recv_buf) - sizeof(zx_txid_t)), 0);
  } else {
    zx_signals_t pending;
    zx_status_t status =
        zx_object_wait_one(arg->syscall_handle, ZX_EVENT_SIGNALED, ZX_TIME_INFINITE, &pending);
    ASSERT_EQ(status, ZX_OK);
    ASSERT_NE((pending & ZX_EVENT_SIGNALED), 0u);
  }
}

void* suspended_in_syscall_reg_access_thread_func(void* arg_) {
  auto arg = reinterpret_cast<suspended_in_syscall_reg_access_arg_t*>(arg_);

  uint64_t sp;
#ifdef __x86_64__
  __asm__(
      "\
        mov %%rsp, %[sp]"
      : [sp] "=r"(sp));
#endif
#ifdef __aarch64__
  __asm__(
      "\
        mov %[sp], sp"
      : [sp] "=r"(sp));
#endif
  arg->sp.store(sp);

  suspended_in_syscall_reg_access_thread_func_helper(arg);
  if (CURRENT_TEST_HAS_FATAL_FAILURE()) {
    return reinterpret_cast<void*>((uintptr_t)-1);
  }

  return nullptr;
}

// Channel calls are a little special in that they are a two part syscall,
// with suspension possible in between the two parts.
// If |do_channel_call| is true, test zx_channel_call. Otherwise test some
// random syscall that can block, here we use zx_object_wait_one.
//
// The syscall entry point is the vdso, there's no bypassing this for test
// purposes. Also, the kernel doesn't save userspace regs on entry, it only
// saves them later if it needs to - at which point many don't necessarily
// have any useful value. Putting these together means we can't easily test
// random integer registers: there's no guarantee any value we set in the test
// will be available when the syscall is suspended. All is not lost, we can
// still at least test that reading $pc, $sp work.

void suspended_in_syscall_reg_access_worker(bool do_channel_call) {
  zx_handle_t self_proc = zx_process_self();

  uintptr_t vdso_start = 0, vdso_end = 0;
  get_vdso_exec_range(&vdso_start, &vdso_end);

  suspended_in_syscall_reg_access_arg_t arg = {};
  arg.do_channel_call = do_channel_call;

  zx_handle_t syscall_handle;
  if (do_channel_call) {
    ASSERT_EQ(zx_channel_create(0, &arg.syscall_handle, &syscall_handle), ZX_OK);
  } else {
    ASSERT_EQ(zx_event_create(0u, &syscall_handle), ZX_OK);
    arg.syscall_handle = syscall_handle;
  }

  // We use pthread attrs to get the size of the created stack.
  pthread_attr_t pthread_attrs;
  int ret = pthread_attr_init(&pthread_attrs);
  ASSERT_EQ(ret, 0);

  pthread_t thread_pthread;
  ret = pthread_create(&thread_pthread, &pthread_attrs, suspended_in_syscall_reg_access_thread_func,
                       &arg);
  ASSERT_EQ(ret, 0);

  // Get our own copy of the thread handle to avoid lifetime issues of
  // thrd's copy.
  zx_handle_t thread = ZX_HANDLE_INVALID;
  ASSERT_EQ(zx_handle_duplicate(thrd_get_zx_handle(static_cast<thrd_t>(thread_pthread)),
                                ZX_RIGHT_SAME_RIGHTS, &thread),
            ZX_OK);

  // Busy-wait until thread is blocked inside the syscall.
  zx_info_thread_t thread_info;
  uint32_t expected_blocked_reason =
      do_channel_call ? ZX_THREAD_STATE_BLOCKED_CHANNEL : ZX_THREAD_STATE_BLOCKED_WAIT_ONE;
  do {
    // Don't check too frequently here as it can blow up tracing output
    // when debugging with kernel tracing turned on.
    zx_nanosleep(zx_deadline_after(ZX_USEC(100)));
    zx_status_t status = zx_object_get_info(thread, ZX_INFO_THREAD, &thread_info,
                                            sizeof(thread_info), nullptr, nullptr);
    ASSERT_EQ(status, ZX_OK);
  } while (thread_info.state != expected_blocked_reason);
  ASSERT_EQ(thread_info.wait_exception_channel_type, ZX_EXCEPTION_CHANNEL_TYPE_NONE);

  // Extra sanity check for channels.
  if (do_channel_call) {
    EXPECT_TRUE(tu_channel_wait_readable(syscall_handle));
  }

  zx_handle_t port = ZX_HANDLE_INVALID;
  EXPECT_EQ(zx_port_create(0, &port), ZX_OK);

  zx_handle_t token;
  ASSERT_EQ(zx_task_suspend_token(thread, &token), ZX_OK);
  ASSERT_NO_FATAL_FAILURE(wait_thread_state(self_proc, thread, port, ZX_THREAD_SUSPENDED));

  zx_thread_state_general_regs_t regs;
  read_inferior_gregs(thread, &regs);

  // Verify the pc is somewhere within the vdso.
  uint64_t pc_value = extract_pc_reg(&regs);
  EXPECT_GE(pc_value, vdso_start);
  EXPECT_LE(pc_value, vdso_end);

  // The stack pointer is somewhere within the syscall.
  // Just verify the value we have is within range.

  // First, get the size of the stack. We'll use this to compute an
  // approximate bound on the stack.
  size_t stack_size;
  ret = pthread_attr_getstacksize(&pthread_attrs, &stack_size);
  ASSERT_EQ(ret, 0);

  // The current value of the stack pointer, while in the vdso.
  uint64_t vdso_sp = extract_sp_reg(&regs);
  // The originally snapshotted value of the stack pointer.
  uint64_t arg_sp = arg.sp.load();
  // Stacks grow down, so the pointer while in the vdso should be
  // below the pointer originally snapshotted.
  EXPECT_LE(vdso_sp, arg_sp);

  // Check that both vdso_sp is within |stack_size| of the arg_sp value.
  EXPECT_LT(arg_sp, vdso_sp + stack_size);

  // wake the thread
  if (do_channel_call) {
    uint8_t buf[CHANNEL_CALL_PACKET_SIZE];
    uint32_t actual_bytes;
    ASSERT_EQ(zx_channel_read(syscall_handle, 0, buf, NULL, sizeof(buf), 0, &actual_bytes, NULL),
              ZX_OK);
    EXPECT_EQ(actual_bytes, sizeof(buf));
    EXPECT_EQ(memcmp(buf + sizeof(zx_txid_t), "x", sizeof(buf) - sizeof(zx_txid_t)), 0);

    // write a reply
    buf[sizeof(zx_txid_t)] = 'y';
    ASSERT_EQ(zx_channel_write(syscall_handle, 0, buf, sizeof(buf), NULL, 0), ZX_OK);

    // Make sure the remote channel didn't get signaled
    EXPECT_EQ(zx_object_wait_one(arg.syscall_handle, ZX_CHANNEL_READABLE, 0, NULL),
              ZX_ERR_TIMED_OUT);

    // Make sure we can't read from the remote channel (the message should have
    // been reserved for the other thread, even though it is suspended).
    EXPECT_EQ(
        zx_channel_read(arg.syscall_handle, 0, buf, NULL, sizeof(buf), 0, &actual_bytes, NULL),
        ZX_ERR_SHOULD_WAIT);
  } else {
    ASSERT_EQ(zx_object_signal(syscall_handle, 0u, ZX_EVENT_SIGNALED), ZX_OK);
  }

  ASSERT_EQ(zx_handle_close(token), ZX_OK);
  void* thread_result;
  EXPECT_EQ(pthread_join(thread_pthread, &thread_result), 0);
  EXPECT_NULL(thread_result);
  zx_handle_close(thread);

  zx_handle_close(port);
  if (do_channel_call) {
    zx_handle_close(arg.syscall_handle);
  }
  zx_handle_close(syscall_handle);
}

TEST(SuspendedTests, SuspendedInSyscallRegAccessTest) {
  suspended_in_syscall_reg_access_worker(false);
}

TEST(SuspendedTests, SuspendedInChannelCallRegAccessTest) {
  suspended_in_syscall_reg_access_worker(true);
}

struct suspend_in_exception_data_t {
  std::atomic<int> segv_count;
  std::atomic<int> suspend_count;
  std::atomic<int> resume_count;
  zx_handle_t thread_handle;
  zx_handle_t suspend_token;
  zx_koid_t process_id;
  zx_koid_t thread_id;
};

// N.B. This runs on the wait-inferior thread.

void suspended_in_exception_handler(inferior_data_t* data, const zx_port_packet_t* packet,
                                    void* handler_arg) {
  auto suspend_data = reinterpret_cast<suspend_in_exception_data_t*>(handler_arg);

  zx_info_handle_basic_t basic_info;
  zx_status_t status = zx_object_get_info(data->exception_channel, ZX_INFO_HANDLE_BASIC,
                                          &basic_info, sizeof(basic_info), nullptr, nullptr);
  ASSERT_EQ(status, ZX_OK);
  zx_koid_t exception_channel_koid = basic_info.koid;

  if (packet->key != exception_channel_koid) {
    // Must be a signal on one of the threads.
    ASSERT_TRUE(packet->key != suspend_data->process_id);
    zx_koid_t pkt_tid = packet->key;

    // The following signals are expected here.  Note that
    // ZX_THREAD_RUNNING and ZX_THREAD_TERMINATED can be reported
    // together in the same zx_port_packet_t.
    if (packet->signal.observed & ZX_THREAD_TERMINATED) {
      // Nothing to do.
    }
    if (packet->signal.observed & ZX_THREAD_RUNNING) {
      ASSERT_EQ(pkt_tid, suspend_data->thread_id);
      atomic_fetch_add(&suspend_data->resume_count, 1);
    }
    if (packet->signal.observed & ZX_THREAD_SUSPENDED) {
      ASSERT_EQ(pkt_tid, suspend_data->thread_id);
      atomic_fetch_add(&suspend_data->suspend_count, 1);
      ASSERT_EQ(zx_handle_close(suspend_data->suspend_token), ZX_OK);
      // At this point we should get ZX_THREAD_RUNNING, we'll
      // process it later.
    }
  } else {
    zx::exception exception;
    zx_exception_info_t info;
    uint32_t num_bytes = sizeof(info);
    uint32_t num_handles = 1;
    status = zx_channel_read(data->exception_channel, 0, &info, exception.reset_and_get_address(),
                             num_bytes, num_handles, nullptr, nullptr);
    ASSERT_EQ(status, ZX_OK);

    switch (info.type) {
      case ZX_EXCP_THREAD_EXITING:
        // N.B. We could get thread exiting messages from previous
        // tests.
        handle_thread_exiting(data->inferior, &info, std::move(exception));
        break;

      case ZX_EXCP_FATAL_PAGE_FAULT: {
        printf("wait-inf: got page fault exception\n");

        ASSERT_EQ(info.tid, suspend_data->thread_id);

        // Verify that the fault is at the PC we expected.
        ASSERT_NO_FATAL_FAILURE(test_segv_pc(suspend_data->thread_handle));

        // Suspend the thread before fixing the segv to verify register
        // access works while the thread is in an exception and suspended.
        ASSERT_EQ(zx_task_suspend_token(suspend_data->thread_handle, &suspend_data->suspend_token),
                  ZX_OK);

        // Waiting for the thread to suspend doesn't work here as the
        // thread stays in the exception until we pass ZX_RESUME_EXCEPTION.
        // Just give the scheduler a chance to run the thread and process
        // the ZX_ERR_INTERNAL_INTR_RETRY in ExceptionHandlerExchange.
        zx_nanosleep(zx_deadline_after(ZX_MSEC(1)));

        // Do some tests that require a suspended inferior.
        // This is required as the inferior does tests after it wakes up
        // that assumes we've done this.
        test_memory_ops(data->inferior, suspend_data->thread_handle);

        // Now correct the issue and resume the inferior.
        fix_inferior_segv(suspend_data->thread_handle);

        atomic_fetch_add(&suspend_data->segv_count, 1);

        uint32_t state = ZX_EXCEPTION_STATE_HANDLED;
        ASSERT_EQ(exception.set_property(ZX_PROP_EXCEPTION_STATE, &state, sizeof(state)), ZX_OK);
        // At this point we should get ZX_THREAD_SUSPENDED, we'll
        // process it later.

        break;
      }

      default: {
        ASSERT_TRUE(false, "unexpected exception type: 0x%x", info.type);
        __UNREACHABLE;
      }
    }
  }
}

TEST(SuspendedTests, SuspendedInExceptionRegAccessTest) {
  springboard_t* sb;
  zx_handle_t inferior, channel;
  ASSERT_NO_FATAL_FAILURE(setup_inferior(kTestInferiorChildName, &sb, &inferior, &channel));

  ASSERT_NO_FATAL_FAILURE(start_inferior(sb));
  ASSERT_NO_FATAL_FAILURE(verify_inferior_running(channel));

  suspend_in_exception_data_t data;
  data.segv_count.store(0);
  data.suspend_count.store(0);
  data.resume_count.store(0);
  ASSERT_NO_FATAL_FAILURE(get_inferior_thread_handle(channel, &data.thread_handle));

  zx_info_handle_basic_t basic_info;
  zx_status_t status = zx_object_get_info(inferior, ZX_INFO_HANDLE_BASIC, &basic_info,
                                          sizeof(basic_info), nullptr, nullptr);
  ASSERT_EQ(status, ZX_OK);
  zx_koid_t inferior_koid = basic_info.koid;

  status = zx_object_get_info(data.thread_handle, ZX_INFO_HANDLE_BASIC, &basic_info,
                              sizeof(basic_info), nullptr, nullptr);
  ASSERT_EQ(status, ZX_OK);
  zx_koid_t handle_koid = basic_info.koid;

  data.process_id = inferior_koid;
  data.thread_id = handle_koid;

  // Defer attaching until after the inferior is running to test
  // attach_inferior's recording of existing threads. If that fails
  // it won't see thread suspended/running messages from the thread.
  zx_handle_t port = ZX_HANDLE_INVALID;
  EXPECT_EQ(zx_port_create(0, &port), ZX_OK);
  size_t max_threads = 10;
  inferior_data_t* inferior_data = attach_inferior(inferior, port, max_threads);
  thrd_t wait_inf_thread =
      start_wait_inf_thread(inferior_data, suspended_in_exception_handler, &data);
  EXPECT_NE(port, ZX_HANDLE_INVALID);

  send_simple_request(channel, RQST_CRASH_AND_RECOVER_TEST);
  // wait_inf_thread will process the crash and resume the inferior.
  recv_simple_response(channel, RESP_RECOVERED_FROM_CRASH);

  ASSERT_NO_FATAL_FAILURE(shutdown_inferior(channel, inferior));

  // Stop the waiter thread before closing the port that it's waiting on.
  join_wait_inf_thread(wait_inf_thread);

  detach_inferior(inferior_data, true);

  // Don't check these until now to ensure the resume_count has been
  // updated (we're guaranteed that ZX_THREAD_RUNNING will be signalled
  // and processed before the waiter thread exits.
  EXPECT_EQ(data.segv_count.load(), kNumSegvTries);
  EXPECT_EQ(data.suspend_count.load(), kNumSegvTries);
  // There's an initial "RUNNING" signal that the handler could see,
  // or it might get delayed and essentially folded into a later one.
  // That is why we allow for potentially seeing an extra one here.
  EXPECT_TRUE(
      data.resume_count.load() == kNumSegvTries || data.resume_count.load() == kNumSegvTries + 1,
      "actual resume count: %d", data.resume_count.load());

  zx_handle_close(data.thread_handle);
  zx_handle_close(port);
  zx_handle_close(channel);
  zx_handle_close(inferior);
}

}  // namespace
