// 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 <inttypes.h>
#include <trace.h>

#include <kernel/mp.h>
#include <kernel/stats.h>
#include <vm/pmm.h>
#include <lib/heap.h>
#include <platform.h>
#include <zircon/types.h>

#include <object/diagnostics.h>
#include <object/handle.h>
#include <object/bus_transaction_initiator_dispatcher.h>
#include <object/job_dispatcher.h>
#include <object/process_dispatcher.h>
#include <object/resource_dispatcher.h>
#include <object/resources.h>
#include <object/socket_dispatcher.h>
#include <object/thread_dispatcher.h>
#include <object/vm_address_region_dispatcher.h>

#include <fbl/ref_ptr.h>

#include "priv.h"

#define LOCAL_TRACE 0

namespace {

// Gathers the koids of a job's descendants.
class SimpleJobEnumerator final : public JobEnumerator {
public:
    // If |job| is true, only records job koids; otherwise, only
    // records process koids.
    SimpleJobEnumerator(user_out_ptr<zx_koid_t> ptr, size_t max, bool jobs)
        : jobs_(jobs), ptr_(ptr), max_(max) {}

    size_t get_avail() const { return avail_; }
    size_t get_count() const { return count_; }

private:
    bool OnJob(JobDispatcher* job) override {
        if (!jobs_) {
            return true;
        }
        return RecordKoid(job->get_koid());
    }

    bool OnProcess(ProcessDispatcher* proc) override {
        if (jobs_) {
            return true;
        }
        return RecordKoid(proc->get_koid());
    }

    bool RecordKoid(zx_koid_t koid) {
        avail_++;
        if (count_ < max_) {
            // TODO: accumulate batches and do fewer user copies
            if (ptr_.copy_array_to_user(&koid, 1, count_) != ZX_OK) {
                return false;
            }
            count_++;
        }
        return true;
    }

    const bool jobs_;
    const user_out_ptr<zx_koid_t> ptr_;
    const size_t max_;

    size_t count_ = 0;
    size_t avail_ = 0;
};

zx_status_t single_record_result(user_out_ptr<void> _buffer, size_t buffer_size,
                                 user_out_ptr<size_t> _actual,
                                 user_out_ptr<size_t> _avail,
                                 void* record_data, size_t record_size) {
    size_t avail = 1;
    size_t actual;
    if (buffer_size >= record_size) {
        if (_buffer.copy_array_to_user(record_data, record_size) != ZX_OK)
            return ZX_ERR_INVALID_ARGS;
        actual = 1;
    } else {
        actual = 0;
    }
    if (_actual) {
        zx_status_t status = _actual.copy_to_user(actual);
        if (status != ZX_OK)
            return status;
    }
    if (_avail) {
        zx_status_t status = _avail.copy_to_user(avail);
        if (status != ZX_OK)
            return status;
    }
    if (actual == 0)
        return ZX_ERR_BUFFER_TOO_SMALL;
    return ZX_OK;
}

} // namespace

// actual is an optional return parameter for the number of records returned
// avail is an optional return parameter for the number of records available

// Topics which return a fixed number of records will return ZX_ERR_BUFFER_TOO_SMALL
// if there is not enough buffer space provided.
// This allows for zx_object_get_info(handle, topic, &info, sizeof(info), NULL, NULL)

