trplddsx.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 622 行 · 第 1/2 页

C
622
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Trap file loading for DOS extended debugger.
*
****************************************************************************/


#include <i86.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include "dpmi.h"
#include "exedos.h"
#include "dbgdefn.h"
#include "dbgio.h"
#include "dsxutil.h"
#include "trpcore.h"
#include "tinyio.h"
#include "tcerr.h"

#ifdef __OSI__
#include "extender.h"
#endif

#include <conio.h>

#include <stdio.h>

extern trap_version     TrapVer;
extern unsigned         (TRAPENTRY *ReqFunc)( unsigned, mx_entry *,
                                        unsigned, mx_entry * );

#define DOS4G_COMM_VECTOR       0x15
#define NUM_BUFF_RELOCS         16
#define DEFAULT_TRP_NAME        "STD"
#define DEFAULT_TRP_EXT         "TRP"
#define PARM_SEPARATOR          ';'
#define TRAP_VECTOR             0x1a
#define PSP_ENVSEG_OFF          0x2c

#define TRAP_SIGNATURE          0xdeaf
typedef _Packed struct {
    unsigned_16         sig;
    addr32_off          init;
    addr32_off          req;
    addr32_off          fini;
} trap_file_header;

typedef _Packed struct {
    memptr      ptr;
    unsigned_16 len;
} mx_entry16;

static dos_memory               TrapMem;

static void __far               *RawPMtoRMSwitchAddr;

extern int                      EnvLkup( char *, char *, int max );
extern handle                   PathOpen( char *, uint, char * );
extern sys_handle               GetSystemHandle( handle );


unsigned_8      DPMICheck = 0;

//#define FULL_SAVE

#ifdef FULL_SAVE
#define INT_VECT_COUNT  256
#define EXCEPT_COUNT    32
#else
#define INT_VECT_COUNT
#define EXCEPT_COUNT
#endif

static unsigned_8       PMVectSaveList[INT_VECT_COUNT] = {
    0x00, 0x10, 0x21, 0x2f, 0x31, 0x33
};
#define NUM_PM_SAVE_VECTS (sizeof(PMVectSaveList)/sizeof(PMVectSaveList[0]))

static void __far *OrigPMVects[NUM_PM_SAVE_VECTS];
static void __far *SavePMVects[NUM_PM_SAVE_VECTS];

static unsigned_8       PMExceptSaveList[EXCEPT_COUNT] = {
    0x01, 0x03, 0x05
};
#define NUM_PM_SAVE_EXCEPTS (sizeof(PMExceptSaveList)/sizeof(PMExceptSaveList[0]))

static void __far *OrigPMExcepts[NUM_PM_SAVE_VECTS];
static void __far *SavePMExcepts[NUM_PM_SAVE_VECTS];

static enum {
    IS_NONE,
    IS_DPMI,
    IS_RATIONAL
}                       IntrState = IS_NONE;


extern void DoRawSwitchToRM( unsigned, unsigned, unsigned );
#pragma aux DoRawSwitchToRM =   \
        "push   ebp"            \
        "mov    edx,eax"        \
        "mov    ecx,eax"        \
        "mov    esi,eax"        \
        "lea    ebp,-8[esp]"    \
        "call   pword ptr [RawPMtoRMSwitchAddr]"        \
        "pop    ebp"            \
        parm caller [eax] [ebx] [edi]   \
        modify exact [ eax ebx ecx edx esi edi gs ];

extern void                     BackFromRealMode( void );

/*
        We zero out the registers here so that there isn't any garbage
        in the high word of them in 16-bit code. It turns out that the
        Pentium sometimes uses the full 32-bit registers even
        when the instruction specifies the 16-bit version (e.g string
        instructions.
*/
extern void DoIntSwitchToRM( void );
#pragma aux DoIntSwitchToRM =   \
        "pushad",               \
        "xor    ebp,ebp"        \
        "xor    ebx,ebx"        \
        "xor    esi,esi"        \
        "xor    edi,edi"        \
        "xor    ecx,ecx"        \
        "xor    edx,edx"        \
        "xor    eax,eax"        \
        "mov    ah,6"           \
        "mov    cx,0xffff"      \
        "int    1ah",           \
        "popad"                 \
        modify exact [];

typedef unsigned long P1616;
typedef P1616 extension_routine( unsigned, void *, void * );

static char sig_str[] = "RATIONAL DOS/4G";
static char pkg_name[] = "D32_KERNEL";
static char pkg_entry[] = "D32NullPtrCheck";

#pragma aux extension_routine parm [eax] [edx] [ebx] value [eax];
static extension_routine __far *RSI_extensions;

/* These are static because I'm not conversant with your inline asm
        facility, and this accomplished the desired result...
*/
//static void *parmp;
static P1616 _D32NullPtrCheck;

#if 0
void lookup_prep (void);
#pragma aux lookup_prep = \
        "sub eax, eax" \
        "mov ebx, OFFSET pkg_name" \
        "mov edx, OFFSET pkg_entry"

void call_prep (void);
#pragma aux call_prep = \
        "mov eax, 2" \
        "mov ebx, parmp" \
        "mov edx, _D32NullPtrCheck"
