/*
 * Server-side debugger support using Mach primitives
 *
 * Copyright (C) 1999, 2006 Alexandre Julliard
 * Copyright (C) 2006 Ken Thomases for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <stdarg.h>
#include <sys/types.h>
#include <unistd.h>

#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "winternl.h"

#include "file.h"
#include "process.h"
#include "thread.h"
#include "request.h"
#include "wine/library.h"

#ifdef USE_MACH

#include <mach/mach.h>
#include <mach/mach_error.h>
#include <mach/thread_act.h>
#include <servers/bootstrap.h>

extern int __pthread_kill(mach_port_t, int);

static mach_port_t server_mach_port;

void sigchld_callback(void)
{
    assert(0);  /* should never be called on MacOS */
}

static void mach_set_error(kern_return_t mach_error)
{
    switch (mach_error)
    {
        case KERN_SUCCESS:              break;
        case KERN_INVALID_ARGUMENT:     set_error(STATUS_INVALID_PARAMETER); break;
        case KERN_NO_SPACE:             set_error(STATUS_NO_MEMORY); break;
        case KERN_PROTECTION_FAILURE:   set_error(STATUS_ACCESS_DENIED); break;
        case KERN_INVALID_ADDRESS:      set_error(STATUS_ACCESS_VIOLATION); break;
        default:                        set_error(STATUS_UNSUCCESSFUL); break;
    }
}

static mach_port_t get_process_port( struct process *process )
{
    return process->trace_data;
}

/* initialize the process control mechanism */
void init_tracing_mechanism(void)
{
    mach_port_t bp;

    if (task_get_bootstrap_port(mach_task_self(), &bp) != KERN_SUCCESS)
        fatal_error("Can't find bootstrap port\n");
    if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &server_mach_port) != KERN_SUCCESS)
        fatal_error("Can't allocate port\n");
    if  (mach_port_insert_right( mach_task_self(),
                                 server_mach_port,
                                 server_mach_port,
                                 MACH_MSG_TYPE_MAKE_SEND ) != KERN_SUCCESS)
            fatal_error("Error inserting rights\n");
    if (bootstrap_register(bp, (char*)wine_get_server_dir(), server_mach_port) != KERN_SUCCESS)
        fatal_error("Can't check in server_mach_port\n");
    mach_port_deallocate(mach_task_self(), bp);
}

/* initialize the per-process tracing mechanism */
void init_process_tracing( struct process *process )
{
    int pid, ret;
    struct
    {
        mach_msg_header_t           header;
        mach_msg_body_t             body;
        mach_msg_port_descriptor_t  task_port;
        mach_msg_trailer_t          trailer; /* only present on receive */
    } msg;

    for (;;)
    {
        ret = mach_msg( &msg.header, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, sizeof(msg),
                        server_mach_port, 0, 0 );
        if (ret)
        {
            if (ret != MACH_RCV_TIMED_OUT && debug_level)
                fprintf( stderr, "warning: mach port receive failed with %x\n", ret );
            return;
        }

        /* if anything in the message is invalid, ignore it */
        if (msg.header.msgh_size != offsetof(typeof(msg), trailer)) continue;
        if (msg.body.msgh_descriptor_count != 1) continue;
        if (msg.task_port.type != MACH_MSG_PORT_DESCRIPTOR) continue;
        if (msg.task_port.disposition != MACH_MSG_TYPE_PORT_SEND) continue;
        if (msg.task_port.name == MACH_PORT_NULL) continue;
        if (msg.task_port.name == MACH_PORT_DEAD) continue;

        if (!pid_for_task( msg.task_port.name, &pid ))
        {
            struct thread *thread = get_thread_from_pid( pid );

            if (thread && !thread->process->trace_data)
                thread->process->trace_data = msg.task_port.name;
            else
                mach_port_deallocate( mach_task_self(), msg.task_port.name );
        }
    }
}

/* terminate the per-process tracing mechanism */
void finish_process_tracing( struct process *process )
{
    if (process->trace_data)
    {
        mach_port_deallocate( mach_task_self(), process->trace_data );
        process->trace_data = 0;
    }
}

