// Copyright 2017 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 <object/excp_port.h>

#include <err.h>
#include <inttypes.h>
#include <string.h>

#include <arch/exception.h>

#include <object/job_dispatcher.h>
#include <object/port_dispatcher.h>
#include <object/process_dispatcher.h>
#include <object/thread_dispatcher.h>

#include <fbl/alloc_checker.h>

#include <trace.h>

#define LOCAL_TRACE 0

static PortPacket* MakePacket(uint64_t key, uint32_t type, zx_koid_t pid, zx_koid_t tid) {
    if (!ZX_PKT_IS_EXCEPTION(type))
        return nullptr;

    auto port_packet = PortDispatcher::DefaultPortAllocator()->Alloc();
    if (!port_packet)
        return nullptr;

    port_packet->packet.key = key;
    port_packet->packet.type = type;
    port_packet->packet.status = ZX_OK;
    port_packet->packet.exception.pid = pid;
    port_packet->packet.exception.tid = tid;
    port_packet->packet.exception.reserved0 = 0;
    port_packet->packet.exception.reserved1 = 0;

    return port_packet;
}

// static
zx_status_t ExceptionPort::Create(Type type, fbl::RefPtr<PortDispatcher> port, uint64_t port_key,
                                  fbl::RefPtr<ExceptionPort>* out_eport) {
    fbl::AllocChecker ac;
    auto eport = new (&ac) ExceptionPort(type, ktl::move(port), port_key);
    if (!ac.check())
        return ZX_ERR_NO_MEMORY;

    // ExceptionPort's ctor causes the first ref to be adopted,
    // so we should only wrap.
    *out_eport = fbl::WrapRefPtr<ExceptionPort>(eport);
    return ZX_OK;
}

ExceptionPort::ExceptionPort(Type type, fbl::RefPtr<PortDispatcher> port, uint64_t port_key)
    : type_(type), port_key_(port_key), port_(port) {
    LTRACE_ENTRY_OBJ;
    DEBUG_ASSERT(port_ != nullptr);

    Guard<fbl::Mutex> guard{&lock_};
    port_->LinkExceptionPortEportLocked(this);
}

ExceptionPort::~ExceptionPort() {
    LTRACE_ENTRY_OBJ;
    DEBUG_ASSERT(port_ == nullptr);
    DEBUG_ASSERT(!InContainer());
    DEBUG_ASSERT(!IsBoundLocked());
}

void ExceptionPort::SetTarget(const fbl::RefPtr<JobDispatcher>& target) {
    canary_.Assert();

    LTRACE_ENTRY_OBJ;
    Guard<fbl::Mutex> guard{&lock_};
    DEBUG_ASSERT_MSG(type_ == Type::JOB || type_ == Type::JOB_DEBUGGER,
                     "unexpected type %d", static_cast<int>(type_));
    DEBUG_ASSERT(!IsBoundLocked());
    DEBUG_ASSERT(target != nullptr);
    DEBUG_ASSERT(port_ != nullptr);
    target_ = target;
}

void ExceptionPort::SetTarget(const fbl::RefPtr<ProcessDispatcher>& target) {
    canary_.Assert();

    LTRACE_ENTRY_OBJ;
    Guard<fbl::Mutex> guard{&lock_};
    DEBUG_ASSERT_MSG(type_ == Type::DEBUGGER || type_ == Type::PROCESS,
                     "unexpected type %d", static_cast<int>(type_));
    DEBUG_ASSERT(!IsBoundLocked());
    DEBUG_ASSERT(target != nullptr);
    DEBUG_ASSERT(port_ != nullptr);
    target_ = target;
}

void ExceptionPort::SetTarget(const fbl::RefPtr<ThreadDispatcher>& target) {
    canary_.Assert();

    LTRACE_ENTRY_OBJ;
    Guard<fbl::Mutex> guard{&lock_};
    DEBUG_ASSERT_MSG(type_ == Type::THREAD,
                     "unexpected type %d", static_cast<int>(type_));
    DEBUG_ASSERT(!IsBoundLocked());
    DEBUG_ASSERT(target != nullptr);
    DEBUG_ASSERT(port_ != nullptr);
    target_ = target;
}