#endif

P1616 __cdecl find_entry( void )
        {
        P1616 retval = 0;

        RSI_extensions = DPMIGetVenderSpecificAPI( sig_str );
        if (RSI_extensions != NULL )
                {
                retval = RSI_extensions( 0, pkg_entry, pkg_name );
                }
        return (retval);
        }

/*      Returns 16:16 pointer to MONITOR array, describing state of hardware
        breakpoints.  You shouldn't care about the return value during your init.
*/
int __cdecl D32NullPtrCheck( unsigned short on )
        {
        static int      old_state;
        int             old;
        char            buff[128];

        if( _D32NullPtrCheck == NULL ) {
            _D32NullPtrCheck = find_entry();
            if( _D32NullPtrCheck == NULL ) return( 0 );
            EnvLkup( "DOS4G", buff, sizeof( buff ) );
            if( strstr( strupr( buff ), "NULLP" ) ) {
                old_state = 1;
            }
        }
        old = old_state;
        if( old_state != on ) {
            RSI_extensions( 2, (void *)_D32NullPtrCheck, &on );
            old_state = on;
        }
        return (old);
        }

void SaveOrigVectors( void )
{
    rm_data             *p;
    unsigned            i;
    unsigned            old;

#ifdef FULL_SAVE
    for( i = 0; i < INT_VECT_COUNT; ++i ) PMVectSaveList[i]=i;
    for( i = 0; i < EXCEPT_COUNT; ++i ) PMExceptSaveList[i]=i;
#endif
    old = D32NullPtrCheck( 0 );
    /* haven't moved things yet, so PMData isn't set up */
    p = (rm_data *)RMDataStart;
    for( i = 0; i < NUM_VECTS; ++i ) {
        p->orig_vects[i].a = MyGetRMVector( i );
    }
    D32NullPtrCheck( old );
    for( i = 0; i < NUM_PM_SAVE_VECTS; ++i ) {
        OrigPMVects[i] = DPMIGetPMInterruptVector( PMVectSaveList[i] );
    }
    for( i = 0; i < NUM_PM_SAVE_EXCEPTS; ++i ) {
        OrigPMExcepts[i] = DPMIGetPMExceptionVector( PMExceptSaveList[i] );
    }
    memcpy( p->vecttable1, p->orig_vects, sizeof( p->vecttable1 ) );
    memcpy( p->vecttable2, p->orig_vects, sizeof( p->vecttable2 ) );
    memcpy( SavePMVects, OrigPMVects, sizeof( SavePMVects ) );
    memcpy( SavePMExcepts, OrigPMExcepts, sizeof( SavePMExcepts ) );
}

void RestoreOrigVectors(void)
{
    unsigned            i;
    unsigned            old;

    for( i = 0; i < NUM_PM_SAVE_EXCEPTS; ++i ) {
        DPMISetPMExceptionVector( PMExceptSaveList[i], OrigPMExcepts[i] );
    }
    for( i = 0; i < NUM_PM_SAVE_VECTS; ++i ) {
        DPMISetPMInterruptVector( PMVectSaveList[i], OrigPMVects[i] );
    }
    old = D32NullPtrCheck( 0 );
    for( i = 0; i < NUM_VECTS; ++i ) {
        MySetRMVector( i,
                PMData->orig_vects[i].s.segment,
                PMData->orig_vects[i].s.offset );
    }
    D32NullPtrCheck( old );
}

static void GoToRealMode( void *rm_func )
{
    unsigned    i;

    PMData->rm_func = RM_OFF( rm_func );
    if( IntrState == IS_DPMI ) {
        for( i = 0; i < NUM_PM_SAVE_VECTS; ++i ) {
            DPMISetPMInterruptVector( PMVectSaveList[i], SavePMVects[i] );
        }
        for( i = 0; i < NUM_PM_SAVE_EXCEPTS; ++i ) {
            DPMISetPMExceptionVector( PMExceptSaveList[i], SavePMExcepts[i] );
        }
        DoRawSwitchToRM( RMData.s.rm,
                        offsetof( rm_data, stack )+STACK_SIZE,
                        RM_OFF( RawSwitchHandler ) );
        for( i = 0; i < NUM_PM_SAVE_EXCEPTS; ++i ) {
            SavePMExcepts[i] = DPMIGetPMExceptionVector(PMExceptSaveList[i]);
            DPMISetPMExceptionVector( PMExceptSaveList[i], OrigPMExcepts[i] );
        }
        for( i = 0; i < NUM_PM_SAVE_VECTS; ++i ) {
            SavePMVects[i] = DPMIGetPMInterruptVector( PMVectSaveList[i] );
            DPMISetPMInterruptVector( PMVectSaveList[i], OrigPMVects[i] );
        }
    } else {
        DoIntSwitchToRM();
    }
}

static uint_16 EnvAreaSize( char __far *envarea )
{
    char                __far *envptr;

    envptr = envarea;
    while( *envptr ) {
        envptr += _fstrlen( envptr ) + 1;
    }
    return( envptr - envarea + 1 );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?