/* retrieve the thread x86 registers */
void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags )
{
    struct x86_debug_state32 state;
    mach_msg_type_number_t count = sizeof(state) / sizeof(int);
    mach_msg_type_name_t type;
    mach_port_t port, process_port = get_process_port( thread->process );

    /* all other regs are handled on the client side */
    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );

    if (thread->unix_pid == -1 || !process_port ||
        mach_port_extract_right( process_port, thread->unix_tid,
                                 MACH_MSG_TYPE_COPY_SEND, &port, &type ))
    {
        set_error( STATUS_ACCESS_DENIED );
        return;
    }

    if (!thread_get_state( port, x86_DEBUG_STATE32, (thread_state_t)&state, &count ))
    {
        context->Dr0 = state.dr0;
        context->Dr1 = state.dr1;
        context->Dr2 = state.dr2;
        context->Dr3 = state.dr3;
        context->Dr6 = state.dr6;
        context->Dr7 = state.dr7;
        context->ContextFlags |= CONTEXT_DEBUG_REGISTERS;
    }
    mach_port_deallocate( mach_task_self(), port );
}

/* set the thread x86 registers */
void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags )
{
    struct x86_debug_state32 state;
    mach_msg_type_number_t count = sizeof(state) / sizeof(int);
    mach_msg_type_name_t type;
    mach_port_t port, process_port = get_process_port( thread->process );

    /* all other regs are handled on the client side */
    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );

    if (thread->unix_pid == -1 || !process_port ||
        mach_port_extract_right( process_port, thread->unix_tid,
                                 MACH_MSG_TYPE_COPY_SEND, &port, &type ))
    {
        set_error( STATUS_ACCESS_DENIED );
        return;
    }

    state.dr0 = context->Dr0;
    state.dr1 = context->Dr1;
    state.dr2 = context->Dr2;
    state.dr3 = context->Dr3;
    state.dr4 = 0;
    state.dr5 = 0;
    state.dr6 = context->Dr6;
    state.dr7 = context->Dr7;
    if (!thread_set_state( port, x86_DEBUG_STATE32, (thread_state_t)&state, count ))
    {
        if (thread->context)  /* update the cached values */
        {
            thread->context->Dr0 = context->Dr0;
            thread->context->Dr1 = context->Dr1;
            thread->context->Dr2 = context->Dr2;
            thread->context->Dr3 = context->Dr3;
            thread->context->Dr6 = context->Dr6;
            thread->context->Dr7 = context->Dr7;
        }
    }
    mach_port_deallocate( mach_task_self(), port );
}

int send_thread_signal( struct thread *thread, int sig )
{
    int ret = -1;
    mach_port_t process_port = get_process_port( thread->process );

    if (thread->unix_pid != -1 && process_port)
    {
        mach_msg_type_name_t type;
        mach_port_t port;

        if (!mach_port_extract_right( process_port, thread->unix_tid,
                                      MACH_MSG_TYPE_COPY_SEND, &port, &type ))
        {
            ret = __pthread_kill( port, sig );
            mach_port_deallocate( mach_task_self(), port );
        }
        else errno = ESRCH;

        if (ret == -1 && errno == ESRCH) /* thread got killed */
        {
            thread->unix_pid = -1;
            thread->unix_tid = -1;
        }
    }
    return (ret != -1);
}

/* read data from a process memory space */
int read_process_memory( struct process *process, const void *ptr, data_size_t size, char *dest )
{
    kern_return_t ret;
    mach_msg_type_number_t bytes_read;
    vm_offset_t offset, data;
    vm_address_t aligned_address;
    vm_size_t aligned_size;
    unsigned int page_size = get_page_size();
    mach_port_t process_port = get_process_port( process );

    if (!process_port)
    {
        set_error( STATUS_ACCESS_DENIED );
        return 0;
    }

    if ((ret = task_suspend( process_port )) != KERN_SUCCESS)
    {
        mach_set_error( ret );
        return 0;
    }

    offset = (unsigned long)ptr % page_size;
    aligned_address = (vm_address_t)((char *)ptr - offset);
    aligned_size = (size + offset + page_size - 1) / page_size * page_size;

    ret = vm_read( process_port, aligned_address, aligned_size, &data, &bytes_read );
    if (ret != KERN_SUCCESS) mach_set_error( ret );
    else
    {
        memcpy( dest, (char *)data + offset, size );
        vm_deallocate( mach_task_self(), data, bytes_read );
    }
    task_resume( process_port );
    return (ret == KERN_SUCCESS);
}