zx_status_t sys_object_get_info(zx_handle_t handle, uint32_t topic,
                                user_out_ptr<void> _buffer, size_t buffer_size,
                                user_out_ptr<size_t> _actual, user_out_ptr<size_t> _avail) {
    LTRACEF("handle %x topic %u\n", handle, topic);

    ProcessDispatcher* up = ProcessDispatcher::GetCurrent();

    switch (topic) {
        case ZX_INFO_HANDLE_VALID: {
            return up->IsHandleValid(handle) ?  ZX_OK : ZX_ERR_BAD_HANDLE;
        }
        case ZX_INFO_HANDLE_BASIC: {
            // TODO(ZX-458): Handle forward/backward compatibility issues
            // with changes to the struct.

            fbl::RefPtr<Dispatcher> dispatcher;
            zx_rights_t rights;
            auto status = up->GetDispatcherAndRights(handle, &dispatcher, &rights);
            if (status != ZX_OK)
                return status;

            bool waitable = dispatcher->has_state_tracker();

            // build the info structure
            zx_info_handle_basic_t info = {
                .koid = dispatcher->get_koid(),
                .rights = rights,
                .type = dispatcher->get_type(),
                .related_koid = dispatcher->get_related_koid(),
                .props = waitable ? ZX_OBJ_PROP_WAITABLE : ZX_OBJ_PROP_NONE,
            };

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &info, sizeof(info));
        }
        case ZX_INFO_PROCESS: {
            // TODO(ZX-458): Handle forward/backward compatibility issues
            // with changes to the struct.

            // grab a reference to the dispatcher
            fbl::RefPtr<ProcessDispatcher> process;
            auto error = up->GetDispatcherWithRights(handle, ZX_RIGHT_READ, &process);
            if (error < 0)
                return error;

            // build the info structure
            zx_info_process_t info = { };

            auto err = process->GetInfo(&info);
            if (err != ZX_OK)
                return err;

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &info, sizeof(info));
        }
        case ZX_INFO_PROCESS_THREADS: {
            // grab a reference to the dispatcher
            fbl::RefPtr<ProcessDispatcher> process;
            auto error = up->GetDispatcherWithRights(handle, ZX_RIGHT_ENUMERATE, &process);
            if (error < 0)
                return error;

            // Getting the list of threads is inherently racy (unless the
            // caller has already stopped all threads, but that's not our
            // concern). Still, we promise to either return all threads we know
            // about at a particular point in time, or notify the caller that
            // more threads exist than what we computed at that same point in
            // time.

            fbl::Array<zx_koid_t> threads;
            zx_status_t status = process->GetThreads(&threads);
            if (status != ZX_OK)
                return status;
            size_t num_threads = threads.size();
            size_t num_space_for = buffer_size / sizeof(zx_koid_t);
            size_t num_to_copy = MIN(num_threads, num_space_for);

            // Don't try to copy if there are no bytes to copy, as the "is
            // user space" check may not handle (_buffer == NULL and len == 0).
            if (num_to_copy &&
                _buffer.copy_array_to_user(threads.get(), sizeof(zx_koid_t) * num_to_copy) != ZX_OK)
                return ZX_ERR_INVALID_ARGS;
            if (_actual) {
                zx_status_t status = _actual.copy_to_user(num_to_copy);
                if (status != ZX_OK)
                    return status;
            }
            if (_avail) {
                zx_status_t status = _avail.copy_to_user(num_threads);
                if (status != ZX_OK)
                    return status;
            }
            return ZX_OK;
        }
        case ZX_INFO_JOB_CHILDREN:
        case ZX_INFO_JOB_PROCESSES: {
            fbl::RefPtr<JobDispatcher> job;
            auto error = up->GetDispatcherWithRights(handle, ZX_RIGHT_ENUMERATE, &job);
            if (error < 0)
                return error;

            size_t max = buffer_size / sizeof(zx_koid_t);
            auto koids = _buffer.reinterpret<zx_koid_t>();
            SimpleJobEnumerator sje(koids, max, topic == ZX_INFO_JOB_CHILDREN);

            // Don't recurse; we only want the job's direct children.
            if (!job->EnumerateChildren(&sje, /* recurse */ false)) {
                // SimpleJobEnumerator only returns false when it can't
                // write to the user pointer.
                return ZX_ERR_INVALID_ARGS;
            }
            if (_actual) {
                zx_status_t status = _actual.copy_to_user(sje.get_count());
                if (status != ZX_OK)
                    return status;
            }
            if (_avail) {
                zx_status_t status = _avail.copy_to_user(sje.get_avail());
                if (status != ZX_OK)
                    return status;
            }
            return ZX_OK;
        }
        case ZX_INFO_THREAD: {
            // TODO(ZX-458): Handle forward/backward compatibility issues
            // with changes to the struct.

            // grab a reference to the dispatcher
            fbl::RefPtr<ThreadDispatcher> thread;
            auto error = up->GetDispatcherWithRights(handle, ZX_RIGHT_READ, &thread);
            if (error < 0)
                return error;

            // build the info structure
            zx_info_thread_t info = { };

            auto err = thread->GetInfoForUserspace(&info);
            if (err != ZX_OK)
                return err;

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &info, sizeof(info));
        }
        case ZX_INFO_THREAD_EXCEPTION_REPORT: {
            // TODO(ZX-458): Handle forward/backward compatibility issues
            // with changes to the struct.

            // grab a reference to the dispatcher
            fbl::RefPtr<ThreadDispatcher> thread;
            auto error = up->GetDispatcherWithRights(handle, ZX_RIGHT_READ, &thread);
            if (error < 0)
                return error;

            // build the info structure
            zx_exception_report_t report = { };

            auto err = thread->GetExceptionReport(&report);
            if (err != ZX_OK)
                return err;

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &report, sizeof(report));
        }
        case ZX_INFO_THREAD_STATS: {
            // TODO(ZX-458): Handle forward/backward compatibility issues
            // with changes to the struct.

            // grab a reference to the dispatcher
            fbl::RefPtr<ThreadDispatcher> thread;
            auto error = up->GetDispatcherWithRights(handle, ZX_RIGHT_READ, &thread);
            if (error < 0)
                return error;

            // build the info structure
            zx_info_thread_stats_t info = { };

            auto err = thread->GetStatsForUserspace(&info);
            if (err != ZX_OK)
                return err;

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &info, sizeof(info));
        }
        case ZX_INFO_TASK_STATS: {
            // TODO(ZX-458): Handle forward/backward compatibility issues
            // with changes to the struct.

            // Grab a reference to the dispatcher. Only supports processes for
            // now, but could support jobs or threads in the future.
            fbl::RefPtr<ProcessDispatcher> process;
            auto error = up->GetDispatcherWithRights(handle, ZX_RIGHT_READ,
                                                     &process);
            if (error < 0)
                return error;

            // Build the info structure.
            zx_info_task_stats_t info = {};

            auto err = process->GetStats(&info);
            if (err != ZX_OK)
                return err;

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &info, sizeof(info));
        }
        case ZX_INFO_PROCESS_MAPS: {
            fbl::RefPtr<ProcessDispatcher> process;
            zx_status_t status =
                up->GetDispatcherWithRights(handle, ZX_RIGHT_READ, &process);
            if (status < 0)
                return status;
            if (process.get() == up) {
                // Not safe to look at yourself: the user buffer will live
                // inside the VmAspace we're examining, and we can't
                // fault in the buffer's pages while the aspace lock is held.
                return ZX_ERR_ACCESS_DENIED;
            }

            auto maps = _buffer.reinterpret<zx_info_maps_t>();
            size_t count = buffer_size / sizeof(zx_info_maps_t);
            size_t avail = 0;
            status = process->GetAspaceMaps(maps, count, &count, &avail);

            if (_actual) {
                zx_status_t status = _actual.copy_to_user(count);
                if (status != ZX_OK)
                    return status;
            }
            if (_avail) {
                zx_status_t status = _avail.copy_to_user(avail);
                if (status != ZX_OK)
                    return status;
            }
            return status;
        }
        case ZX_INFO_PROCESS_VMOS: {
            fbl::RefPtr<ProcessDispatcher> process;
            zx_status_t status =
                up->GetDispatcherWithRights(handle, ZX_RIGHT_READ, &process);
            if (status < 0)
                return status;
            if (process.get() == up) {
                // Not safe to look at yourself: the user buffer will live
                // inside the VmAspace we're examining, and we can't
                // fault in the buffer's pages while the aspace lock is held.
                return ZX_ERR_ACCESS_DENIED;
            }

            auto vmos = _buffer.reinterpret<zx_info_vmo_t>();
            size_t count = buffer_size / sizeof(zx_info_vmo_t);
            size_t avail = 0;
            status = process->GetVmos(vmos, count, &count, &avail);

            if (_actual) {
                zx_status_t status = _actual.copy_to_user(count);
                if (status != ZX_OK)
                    return status;
            }
            if (_avail) {
                zx_status_t status = _avail.copy_to_user(avail);
                if (status != ZX_OK)
                    return status;
            }
            return status;
        }
        case ZX_INFO_VMAR: {
            fbl::RefPtr<VmAddressRegionDispatcher> vmar;
            zx_status_t status = up->GetDispatcher(handle, &vmar);
            if (status < 0)
                return status;

            auto real_vmar = vmar->vmar();
            zx_info_vmar_t info = {
                .base = real_vmar->base(),
                .len = real_vmar->size(),
            };

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &info, sizeof(info));
        }
        case ZX_INFO_CPU_STATS: {
            auto status = validate_resource(handle, ZX_RSRC_KIND_ROOT);
            if (status != ZX_OK)
                return status;

            // TODO: figure out a better handle to hang this off to and push this copy code into
            // that dispatcher.

            size_t num_cpus = arch_max_num_cpus();
            size_t num_space_for = buffer_size / sizeof(zx_info_cpu_stats_t);
            size_t num_to_copy = MIN(num_cpus, num_space_for);

            // build an alias to the output buffer that is in units of the cpu stat structure
            user_out_ptr<zx_info_cpu_stats_t> cpu_buf = _buffer.reinterpret<zx_info_cpu_stats_t>();

            for (unsigned int i = 0; i < static_cast<unsigned int>(num_to_copy); i++) {
                const auto cpu = &percpu[i];

                // copy the per cpu stats from the kernel percpu structure
                // NOTE: it's technically racy to read this without grabbing a lock
                // but since each field is wordwise any sane architecture will not
                // return a corrupted value.
                zx_info_cpu_stats_t stats = {};
                stats.cpu_number = i;
                stats.flags = mp_is_cpu_online(i) ? ZX_INFO_CPU_STATS_FLAG_ONLINE : 0;

                // account for idle time if a cpu is currently idle
                {
                    AutoSpinLock lock(&thread_lock);

                    zx_time_t idle_time = cpu->stats.idle_time;
                    bool is_idle = mp_is_cpu_idle(i);
                    if (is_idle) {
                        idle_time += current_time() - percpu[i].idle_thread.last_started_running;
                    }
                    stats.idle_time = idle_time;
                }

                stats.reschedules = cpu->stats.reschedules;
                stats.context_switches = cpu->stats.context_switches;
                stats.irq_preempts = cpu->stats.irq_preempts;
                stats.preempts = cpu->stats.preempts;
                stats.yields = cpu->stats.yields;
                stats.ints = cpu->stats.interrupts;
                stats.timer_ints = cpu->stats.timer_ints;
                stats.timers = cpu->stats.timers;
                stats.page_faults = 0;      // deprecated, use "k counters" for now.
                stats.exceptions = 0;       // deprecated, use "k counters" for now.
                stats.syscalls = cpu->stats.syscalls;
                stats.reschedule_ipis = cpu->stats.reschedule_ipis;
                stats.generic_ipis = cpu->stats.generic_ipis;

                // copy out one at a time
                if (cpu_buf.copy_array_to_user(&stats, 1, i) != ZX_OK)
                    return ZX_ERR_INVALID_ARGS;
            }

            if (_actual) {
                zx_status_t status = _actual.copy_to_user(num_to_copy);
                if (status != ZX_OK)
                    return status;
            }
            if (_avail) {
                zx_status_t status = _avail.copy_to_user(num_cpus);
                if (status != ZX_OK)
                    return status;
            }
            return ZX_OK;
        }
        case ZX_INFO_KMEM_STATS: {
            auto status = validate_resource(handle, ZX_RSRC_KIND_ROOT);
            if (status != ZX_OK)
                return status;

            // TODO: figure out a better handle to hang this off to and push this copy code into
            // that dispatcher.

            size_t state_count[_VM_PAGE_STATE_COUNT] = {};
            pmm_count_total_states(state_count);

            size_t total = 0;
            for (int i = 0; i < _VM_PAGE_STATE_COUNT; i++) {
                total += state_count[i];
            }

            size_t unused_size = 0;
            size_t free_heap_bytes = 0;
            heap_get_info(&unused_size, &free_heap_bytes);

            // Note that this intentionally uses uint64_t instead of
            // size_t in case we ever have a 32-bit userspace but more
            // than 4GB physical memory.
            zx_info_kmem_stats_t stats = {};
            stats.total_bytes = total * PAGE_SIZE;
            size_t other_bytes = stats.total_bytes;

            stats.free_bytes = state_count[VM_PAGE_STATE_FREE] * PAGE_SIZE;
            other_bytes -= stats.free_bytes;

            stats.wired_bytes = state_count[VM_PAGE_STATE_WIRED] * PAGE_SIZE;
            other_bytes -= stats.wired_bytes;

            stats.total_heap_bytes = state_count[VM_PAGE_STATE_HEAP] * PAGE_SIZE;
            other_bytes -= stats.total_heap_bytes;
            stats.free_heap_bytes = free_heap_bytes;

            stats.vmo_bytes = state_count[VM_PAGE_STATE_OBJECT] * PAGE_SIZE;
            other_bytes -= stats.vmo_bytes;

            stats.mmu_overhead_bytes = state_count[VM_PAGE_STATE_MMU] * PAGE_SIZE;
            other_bytes -= stats.mmu_overhead_bytes;

            // All other VM_PAGE_STATE_* counts get lumped into other_bytes.
            stats.other_bytes = other_bytes;

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &stats, sizeof(stats));
        }
        case ZX_INFO_RESOURCE: {
            // grab a reference to the dispatcher
            fbl::RefPtr<ResourceDispatcher> resource;
            auto error = up->GetDispatcherWithRights(handle, ZX_RIGHT_NONE, &resource);
            if (error < 0)
                return error;

            // build the info structure
            zx_info_resource_t info = {};
            info.kind = resource->get_kind();
            resource->get_range(&info.low, &info.high);

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &info, sizeof(info));
        }
        case ZX_INFO_HANDLE_COUNT: {
            fbl::RefPtr<Dispatcher> dispatcher;
            auto status = up->GetDispatcherWithRights(handle, ZX_RIGHT_READ, &dispatcher);
            if (status != ZX_OK)
                return status;

            zx_info_handle_count_t info = {
                .handle_count = Handle::Count(fbl::move(dispatcher))
            };

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &info, sizeof(info));
        }
        case ZX_INFO_BTI: {
            fbl::RefPtr<BusTransactionInitiatorDispatcher> dispatcher;
            auto status = up->GetDispatcherWithRights(handle, ZX_RIGHT_READ, &dispatcher);
            if (status != ZX_OK)
                return status;

            zx_info_bti_t info = {
                .minimum_contiguity = dispatcher->minimum_contiguity(),
                .aspace_size = dispatcher->aspace_size(),
            };

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &info, sizeof(info));
        }
        case ZX_INFO_PROCESS_HANDLE_STATS: {
            fbl::RefPtr<ProcessDispatcher> process;
            auto status = up->GetDispatcherWithRights(handle, ZX_RIGHT_READ, &process);
            if (status != ZX_OK)
                return status;

            zx_info_process_handle_stats_t info = {};
            static_assert(fbl::count_of(info.handle_count) >= ZX_OBJ_TYPE_LAST,
                          "Need room for each handle type.");

            process->ForEachHandle([&](zx_handle_t handle, zx_rights_t rights,
                                       const Dispatcher* dispatcher) {
                ++info.handle_count[dispatcher->get_type()];
                return ZX_OK;
            });

            return single_record_result(
                _buffer, buffer_size, _actual, _avail, &info, sizeof(info));
        }

        default:
            return ZX_ERR_NOT_SUPPORTED;
    }
}

