// 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 <err.h>
#include <kernel/stats.h>
#include <kernel/thread.h>
#include <lib/ktrace.h>
#include <lib/vdso.h>
#include <zircon/zx-syscall-numbers.h>
#include <object/process_dispatcher.h>
#include <platform.h>
#include <trace.h>

#include <inttypes.h>
#include <stdint.h>

#include "syscalls_priv.h"
#include "vdso-valid-sysret.h"

#define LOCAL_TRACE 0

int sys_invalid_syscall(uint64_t num, uint64_t pc,
                        uintptr_t vdso_code_address) {
    LTRACEF("invalid syscall %lu from PC %#lx vDSO code %#lx\n",
            num, pc, vdso_code_address);
    thread_signal_policy_exception();
    return ZX_ERR_BAD_SYSCALL;
}

inline uint64_t invoke_syscall(
    uint64_t syscall_num, uint64_t pc,
    uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4,
    uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8) {
    uint64_t ret;

    const uintptr_t vdso_code_address =
        ProcessDispatcher::GetCurrent()->vdso_code_address();
    const uint64_t pc_offset = pc - vdso_code_address;

#define CHECK_SYSCALL_PC(name)                                          \
    do {                                                                \
        if (unlikely(!VDso::ValidSyscallPC::name(pc_offset)))           \
            return sys_invalid_syscall(syscall_num, pc, vdso_code_address); \
    } while (0)

    switch (syscall_num) {
#include <zircon/syscall-invocation-cases.inc>
    default:
        return sys_invalid_syscall(syscall_num, pc, vdso_code_address);
    }

    return ret;
}

#if ARCH_ARM64
#include <arch/arm64.h>

// N.B. Interrupts must be disabled on entry and they will be disabled on exit.
// The reason is the two calls two arch_curr_cpu_num in the ktrace calls: we
// don't want the cpu changing during the call.

extern "C" void arm64_syscall(struct arm64_iframe_long* frame, bool is_64bit, uint64_t pc) {
    uint64_t syscall_num = frame->r[16];

    ktrace_tiny(TAG_SYSCALL_ENTER, ((uint32_t)syscall_num << 8) | arch_curr_cpu_num());

    CPU_STATS_INC(syscalls);

    /* re-enable interrupts to maintain kernel preemptiveness
       This must be done after the above ktrace_tiny call, and after the
       above CPU_STATS_INC call as it also calls arch_curr_cpu_num. */
    arch_enable_ints();

    LTRACEF_LEVEL(2, "num %" PRIu64 "\n", syscall_num);

    /* call the routine */
    uint64_t ret = invoke_syscall(
        syscall_num, pc,
        frame->r[0], frame->r[1], frame->r[2], frame->r[3],
        frame->r[4], frame->r[5], frame->r[6], frame->r[7]);

    LTRACEF_LEVEL(2, "ret %#" PRIx64 "\n", ret);

    /* put the return code back */
    frame->r[0] = ret;

    /* re-disable interrupts on the way out
       This must be done before the below ktrace_tiny call. */
    arch_disable_ints();

    ktrace_tiny(TAG_SYSCALL_EXIT, ((uint32_t)syscall_num << 8) | arch_curr_cpu_num());
}

#endif

#if ARCH_X86_64
#include <arch/x86.h>

// N.B. Interrupts must be disabled on entry and they will be disabled on exit.
// The reason is the two calls two arch_curr_cpu_num in the ktrace calls: we
// don't want the cpu changing during the call.

template <typename T>
inline x86_64_syscall_result do_syscall(uint64_t syscall_num, uint64_t ip,
                                        bool (*valid_pc)(uintptr_t), T make_call) {
    ktrace_tiny(TAG_SYSCALL_ENTER, (static_cast<uint32_t>(syscall_num) << 8) | arch_curr_cpu_num());

    CPU_STATS_INC(syscalls);

    /* re-enable interrupts to maintain kernel preemptiveness
       This must be done after the above ktrace_tiny call, and after the
       above CPU_STATS_INC call as it also calls arch_curr_cpu_num. */
    arch_enable_ints();

    LTRACEF_LEVEL(2, "t %p syscall num %" PRIu64 " ip %#" PRIx64 "\n",
                  get_current_thread(), syscall_num, ip);

    const uintptr_t vdso_code_address =
        ProcessDispatcher::GetCurrent()->vdso_code_address();

    uint64_t ret;
    if (unlikely(!valid_pc(ip - vdso_code_address))) {
        ret = sys_invalid_syscall(syscall_num, ip, vdso_code_address);
    } else {
        ret = make_call();
    }

    LTRACEF_LEVEL(2, "t %p ret %#" PRIx64 "\n", get_current_thread(), ret);

    /* re-disable interrupts on the way out
       This must be done before the below ktrace_tiny call. */
    arch_disable_ints();

    ktrace_tiny(TAG_SYSCALL_EXIT, (static_cast<uint32_t>(syscall_num << 8)) | arch_curr_cpu_num());

    // The assembler caller will re-disable interrupts at the appropriate time.
    return {ret, thread_is_signaled(get_current_thread())};
}

x86_64_syscall_result unknown_syscall(uint64_t syscall_num, uint64_t ip) {
    return do_syscall(syscall_num, ip,
                      [](uintptr_t) { return false; },
                      [&]() {
                          __builtin_unreachable();
                          return ZX_ERR_INTERNAL;
                      });
}

#endif

// Autogenerated per-syscall wrapper functions.
#include <zircon/syscall-kernel-wrappers.inc>
