/*
 * LDT manipulation functions
 *
 * Copyright 1993 Robert J. Amstadt
 * Copyright 1995 Alexandre Julliard
 */

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
#include "ldt.h"
#include "stddebug.h"
#include "debug.h"

#ifndef WINELIB

#ifdef linux
#include <linux/unistd.h>
#include <linux/head.h>
#include <linux/ldt.h>

_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
#endif  /* linux */

#if defined(__NetBSD__) || defined(__FreeBSD__)
#include <machine/segments.h>

extern int i386_get_ldt(int, union descriptor *, int);
extern int i386_set_ldt(int, union descriptor *, int);
#endif  /* __NetBSD__ || __FreeBSD__ */

#endif  /* ifndef WINELIB */


ldt_copy_entry ldt_copy[LDT_SIZE] = { {0,0}, };
unsigned char ldt_flags_copy[LDT_SIZE] = { 0, };

        
/***********************************************************************
 *           LDT_BytesToEntry
 *
 * Convert the raw bytes of the descriptor to an ldt_entry structure.
 */
void LDT_BytesToEntry( const unsigned long *buffer, ldt_entry *content )
{
    content->base  = (*buffer >> 16) & 0x0000ffff;
    content->limit = *buffer & 0x0000ffff;
    buffer++;
    content->base  |= (*buffer & 0xff000000) | ((*buffer << 16) & 0x00ff0000);
    content->limit |= (*buffer & 0x000f0000);
    content->type           = (*buffer >> 10) & 3;
    content->seg_32bit      = (*buffer & 0x00400000) != 0;
    content->read_only      = (*buffer & 0x00000200) == 0;
    content->limit_in_pages = (*buffer & 0x00800000) != 0;
}


/***********************************************************************
 *           LDT_EntryToBytes
 *
 * Convert an ldt_entry structure to the raw bytes of the descriptor.
 */
void LDT_EntryToBytes( unsigned long *buffer, const ldt_entry *content )
{
    *buffer++ = ((content->base & 0x0000ffff) << 16) |
                 (content->limit & 0x0ffff);
    *buffer = (content->base & 0xff000000) |
              ((content->base & 0x00ff0000)>>16) |
              (content->limit & 0xf0000) |
              (content->type << 10) |
              ((content->read_only == 0) << 9) |
              ((content->seg_32bit != 0) << 22) |
              ((content->limit_in_pages != 0) << 23) |
              0xf000;
}


/***********************************************************************
 *           LDT_GetEntry
 *
 * Retrieve an LDT entry.
 */
int LDT_GetEntry( int entry, ldt_entry *content )
{
    int ret = 0;

    content->base           = ldt_copy[entry].base;
    content->limit          = ldt_copy[entry].limit;
    content->type           = (ldt_flags_copy[entry] & LDT_FLAGS_TYPE);
    content->seg_32bit      = (ldt_flags_copy[entry] & LDT_FLAGS_32BIT) != 0;
    content->read_only      = (ldt_flags_copy[entry] & LDT_FLAGS_READONLY) !=0;
    content->limit_in_pages = (ldt_flags_copy[entry] & LDT_FLAGS_BIG) !=0;
    return ret;
}


/***********************************************************************
 *           LDT_SetEntry
 *
 * Set an LDT entry.
 */
int LDT_SetEntry( int entry, const ldt_entry *content )
{
    int ret = 0;

    dprintf_ldt(stddeb,
	  "LDT_SetEntry: entry=%04x base=%08lx limit=%05lx %s %d-bit flags=%c%c%c\n",
          entry, content->base, content->limit,
          content->limit_in_pages ? "pages" : "bytes",
          content->seg_32bit ? 32 : 16,
          content->read_only && (content->type & SEGMENT_CODE) ? '-' : 'r',
          content->read_only || (content->type & SEGMENT_CODE) ? '-' : 'w',
          (content->type & SEGMENT_CODE) ? 'x' : '-' );

    /* Entry 0 must not be modified; its base and limit are always 0 */
    if (!entry) return 0;

#ifndef WINELIB
#ifdef linux
    {
        struct modify_ldt_ldt_s ldt_info;

        memset( &ldt_info, 0, sizeof(ldt_info) );
        ldt_info.entry_number   = entry;
        ldt_info.base_addr      = content->base;
        ldt_info.limit          = content->limit;
        ldt_info.seg_32bit      = content->seg_32bit != 0;
        ldt_info.contents       = content->type;
        ldt_info.read_exec_only = content->read_only != 0;
        ldt_info.limit_in_pages = content->limit_in_pages != 0;
        ret = modify_ldt(1, &ldt_info, sizeof(ldt_info));
    }
#endif  /* linux */

#if defined(__NetBSD__) || defined(__FreeBSD__)
    {
        long d[2];

        LDT_EntryToBytes( d, content );
        ret = i386_set_ldt(entry, (union descriptor *)d, 1);
        if (ret < 0)
        {
            perror("i386_set_ldt");
            fprintf(stderr,
		"Did you reconfigure the kernel with \"options USER_LDT\"?\n");
    	    exit(1);
        }
    }
#endif  /* __NetBSD__ || __FreeBSD__ */
#endif  /* ifndef WINELIB */

    if (ret < 0) return ret;
    ldt_copy[entry].base = content->base;
    if (!content->limit_in_pages) ldt_copy[entry].limit = content->limit;
    else ldt_copy[entry].limit = (content->limit << 12) | 0x0fff;
    ldt_flags_copy[entry] = (content->type & LDT_FLAGS_TYPE) |
                            (content->read_only ? LDT_FLAGS_READONLY : 0) |
                            (content->seg_32bit ? LDT_FLAGS_32BIT : 0) |
                            (content->limit_in_pages ? LDT_FLAGS_BIG : 0) |
                            (ldt_flags_copy[entry] & LDT_FLAGS_ALLOCATED);
    return ret;
}


/***********************************************************************
 *           LDT_Print
 *
 * Print the content of the LDT on stdout.
 */
void LDT_Print()
{
    int i;
    char flags[3];

    for (i = 0; i < LDT_SIZE; i++)
    {
        if (!ldt_copy[i].base && !ldt_copy[i].limit) continue; /* Free entry */
        if ((ldt_flags_copy[i] & LDT_FLAGS_TYPE) == SEGMENT_CODE)
        {
            flags[0] = (ldt_flags_copy[i] & LDT_FLAGS_EXECONLY) ? '-' : 'r';
            flags[1] = '-';
            flags[2] = 'x';
        }
        else
        {
            flags[0] = 'r';
            flags[1] = (ldt_flags_copy[i] & LDT_FLAGS_READONLY) ? '-' : 'w';
            flags[2] = '-';
        }
        printf("%04x: sel=%04x base=%08lx limit=%05lx %s %d-bit %c%c%c\n",
                i, ENTRY_TO_SELECTOR(i),
                ldt_copy[i].base, ldt_copy[i].limit,
                ldt_flags_copy[i] & LDT_FLAGS_BIG ? "(pages)" : "(bytes)",
                ldt_flags_copy[i] & LDT_FLAGS_32BIT ? 32 : 16,
                flags[0], flags[1], flags[2] );
    }
}
