/*
 * LDT manipulation functions
 *
 * Copyright 1993 Robert J. Amstadt
 * Copyright 1995 Alexandre Julliard
 *
 * 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 "wine/port.h"

#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include "windef.h"
#include "winbase.h"
#include "wine/library.h"

#if defined(__i386__) && !defined(__MINGW32__) && !defined(_MSC_VER)

#ifdef __linux__

#ifdef HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
#endif

struct modify_ldt_s
{
    unsigned int  entry_number;
    unsigned long base_addr;
    unsigned int  limit;
    unsigned int  seg_32bit : 1;
    unsigned int  contents : 2;
    unsigned int  read_exec_only : 1;
    unsigned int  limit_in_pages : 1;
    unsigned int  seg_not_present : 1;
    unsigned int  usable : 1;
    unsigned int  garbage : 25;
};

static inline void fill_modify_ldt_struct( struct modify_ldt_s *ptr, const LDT_ENTRY *entry )
{
    ptr->base_addr       = (unsigned long)wine_ldt_get_base(entry);
    ptr->limit           = entry->LimitLow | (entry->HighWord.Bits.LimitHi << 16);
    ptr->seg_32bit       = entry->HighWord.Bits.Default_Big;
    ptr->contents        = (entry->HighWord.Bits.Type >> 2) & 3;
    ptr->read_exec_only  = !(entry->HighWord.Bits.Type & 2);
    ptr->limit_in_pages  = entry->HighWord.Bits.Granularity;
    ptr->seg_not_present = !entry->HighWord.Bits.Pres;
    ptr->usable          = entry->HighWord.Bits.Sys;
    ptr->garbage         = 0;
}

static inline int modify_ldt( int func, struct modify_ldt_s *ptr, unsigned long count )
{
    int res;
    __asm__ __volatile__( "pushl %%ebx\n\t"
                          "movl %2,%%ebx\n\t"
                          "int $0x80\n\t"
                          "popl %%ebx"
                          : "=a" (res)
                          : "0" (SYS_modify_ldt),
                            "r" (func),
                            "c" (ptr),
                            "d" (count),
                            "m" (*ptr) );
    if (res >= 0) return res;
    errno = -res;
    return -1;
}

static inline int set_thread_area( struct modify_ldt_s *ptr )
{
    int res;
    __asm__ __volatile__( "pushl %%ebx\n\t"
                          "movl %3,%%ebx\n\t"
                          "int $0x80\n\t"
                          "popl %%ebx"
                          : "=a" (res), "=m" (*ptr)
                          : "0" (243) /* SYS_set_thread_area */, "q" (ptr), "m" (*ptr) );
    if (res >= 0) return res;
    errno = -res;
    return -1;
}

#endif  /* linux */

#if defined(__svr4__) || defined(_SCO_DS)
#include <sys/sysi86.h>
#ifndef __sun__
#include <sys/seg.h>
#endif
#endif

#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
#include <machine/segments.h>
#include <machine/sysarch.h>
#endif  /* __NetBSD__ || __FreeBSD__ || __OpenBSD__ */

#ifdef __APPLE__
#include <i386/user_ldt.h>
#endif

/* local copy of the LDT */
#ifdef __APPLE__
struct __wine_ldt_copy wine_ldt_copy = { { 0, 0, 0 } };
#else
struct __wine_ldt_copy wine_ldt_copy;
#endif

static const LDT_ENTRY null_entry;  /* all-zeros, used to clear LDT entries */

#define LDT_FIRST_ENTRY 512
#define LDT_SIZE 8192

/* empty function for default locks */
static void nop(void) { }

static void (*lock_ldt)(void) = nop;
static void (*unlock_ldt)(void) = nop;


static inline int is_gdt_sel( unsigned short sel ) { return !(sel & 4); }

/***********************************************************************
 *           wine_ldt_init_locking
 *
 * Set the LDT locking/unlocking functions.
 */
void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) )
{
    lock_ldt = lock_func;
    unlock_ldt = unlock_func;
}


/***********************************************************************
 *           wine_ldt_get_entry
 *
 * Retrieve an LDT entry. Return a null entry if selector is not allocated.
 */