// Called by PortDispatcher after unlinking us from its eport list.
void ExceptionPort::OnPortZeroHandles() {
    canary_.Assert();

    LTRACE_ENTRY_OBJ;
    Guard<fbl::Mutex> guard{&lock_};
    if (port_ == nullptr) {
        // Already unbound. This can happen when
        // PortDispatcher::on_zero_handles and a manual unbind (via
        // zx_task_bind_exception_port) race with each other.
        LTRACEF("already unbound\n");
        DEBUG_ASSERT(!IsBoundLocked());
        return;
    }

    // Unbind ourselves from our target if necessary. At the end of this
    // block, some thread (ours or another) will have called back into our
    // ::OnTargetUnbind method, cleaning up our target/port references. The
    // "other thread" case can happen if another thread manually unbinds after
    // we release the lock.
    if (!IsBoundLocked()) {
        // Created but never bound.
        guard.Release();
        // Simulate an unbinding to finish cleaning up.
        OnTargetUnbind();
    } else {
        switch (type_) {
            case Type::JOB:
            case Type::JOB_DEBUGGER: {
                DEBUG_ASSERT(target_ != nullptr);
                auto job = DownCastDispatcher<JobDispatcher>(&target_);
                DEBUG_ASSERT(job != nullptr);
                guard.Release();  // The target may call our ::OnTargetUnbind
                job->ResetExceptionPort(type_ == Type::JOB_DEBUGGER);
                break;
            }
            case Type::PROCESS:
            case Type::DEBUGGER: {
                DEBUG_ASSERT(target_ != nullptr);
                auto process = DownCastDispatcher<ProcessDispatcher>(&target_);
                DEBUG_ASSERT(process != nullptr);
                guard.Release();  // The target may call our ::OnTargetUnbind
                process->ResetExceptionPort(type_ == Type::DEBUGGER);
                break;
            }
            case Type::THREAD: {
                DEBUG_ASSERT(target_ != nullptr);
                auto thread = DownCastDispatcher<ThreadDispatcher>(&target_);
                DEBUG_ASSERT(thread != nullptr);
                guard.Release();  // The target may call our ::OnTargetUnbind
                thread->ResetExceptionPort();
                break;
            }
            default:
                PANIC("unexpected type %d", static_cast<int>(type_));
        }
    }
    // All cases must release the lock.
    DEBUG_ASSERT(!lock_.lock().IsHeld());

#if (LK_DEBUGLEVEL > 1)
    // The target should have called back into ::OnTargetUnbind by this point,
    // cleaning up our references.
    {
        Guard<fbl::Mutex> guard2{&lock_};
        DEBUG_ASSERT(port_ == nullptr);
        DEBUG_ASSERT(!IsBoundLocked());
    }
#endif  // if (LK_DEBUGLEVEL > 1)

    LTRACE_EXIT_OBJ;
}

void ExceptionPort::OnTargetUnbind() {
    canary_.Assert();

    LTRACE_ENTRY_OBJ;
    fbl::RefPtr<PortDispatcher> port;
    {
        Guard<fbl::Mutex> guard{&lock_};
        if (port_ == nullptr) {
            // Already unbound.
            // This could happen if ::OnPortZeroHandles releases the
            // lock and another thread immediately does a manual unbind
            // via zx_task_bind_exception_port.
            DEBUG_ASSERT(!IsBoundLocked());
            return;
        }
        // Clear port_, indicating that this ExceptionPort has been unbound.
        port_.swap(port);

        // Drop references to the target.
        // We may not have a target if the binding (Set*Target) never happened,
        // so don't require that we're bound.
        target_.reset();

        // Unlink ourselves from the PortDispatcher's list.
        // No-op if this method was ultimately called from
        // PortDispatcher:on_zero_handles (via ::OnPortZeroHandles).
        port->UnlinkExceptionPortEportLocked(this);
    }

    LTRACE_EXIT_OBJ;
}

bool ExceptionPort::PortMatches(const PortDispatcher *port, bool allow_null) {
    Guard<fbl::Mutex> guard{&lock_};
    return PortMatchesLocked(port, allow_null);
}

bool ExceptionPort::PortMatchesLocked(const PortDispatcher *port, bool allow_null) {
    return (allow_null && port_ == nullptr) || port_.get() == port;
}