zx_status_t sys_object_get_property(zx_handle_t handle_value, uint32_t property,
                                    user_out_ptr<void> _value, size_t size) {
    if (!_value)
        return ZX_ERR_INVALID_ARGS;

    auto up = ProcessDispatcher::GetCurrent();
    fbl::RefPtr<Dispatcher> dispatcher;
    auto status = up->GetDispatcherWithRights(handle_value, ZX_RIGHT_GET_PROPERTY, &dispatcher);
    if (status != ZX_OK)
        return status;

    switch (property) {
        case ZX_PROP_NAME: {
            if (size < ZX_MAX_NAME_LEN)
                return ZX_ERR_BUFFER_TOO_SMALL;
            char name[ZX_MAX_NAME_LEN];
            dispatcher->get_name(name);
            if (_value.copy_array_to_user(name, ZX_MAX_NAME_LEN) != ZX_OK)
                return ZX_ERR_INVALID_ARGS;
            return ZX_OK;
        }
        case ZX_PROP_PROCESS_DEBUG_ADDR: {
            if (size < sizeof(uintptr_t))
                return ZX_ERR_BUFFER_TOO_SMALL;
            auto process = DownCastDispatcher<ProcessDispatcher>(&dispatcher);
            if (!process)
                return ZX_ERR_WRONG_TYPE;
            uintptr_t value = process->get_debug_addr();
            zx_status_t status = _value.reinterpret<uintptr_t>().copy_to_user(value);
            if (status != ZX_OK)
                return status;
            return ZX_OK;
        }
        case ZX_PROP_PROCESS_VDSO_BASE_ADDRESS: {
            if (size < sizeof(uintptr_t))
                return ZX_ERR_BUFFER_TOO_SMALL;
            auto process = DownCastDispatcher<ProcessDispatcher>(&dispatcher);
            if (!process)
                return ZX_ERR_WRONG_TYPE;
            uintptr_t value = process->aspace()->vdso_base_address();
            return _value.reinterpret<uintptr_t>().copy_to_user(value);
        }
        case ZX_PROP_JOB_IMPORTANCE: {
            if (size != sizeof(zx_job_importance_t))
                return ZX_ERR_BUFFER_TOO_SMALL;
            auto job = DownCastDispatcher<JobDispatcher>(&dispatcher);
            if (!job)
                return ZX_ERR_WRONG_TYPE;
            zx_job_importance_t value;
            zx_status_t status = job->get_importance(&value);
            if (status != ZX_OK) {
                // Usually a problem resolving inherited importance,
                // like racing with task death.
                return status;
            }
            status = _value.reinterpret<zx_job_importance_t>().copy_to_user(value);
            if (status != ZX_OK)
                return status;
            return ZX_OK;
        }
        case ZX_PROP_SOCKET_RX_BUF_MAX: {
            if (size < sizeof(size_t))
                return ZX_ERR_BUFFER_TOO_SMALL;
            auto socket = DownCastDispatcher<SocketDispatcher>(&dispatcher);
            if (!socket)
                return ZX_ERR_WRONG_TYPE;
            size_t value = socket->ReceiveBufferMax();
            zx_status_t status = _value.reinterpret<size_t>().copy_to_user(value);
            if (status != ZX_OK)
                return status;
            return ZX_OK;
        }
        case ZX_PROP_SOCKET_RX_BUF_SIZE: {
            if (size < sizeof(size_t))
                return ZX_ERR_BUFFER_TOO_SMALL;
            auto socket = DownCastDispatcher<SocketDispatcher>(&dispatcher);
            if (!socket)
                return ZX_ERR_WRONG_TYPE;
            size_t value = socket->ReceiveBufferSize();
            zx_status_t status = _value.reinterpret<size_t>().copy_to_user(value);
            if (status != ZX_OK)
                return status;
            return ZX_OK;
        }
        case ZX_PROP_SOCKET_TX_BUF_MAX: {
            if (size < sizeof(size_t))
                return ZX_ERR_BUFFER_TOO_SMALL;
            auto socket = DownCastDispatcher<SocketDispatcher>(&dispatcher);
            if (!socket)
                return ZX_ERR_WRONG_TYPE;
            size_t value = socket->TransmitBufferMax();
            zx_status_t status = _value.reinterpret<size_t>().copy_to_user(value);
            if (status != ZX_OK)
                return status;
            return ZX_OK;
        }
        case ZX_PROP_SOCKET_TX_BUF_SIZE: {
            if (size < sizeof(size_t))
                return ZX_ERR_BUFFER_TOO_SMALL;
            auto socket = DownCastDispatcher<SocketDispatcher>(&dispatcher);
            if (!socket)
                return ZX_ERR_WRONG_TYPE;
            size_t value = socket->TransmitBufferSize();
            zx_status_t status = _value.reinterpret<size_t>().copy_to_user(value);
            if (status != ZX_OK)
                return status;
            return ZX_OK;
        }
        default:
            return ZX_ERR_INVALID_ARGS;
    }

    __UNREACHABLE;
}

