/*
 * Copyright 1993 Robert J. Amstadt
 * Copyright 1995 Alexandre Julliard
 */

#include <stdio.h>

#include "dlls.h"
#include "global.h"
#include "module.h"
#include "registers.h"
#include "stackframe.h"
#include "stddebug.h"
/* #define DEBUG_RELAY */
#include "debug.h"

#if 0
/* Make make_debug think these were really used */
dprintf_relay
#endif

#define DLL_ENTRY(name) \
  { #name, name##_Code_Start, name##_Data_Start, \
    name##_Module_Start, name##_Module_End, TRUE, 0 }
#define DLL_ENTRY_NOTUSED(name) \
  { #name, name##_Code_Start, name##_Data_Start, \
    name##_Module_Start, name##_Module_End, FALSE, 0 }

struct dll_table_s dll_builtin_table[N_BUILTINS] =
{
    DLL_ENTRY(KERNEL),
    DLL_ENTRY(USER),
    DLL_ENTRY(GDI),
    DLL_ENTRY_NOTUSED(WIN87EM),
    DLL_ENTRY_NOTUSED(SHELL),
    DLL_ENTRY(SOUND),
    DLL_ENTRY(KEYBOARD),
    DLL_ENTRY(WINSOCK),
    DLL_ENTRY(STRESS),
    DLL_ENTRY(MMSYSTEM),
    DLL_ENTRY(SYSTEM),
    DLL_ENTRY(TOOLHELP),
    DLL_ENTRY(MOUSE),
    DLL_ENTRY_NOTUSED(COMMDLG),
    DLL_ENTRY_NOTUSED(OLE2),
    DLL_ENTRY_NOTUSED(OLE2CONV),
    DLL_ENTRY_NOTUSED(OLE2DISP),
    DLL_ENTRY_NOTUSED(OLE2NLS),
    DLL_ENTRY_NOTUSED(OLE2PROX),
    DLL_ENTRY_NOTUSED(OLECLI),
    DLL_ENTRY_NOTUSED(OLESVR),
    DLL_ENTRY_NOTUSED(COMPOBJ),
    DLL_ENTRY_NOTUSED(STORAGE),
    DLL_ENTRY(WINPROCS),
    DLL_ENTRY_NOTUSED(DDEML),
    DLL_ENTRY(LZEXPAND)
};

/* don't forget to increase N_BUILTINS in dlls.h if you add a dll */

  /* Saved 16-bit stack */
WORD IF1632_Saved16_ss = 0;
WORD IF1632_Saved16_sp = 0;

  /* Saved 32-bit stack */
DWORD IF1632_Saved32_esp = 0;
SEGPTR IF1632_Stack32_base = 0;
DWORD IF1632_Original32_esp = 0;

/***********************************************************************
 *           RELAY_Init
 */
BOOL RELAY_Init(void)
{
    WORD codesel;

      /* Allocate the code selector for CallTo16 routines */

    extern void CALL16_Start(), CALL16_End();
    extern void CALL16_Ret_word(), CALL16_Ret_long();
    extern DWORD CALL16_RetAddr_word, CALL16_RetAddr_long;

    codesel = GLOBAL_CreateBlock( GMEM_FIXED, (void *)CALL16_Start,
                                   (int)CALL16_End - (int)CALL16_Start,
                                   0, TRUE, TRUE, FALSE, NULL );
    if (!codesel) return FALSE;

      /* Patch the return addresses for CallTo16 routines */

    CALL16_RetAddr_word = MAKELONG( (int)CALL16_Ret_word - (int)CALL16_Start,
                                    codesel );
    CALL16_RetAddr_long = MAKELONG( (int)CALL16_Ret_long - (int)CALL16_Start,
                                    codesel );

    return TRUE;
}


/***********************************************************************
 *           RELAY_DebugCall32
 */
void RELAY_DebugCall32( int func_type, char *args,
                        void *entry_point, int args32 )
{
    STACK16FRAME *frame;
    struct dll_table_s *table;
    char *args16, *name;
    int i;

    if (!debugging_relay) return;

    frame = CURRENT_STACK16;
    table = &dll_builtin_table[frame->dll_id-1];
    name  = MODULE_GetEntryPointName( table->hModule, frame->ordinal_number );
    printf( "Call %s.%d: %*.*s(",
            table->name, frame->ordinal_number, *name, *name, name + 1 );

    args16 = (char *)frame->args;
    for (i = 0; i < strlen(args); i++)
    {
        switch(args[i])
        {
        case 'w':
        case 's':
            args16 += 2;
            break;
        case 'l':
        case 'p':
            args16 += 4;
            break;
        }
    }

    while (*args)
    {
        switch(*args)
        {
        case 'w':
        case 's':
            args16 -= 2;
            printf( "0x%04x", *(WORD *)args16 );
            break;
        case 'l':
            args16 -= 4;
            printf( "0x%08x", *(int *)args16 );
            break;
        case 'p':
            args16 -= 4;
            printf( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 );
            break;
        }
        args++;
        if (*args) printf( "," );
    }
    printf( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds );

    if (func_type == 2)  /* register function */
    {
        struct sigcontext_struct *context = (struct sigcontext_struct *)&args32;
        printf( "     AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
                AX_reg(context), BX_reg(context), CX_reg(context),
                DX_reg(context), SI_reg(context), DI_reg(context),
                ES_reg(context), EFL_reg(context) );
    }
}


/***********************************************************************
 *           RELAY_DebugReturn
 */
void RELAY_DebugReturn( int func_type, int ret_val, int args32 )
{
    STACK16FRAME *frame;
    struct dll_table_s *table;
    char *name;

    if (*(DWORD *)PTR_SEG_TO_LIN(IF1632_Stack32_base) != 0xDEADBEEF)
    {
	fprintf(stderr, "Wine wrote past the end of the 32 bit stack. Please report this.\n");
        exit(1);  /* There's probably no point in going on */
    }
    if (!debugging_relay) return;

    frame = CURRENT_STACK16;
    table = &dll_builtin_table[frame->dll_id-1];
    name  = MODULE_GetEntryPointName( table->hModule, frame->ordinal_number );
    printf( "Ret  %s.%d: %*.*s() ",
            table->name, frame->ordinal_number, *name, *name, name + 1 );
    switch(func_type)
    {
    case 0: /* long */
        printf( "retval=0x%08x ret=%04x:%04x ds=%04x\n",
                ret_val, frame->cs, frame->ip, frame->ds );
        break;
    case 1: /* word */
        printf( "retval=0x%04x ret=%04x:%04x ds=%04x\n",
                ret_val & 0xffff, frame->cs, frame->ip, frame->ds );
        break;
    case 2: /* regs */
        printf( "retval=none ret=%04x:%04x ds=%04x\n",
                frame->cs, frame->ip, frame->ds );
        {
            struct sigcontext_struct *context = (struct sigcontext_struct *)&args32;
            printf( "     AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
                    AX_reg(context), BX_reg(context), CX_reg(context),
                    DX_reg(context), SI_reg(context), DI_reg(context),
                    ES_reg(context), EFL_reg(context) );
        }
        break;
    }
}


/***********************************************************************
 *           RELAY_Unimplemented
 *
 * This function is called for unimplemented entry points (declared
 * as 'stub' in the spec file).
 */
void RELAY_Unimplemented(void)
{
    STACK16FRAME *frame = CURRENT_STACK16;
    struct dll_table_s *table = &dll_builtin_table[frame->dll_id-1];
    char *name = MODULE_GetEntryPointName( table->hModule, frame->ordinal_number );

    fprintf( stderr, "No handler for routine %s.%d (%*.*s)\n",
             table->name, frame->ordinal_number, *name, *name, name + 1 );
    exit(1);
}


/***********************************************************************
 *           RELAY_DebugCall16
 *
 * 'stack' points to the called function address on the 32-bit stack.
 * Stack layout:
 *  ...        ...
 * (stack+12)  arg2
 * (stack+8)   arg1
 * (stack+4)   16-bit ds
 * (stack)     func to call
 */
void RELAY_DebugCall16( int* stack, int nbargs )
{
    if (!debugging_relay) return;

    printf( "CallTo16(func=%04x:%04x,ds=%04x",
            HIWORD(stack[0]), LOWORD(stack[0]), LOWORD(stack[1]) );
    stack += 2;
    while (nbargs--) printf( ",0x%04x", *stack++ );
    printf( ")\n" );
}