/* write data to a process memory space */
int write_process_memory( struct process *process, void *ptr, data_size_t size, const char *src )
{
    kern_return_t ret;
    vm_address_t aligned_address, region_address;
    vm_size_t aligned_size, region_size;
    mach_msg_type_number_t info_size, bytes_read;
    vm_offset_t offset, task_mem = 0;
    struct vm_region_basic_info info;
    mach_port_t dummy;
    unsigned int page_size = get_page_size();
    mach_port_t process_port = get_process_port( process );

    if (!process_port)
    {
        set_error( STATUS_ACCESS_DENIED );
        return 0;
    }

    offset = (unsigned long)ptr % page_size;
    aligned_address = (vm_address_t)((char *)ptr - offset);
    aligned_size = (size + offset + page_size - 1) / page_size * page_size;

    if ((ret = task_suspend( process_port )) != KERN_SUCCESS)
    {
        mach_set_error( ret );
        return 0;
    }

    ret = vm_read( process_port, aligned_address, aligned_size, &task_mem, &bytes_read );
    if (ret != KERN_SUCCESS)
    {
        mach_set_error( ret );
        goto failed;
    }
    region_address = aligned_address;
    info_size = sizeof(info);
    ret = vm_region( process_port, &region_address, &region_size, VM_REGION_BASIC_INFO,
                     (vm_region_info_t)&info, &info_size, &dummy );
    if (ret != KERN_SUCCESS)
    {
        mach_set_error( ret );
        goto failed;
    }
    if (region_address > aligned_address ||
        region_address + region_size < aligned_address + aligned_size)
    {
        /* FIXME: should support multiple regions */
        set_error( ERROR_ACCESS_DENIED );
        goto failed;
    }
    ret = vm_protect( process_port, aligned_address, aligned_size, 0, VM_PROT_READ | VM_PROT_WRITE );
    if (ret != KERN_SUCCESS)
    {
        mach_set_error( ret );
        goto failed;
    }

    /* FIXME: there's an optimization that can be made: check first and last */
    /* pages for writability; read first and last pages; write interior */
    /* pages to task without ever reading&modifying them; if that succeeds, */
    /* modify first and last pages and write them. */

    memcpy( (char*)task_mem + offset, src, size );

    ret = vm_write( process_port, aligned_address, task_mem, bytes_read );
    if (ret != KERN_SUCCESS) mach_set_error( ret );
    else
    {
        vm_deallocate( mach_task_self(), task_mem, bytes_read );
        /* restore protection */
        vm_protect( process_port, aligned_address, aligned_size, 0, info.protection );
        task_resume( process_port );
        return 1;
    }

failed:
    if (task_mem) vm_deallocate( mach_task_self(), task_mem, bytes_read );
    task_resume( process_port );
    return 0;
}

/* retrieve an LDT selector entry */
void get_selector_entry( struct thread *thread, int entry, unsigned int *base,
                         unsigned int *limit, unsigned char *flags )
{
    const unsigned int total_size = (2 * sizeof(int) + 1) * 8192;
    struct process *process = thread->process;
    unsigned int page_size = get_page_size();
    vm_offset_t data;
    kern_return_t ret;
    mach_msg_type_number_t bytes_read;
    mach_port_t process_port = get_process_port( thread->process );

    if (!process->ldt_copy || !process_port)
    {
        set_error( STATUS_ACCESS_DENIED );
        return;
    }
    if (entry >= 8192)
    {
        set_error( STATUS_INVALID_PARAMETER );  /* FIXME */
        return;
    }

    if ((ret = task_suspend( process_port )) == KERN_SUCCESS)
    {
        void *ptr = process->ldt_copy;
        vm_offset_t offset = (unsigned long)ptr % page_size;
        vm_address_t aligned_address = (vm_address_t)((char *)ptr - offset);
        vm_size_t aligned_size = (total_size + offset + page_size - 1) / page_size * page_size;

        ret = vm_read( process_port, aligned_address, aligned_size, &data, &bytes_read );
        if (ret != KERN_SUCCESS) mach_set_error( ret );
        else
        {
            const int *ldt = (const int *)((char *)data + offset);
            memcpy( base, ldt + entry, sizeof(int) );
            memcpy( limit, ldt + entry + 8192, sizeof(int) );
            memcpy( flags, (char *)(ldt + 2 * 8192) + entry, 1 );
            vm_deallocate( mach_task_self(), data, bytes_read );
        }
        task_resume( process_port );
    }
    else mach_set_error( ret );
}

#endif  /* USE_MACH */