void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry )
{
    int index = sel >> 3;

    if (is_gdt_sel(sel))
    {
        *entry = null_entry;
        return;
    }
    lock_ldt();
    if (wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
    {
        wine_ldt_set_base(  entry, wine_ldt_copy.base[index] );
        wine_ldt_set_limit( entry, wine_ldt_copy.limit[index] );
        wine_ldt_set_flags( entry, wine_ldt_copy.flags[index] );
    }
    else *entry = null_entry;
    unlock_ldt();
}


/***********************************************************************
 *           internal_set_entry
 *
 * Set an LDT entry, without locking. For internal use only.
 */
static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
{
    int ret = 0, index = sel >> 3;

    if (index < LDT_FIRST_ENTRY) return 0;  /* cannot modify reserved entries */

#ifdef linux
    {
        struct modify_ldt_s ldt_info;

        ldt_info.entry_number = index;
        fill_modify_ldt_struct( &ldt_info, entry );
        if ((ret = modify_ldt(0x11, &ldt_info, sizeof(ldt_info))) < 0)
            perror( "modify_ldt" );
    }
#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
    {
	LDT_ENTRY entry_copy = *entry;
	/* The kernel will only let us set LDTs with user priority level */
	if (entry_copy.HighWord.Bits.Pres
	    && entry_copy.HighWord.Bits.Dpl != 3)
		entry_copy.HighWord.Bits.Dpl = 3;
        ret = i386_set_ldt(index, (union descriptor *)&entry_copy, 1);
        if (ret < 0)
        {
            perror("i386_set_ldt");
            fprintf( stderr, "Did you reconfigure the kernel with \"options USER_LDT\"?\n" );
            exit(1);
        }
    }
#elif defined(__svr4__) || defined(_SCO_DS)
    {
        struct ssd ldt_mod;
        ldt_mod.sel  = sel;
        ldt_mod.bo   = (unsigned long)wine_ldt_get_base(entry);
        ldt_mod.ls   = entry->LimitLow | (entry->HighWord.Bits.LimitHi << 16);
        ldt_mod.acc1 = entry->HighWord.Bytes.Flags1;
        ldt_mod.acc2 = entry->HighWord.Bytes.Flags2 >> 4;
        if ((ret = sysi86(SI86DSCR, &ldt_mod)) == -1) perror("sysi86");
    }
#elif defined(__APPLE__)
    if ((ret = i386_set_ldt(index, (union ldt_entry *)entry, 1)) < 0)
        perror("i386_set_ldt");
#else
    fprintf( stderr, "No LDT support on this platform\n" );
    exit(1);
#endif

    if (ret >= 0)
    {
        wine_ldt_copy.base[index]  = wine_ldt_get_base(entry);
        wine_ldt_copy.limit[index] = wine_ldt_get_limit(entry);
        wine_ldt_copy.flags[index] = (entry->HighWord.Bits.Type |
                                 (entry->HighWord.Bits.Default_Big ? WINE_LDT_FLAGS_32BIT : 0) |
                                 (wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_ALLOCATED));
    }
    return ret;
}


/***********************************************************************
 *           wine_ldt_set_entry
 *
 * Set an LDT entry.
 */
int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry )
{
    int ret;

    lock_ldt();
    ret = internal_set_entry( sel, entry );
    unlock_ldt();
    return ret;
}


/***********************************************************************
 *           wine_ldt_is_system
 *
 * Check if the selector is a system selector (i.e. not managed by Wine).
 */
int wine_ldt_is_system( unsigned short sel )
{
    return is_gdt_sel(sel) || ((sel >> 3) < LDT_FIRST_ENTRY);
}


/***********************************************************************
 *           wine_ldt_get_ptr
 *
 * Convert a segment:offset pair to a linear pointer.
 * Note: we don't lock the LDT since this has to be fast.
 */