static zx_status_t is_current_thread(fbl::RefPtr<Dispatcher>* dispatcher) {
    auto thread_dispatcher = DownCastDispatcher<ThreadDispatcher>(dispatcher);
    if (!thread_dispatcher)
        return ZX_ERR_WRONG_TYPE;
    if (thread_dispatcher.get() != ThreadDispatcher::GetCurrent())
        return ZX_ERR_ACCESS_DENIED;
    return ZX_OK;
}

zx_status_t sys_object_set_property(zx_handle_t handle_value, uint32_t property,
                                    user_in_ptr<const void> _value, size_t size) {
    if (!_value)
        return ZX_ERR_INVALID_ARGS;

    auto up = ProcessDispatcher::GetCurrent();
    fbl::RefPtr<Dispatcher> dispatcher;

    auto status = up->GetDispatcherWithRights(handle_value, ZX_RIGHT_SET_PROPERTY, &dispatcher);
    if (status != ZX_OK)
        return status;

    switch (property) {
        case ZX_PROP_NAME: {
            if (size >= ZX_MAX_NAME_LEN)
                size = ZX_MAX_NAME_LEN - 1;
            char name[ZX_MAX_NAME_LEN - 1];
            if (_value.copy_array_from_user(name, size) != ZX_OK)
                return ZX_ERR_INVALID_ARGS;
            return dispatcher->set_name(name, size);
        }
#if ARCH_X86
        case ZX_PROP_REGISTER_FS: {
            if (size < sizeof(uintptr_t))
                return ZX_ERR_BUFFER_TOO_SMALL;
            zx_status_t status = is_current_thread(&dispatcher);
            if (status != ZX_OK)
                return status;
            uintptr_t addr;
            status = _value.reinterpret<const uintptr_t>().copy_from_user(&addr);
            if (status != ZX_OK)
                return status;
            if (!x86_is_vaddr_canonical(addr))
                return ZX_ERR_INVALID_ARGS;
            write_msr(X86_MSR_IA32_FS_BASE, addr);
            return ZX_OK;
        }
#endif
        case ZX_PROP_PROCESS_DEBUG_ADDR: {
            if (size < sizeof(uintptr_t))
                return ZX_ERR_BUFFER_TOO_SMALL;
            auto process = DownCastDispatcher<ProcessDispatcher>(&dispatcher);
            if (!process)
                return ZX_ERR_WRONG_TYPE;
            uintptr_t value = 0;
            zx_status_t status = _value.reinterpret<const uintptr_t>().copy_from_user(&value);
            if (status != ZX_OK)
                return status;
            return process->set_debug_addr(value);
        }
        case ZX_PROP_JOB_IMPORTANCE: {
            if (size != sizeof(zx_job_importance_t))
                return ZX_ERR_BUFFER_TOO_SMALL;
            auto job = DownCastDispatcher<JobDispatcher>(&dispatcher);
            if (!job)
                return ZX_ERR_WRONG_TYPE;
            int32_t value = 0;
            zx_status_t status = _value.reinterpret<const zx_job_importance_t>()
                .copy_from_user(&value);
            if (status != ZX_OK)
                return status;
            return job->set_importance(
                static_cast<zx_job_importance_t>(value));
        }
    }

    return ZX_ERR_INVALID_ARGS;
}