zx_status_t ExceptionPort::SendPacketWorker(uint32_t type, zx_koid_t pid, zx_koid_t tid) {
    Guard<fbl::Mutex> guard{&lock_};
    LTRACEF("%s, type %u, pid %" PRIu64 ", tid %" PRIu64 "\n",
            port_ == nullptr ? "Not sending exception report on unbound port"
                : "Sending exception report",
            type, pid, tid);
    if (port_ == nullptr) {
        // The port has been unbound.
        return ZX_ERR_PEER_CLOSED;
    }

    auto iopk = MakePacket(port_key_, type, pid, tid);
    if (!iopk)
        return ZX_ERR_NO_MEMORY;

    zx_status_t status = port_->Queue(iopk, 0, 0);
    if (status != ZX_OK) {
        iopk->Free();
    }
    return status;
}

zx_status_t ExceptionPort::SendPacket(ThreadDispatcher* thread, uint32_t type) {
    canary_.Assert();

    zx_koid_t pid = thread->process()->get_koid();
    zx_koid_t tid = thread->get_koid();
    return SendPacketWorker(type, pid, tid);
}

void ExceptionPort::BuildReport(zx_exception_report_t* report, uint32_t type) {
    memset(report, 0, sizeof(*report));
    report->header.size = sizeof(*report);
    report->header.type = type;
}

void ExceptionPort::BuildArchReport(zx_exception_report_t* report, uint32_t type,
                                    const arch_exception_context_t* context) {
    BuildReport(report, type);
    arch_fill_in_exception_context(context, report);
}

void ExceptionPort::OnThreadStartForDebugger(ThreadDispatcher* thread,
                                             const arch_exception_context_t* context) {
    canary_.Assert();

    DEBUG_ASSERT(type_ == Type::DEBUGGER);

    zx_koid_t pid = thread->process()->get_koid();
    zx_koid_t tid = thread->get_koid();
    LTRACEF("thread %" PRIu64 ".%" PRIu64 " started\n", pid, tid);

    zx_status_t status = dispatch_debug_exception(fbl::RefPtr<ExceptionPort>(this),
                                                  ZX_EXCP_THREAD_STARTING,
                                                  context);
    if (status != ZX_OK) {
        // Ignore any errors. There's nothing we can do here, and
        // we still want the thread to run. It's possible the thread was
        // killed (status == ZX_ERR_INTERNAL_INTR_KILLED), the kernel will kill
        // the thread shortly.
    }
}

void ExceptionPort::OnProcessStartForDebugger(ThreadDispatcher* thread,
                                              const arch_exception_context_t* context) {
    canary_.Assert();

    DEBUG_ASSERT(type_ == Type::JOB_DEBUGGER);

    zx_koid_t pid = thread->process()->get_koid();
    zx_koid_t tid = thread->get_koid();
    LTRACEF("process %" PRIu64 ".%" PRIu64 " started\n", pid, tid);

    zx_status_t status = dispatch_debug_exception(fbl::RefPtr<ExceptionPort>(this),
                                                  ZX_EXCP_PROCESS_STARTING,
                                                  context);
    if (status != ZX_OK) {
        // Ignore any errors. There's nothing we can do here, and
        // we still want the thread to run. It's possible the thread was
        // killed (status == ZX_ERR_INTERNAL_INTR_KILLED), the kernel will kill
        // the thread shortly.
    }
}

// This isn't called for every thread's destruction, only when a debugger
// is attached.

void ExceptionPort::OnThreadExitForDebugger(ThreadDispatcher* thread) {
    canary_.Assert();

    DEBUG_ASSERT(type_ == Type::DEBUGGER);

    zx_koid_t pid = thread->process()->get_koid();
    zx_koid_t tid = thread->get_koid();
    LTRACEF("thread %" PRIu64 ".%" PRIu64 " exited\n", pid, tid);

    // There is no iframe at the moment. We'll need one (or equivalent) if/when
    // we want to make $pc, $sp available.
    arch_exception_context_t context{};

    // N.B. If the process is exiting it will have killed all threads. That
    // means all threads get marked with THREAD_SIGNAL_KILL which means this
    // exchange will return immediately with ZX_ERR_INTERNAL_INTR_KILLED.
    zx_status_t status = dispatch_debug_exception(fbl::RefPtr<ExceptionPort>(this),
                                                  ZX_EXCP_THREAD_EXITING,
                                                  &context);
    if (status != ZX_OK) {
        // Ignore any errors, we still want the thread to continue exiting.
    }
}