void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset )
{
    int index;

    if (is_gdt_sel(sel))  /* GDT selector */
        return (void *)offset;
    if ((index = (sel >> 3)) < LDT_FIRST_ENTRY)  /* system selector */
        return (void *)offset;
    if (!(wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
    return (char *)wine_ldt_copy.base[index] + offset;
}


/***********************************************************************
 *           wine_ldt_alloc_entries
 *
 * Allocate a number of consecutive ldt entries, without setting the LDT contents.
 * Return a selector for the first entry.
 */
unsigned short wine_ldt_alloc_entries( int count )
{
    int i, index, size = 0;

    if (count <= 0) return 0;
    lock_ldt();
    for (i = LDT_FIRST_ENTRY; i < LDT_SIZE; i++)
    {
        if (wine_ldt_copy.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
        else if (++size >= count)  /* found a large enough block */
        {
            index = i - size + 1;

            /* mark selectors as allocated */
            for (i = 0; i < count; i++) wine_ldt_copy.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
            unlock_ldt();
            return (index << 3) | 7;
        }
    }
    unlock_ldt();
    return 0;
}


/***********************************************************************
 *           wine_ldt_realloc_entries
 *
 * Reallocate a number of consecutive ldt entries, without changing the LDT contents.
 * Return a selector for the first entry.
 */
unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount )
{
    int i;

    if (oldcount < newcount)  /* we need to add selectors */
    {
        int index = sel >> 3;

        lock_ldt();
        /* check if the next selectors are free */
        if (index + newcount > LDT_SIZE) i = oldcount;
        else
            for (i = oldcount; i < newcount; i++)
                if (wine_ldt_copy.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;

        if (i < newcount)  /* they are not free */
        {
            wine_ldt_free_entries( sel, oldcount );
            sel = wine_ldt_alloc_entries( newcount );
        }
        else  /* mark the selectors as allocated */
        {
            for (i = oldcount; i < newcount; i++)
                wine_ldt_copy.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
        }
        unlock_ldt();
    }
    else if (oldcount > newcount) /* we need to remove selectors */
    {
        wine_ldt_free_entries( sel + (newcount << 3), newcount - oldcount );
    }
    return sel;
}


/***********************************************************************
 *           wine_ldt_free_entries
 *
 * Free a number of consecutive ldt entries and clear their contents.
 */
void wine_ldt_free_entries( unsigned short sel, int count )
{
    int index;

    lock_ldt();
    for (index = sel >> 3; count > 0; count--, index++)
    {
        internal_set_entry( sel, &null_entry );
        wine_ldt_copy.flags[index] = 0;
    }
    unlock_ldt();
}


static int global_fs_sel = -1;  /* global selector for %fs shared among all threads */

/***********************************************************************
 *           wine_ldt_alloc_fs
 *
 * Allocate an LDT entry for a %fs selector, reusing a global
 * GDT selector if possible. Return the selector value.
 */
unsigned short wine_ldt_alloc_fs(void)
{
    if (global_fs_sel == -1)
    {
#ifdef __linux__
        struct modify_ldt_s ldt_info;
        int ret;

        /* the preloader may have allocated it already */
        global_fs_sel = wine_get_fs();
        if (global_fs_sel && is_gdt_sel(global_fs_sel)) return global_fs_sel;

        ldt_info.entry_number = -1;
        fill_modify_ldt_struct( &ldt_info, &null_entry );
        if ((ret = set_thread_area( &ldt_info ) < 0))
        {
            global_fs_sel = 0;  /* don't try it again */
            if (errno != ENOSYS) perror( "set_thread_area" );
        }
        else global_fs_sel = (ldt_info.entry_number << 3) | 3;
#elif defined(__FreeBSD__)
        global_fs_sel = GSEL( GUFS_SEL, SEL_UPL );
#endif
    }
    if (global_fs_sel > 0) return global_fs_sel;
    return wine_ldt_alloc_entries( 1 );
}


/***********************************************************************
 *           wine_ldt_init_fs
 *
 * Initialize the entry for the %fs selector of the current thread, and
 * set the thread %fs register.
 *
 * Note: this runs in the context of the new thread, so cannot acquire locks.
 */
void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry )
{
    if ((sel & ~3) == (global_fs_sel & ~3))
    {
#ifdef __linux__
        struct modify_ldt_s ldt_info;
        int ret;

        ldt_info.entry_number = sel >> 3;
        fill_modify_ldt_struct( &ldt_info, entry );
        if ((ret = set_thread_area( &ldt_info ) < 0)) perror( "set_thread_area" );
#elif defined(__FreeBSD__)
        i386_set_fsbase( wine_ldt_get_base( entry ));
#endif
    }
    else  /* LDT selector */
    {
        internal_set_entry( sel, entry );
    }
    wine_set_fs( sel );
}


/***********************************************************************
 *           wine_ldt_free_fs
 *
 * Free a %fs selector returned by wine_ldt_alloc_fs.
 */
void wine_ldt_free_fs( unsigned short sel )
{
    if (is_gdt_sel(sel)) return;  /* nothing to do */
    if (!((wine_get_fs() ^ sel) & ~3))
    {
        /* FIXME: if freeing current %fs we cannot acquire locks */
        wine_set_fs( 0 );
        internal_set_entry( sel, &null_entry );
        wine_ldt_copy.flags[sel >> 3] = 0;
    }
    else wine_ldt_free_entries( sel, 1 );
}


/***********************************************************************
 *           selector access functions
 */
__ASM_GLOBAL_FUNC( wine_get_cs, "movw %cs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ds, "movw %ds,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )

#endif /* __i386__ */