zx_status_t sys_object_signal(zx_handle_t handle_value, uint32_t clear_mask, uint32_t set_mask) {
    LTRACEF("handle %x\n", handle_value);

    auto up = ProcessDispatcher::GetCurrent();
    fbl::RefPtr<Dispatcher> dispatcher;

    auto status = up->GetDispatcherWithRights(handle_value, ZX_RIGHT_SIGNAL, &dispatcher);
    if (status != ZX_OK)
        return status;

    return dispatcher->user_signal(clear_mask, set_mask, false);
}

zx_status_t sys_object_signal_peer(zx_handle_t handle_value, uint32_t clear_mask, uint32_t set_mask) {
    LTRACEF("handle %x\n", handle_value);

    auto up = ProcessDispatcher::GetCurrent();
    fbl::RefPtr<Dispatcher> dispatcher;

    auto status = up->GetDispatcherWithRights(handle_value, ZX_RIGHT_SIGNAL_PEER, &dispatcher);
    if (status != ZX_OK)
        return status;

    return dispatcher->user_signal(clear_mask, set_mask, true);
}

// Given a kernel object with children objects, obtain a handle to the
// child specified by the provided kernel object id.
//
// ZX_HANDLE_INVALID is currently treated as a "magic" handle used to
// obtain a process from "the system".
zx_status_t sys_object_get_child(zx_handle_t handle, uint64_t koid,
                                 zx_rights_t rights, user_out_handle* out) {
    auto up = ProcessDispatcher::GetCurrent();

    if (handle == ZX_HANDLE_INVALID) {
        //TODO: lookup process from job instead of treating INVALID as magic
        // TODO(ZX-923): Rights handling for debug purposes.
        const auto kDebugRights =
            ZX_RIGHTS_BASIC | ZX_RIGHTS_IO |
            ZX_RIGHTS_PROPERTY | ZX_RIGHT_ENUMERATE;

        if (rights == ZX_RIGHT_SAME_RIGHTS) {
            rights = kDebugRights;
        } else if ((kDebugRights & rights) != rights) {
            return ZX_ERR_ACCESS_DENIED;
        }

        auto process = ProcessDispatcher::LookupProcessById(koid);
        if (!process)
            return ZX_ERR_NOT_FOUND;

        return out->make(fbl::move(process), rights);
    }

    fbl::RefPtr<Dispatcher> dispatcher;
    uint32_t parent_rights;
    auto status = up->GetDispatcherAndRights(handle, &dispatcher, &parent_rights);
    if (status != ZX_OK)
        return status;

    if (!(parent_rights & ZX_RIGHT_ENUMERATE))
        return ZX_ERR_ACCESS_DENIED;

    if (rights == ZX_RIGHT_SAME_RIGHTS) {
        rights = parent_rights;
    } else if ((parent_rights & rights) != rights) {
        return ZX_ERR_ACCESS_DENIED;
    }

    auto process = DownCastDispatcher<ProcessDispatcher>(&dispatcher);
    if (process) {
        auto thread = process->LookupThreadById(koid);
        if (!thread)
            return ZX_ERR_NOT_FOUND;
        return out->make(fbl::move(thread), rights);
    }

    auto job = DownCastDispatcher<JobDispatcher>(&dispatcher);
    if (job) {
        auto child = job->LookupJobById(koid);
        if (child)
            return out->make(fbl::move(child), rights);
        auto proc = job->LookupProcessById(koid);
        if (proc)
            return out->make(fbl::move(proc), rights);
        return ZX_ERR_NOT_FOUND;
    }

    return ZX_ERR_WRONG_TYPE;
}


zx_status_t sys_object_set_cookie(zx_handle_t handle, zx_handle_t hscope, uint64_t cookie) {
    auto up = ProcessDispatcher::GetCurrent();

    zx_koid_t scope = up->GetKoidForHandle(hscope);
    if (scope == ZX_KOID_INVALID)
        return ZX_ERR_BAD_HANDLE;

    fbl::RefPtr<Dispatcher> dispatcher;
    auto status = up->GetDispatcher(handle, &dispatcher);
    if (status != ZX_OK)
        return status;

    if (!dispatcher->has_state_tracker())
        return ZX_ERR_NOT_SUPPORTED;

    return dispatcher->SetCookie(dispatcher->get_cookie_jar(), scope, cookie);
}

zx_status_t sys_object_get_cookie(zx_handle_t handle, zx_handle_t hscope, user_out_ptr<uint64_t> _cookie) {
    auto up = ProcessDispatcher::GetCurrent();

    zx_koid_t scope = up->GetKoidForHandle(hscope);
    if (scope == ZX_KOID_INVALID)
        return ZX_ERR_BAD_HANDLE;

    fbl::RefPtr<Dispatcher> dispatcher;
    auto status = up->GetDispatcher(handle, &dispatcher);
    if (status != ZX_OK)
        return status;

    if (!dispatcher->has_state_tracker())
        return ZX_ERR_NOT_SUPPORTED;

    uint64_t cookie;
    status = dispatcher->GetCookie(dispatcher->get_cookie_jar(), scope, &cookie);
    if (status != ZX_OK)
        return status;

    status = _cookie.copy_to_user(cookie);
    if (status != ZX_OK)
        return status;

    return ZX_OK;
}
