plsacc.c

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

C
1,153
字号
}

//OBSOLETE - use ReqWrite_regs
unsigned ReqWrite_fpu()
{
    _DBG(("AccWriteFPU\r\n"));
    TaskFPExec( (ULONG)&Write387, GetInPtr(sizeof(write_fpu_req)) );
    _DBG(("exit AccWriteFPU\r\n"));
    return( 0 );
}

unsigned ReqRead_regs( void )
{
    mad_registers       *mr;

    mr = GetOutPtr(0);
    ReadCPU( &mr->x86.cpu );
    TaskFPExec( (ULONG)&Read387, &mr->x86.fpu );
    return( sizeof( mr->x86 ) );
}

unsigned ReqWrite_regs( void )
{
    mad_registers       *mr;

    mr = GetInPtr(sizeof(write_regs_req));
    WriteCPU( &mr->x86.cpu );
    TaskFPExec( (ULONG)&Write387, &mr->x86.fpu );
    return( 0 );
}

static int map_dbe( int err )
{
    if( err == 0 ) return( err );
    return( -err + DBE_BASE );
}

static void CheckForPE( char *name )
{
    int                 handle;
    unsigned_32         off;
    unsigned            i;
    pe_object           obj;
    union {
        dos_exe_header  dos;
        pe_header       pe;
    }   head;

    handle = open( name, O_BINARY | O_RDONLY, 0 );
    if( handle == -1 ) return;
    read( handle, &head.dos, sizeof( head.dos ) );
    if( head.dos.signature != DOS_SIGNATURE ) {
        close( handle );
        return;
    }
    lseek( handle, OS2_NE_OFFSET, SEEK_SET );
    read( handle, &off, sizeof( off ) );
    lseek( handle, off, SEEK_SET );
    read( handle, &head.pe, sizeof( head.pe ) );
    switch( head.pe.signature ) {
    case PE_SIGNATURE:
    case PL_SIGNATURE:
        for( i = 0; i < head.pe.num_objects; ++i ) {
            read( handle, &obj, sizeof( obj ) );
            ObjOffReloc[i] = Mach.msb_eip - head.pe.entry_rva + obj.rva;
        }
        break;
    }
    close( handle );
}


unsigned ReqProg_load()
{
    char        ch;
    char        *src;
    char        *dst;
    char        *name;
    prog_load_ret       *ret;
    unsigned            len;

    _DBG(("AccLoadProg\r\n"));
    memset( ObjOffReloc, 0, sizeof( ObjOffReloc ) );
    AtEnd = FALSE;
    ReportedAlias = FALSE;
    dst = UtilBuff + 1;
    name = GetInPtr( sizeof( prog_load_req ) );
    src = name;
    ret = GetOutPtr( 0 );
    while( *src != '\0' ) ++src;
    ++src;
    len = GetTotalSize() - (src - name) - sizeof( prog_load_req );
    for( ;; ) {
        if( len == 0 ) break;
        ch = *src;
        if( ch == '\0' ) ch = ' ';
        *dst = ch;
        ++src;
        ++dst;
        --len;
    }
    if( dst > UtilBuff ) --dst;

    *dst = '\r';
    UtilBuff[ 0 ] = dst - (UtilBuff + 1);
    ret->err = map_dbe( dbg_load( name, NULL, UtilBuff ) );
    if( ret->err == 0 ) {
        HavePSP = TRUE;
    }
    FakeBreak = 1;
//  _dil_global._action_flags |= ACT_DIS387;
    FakeBreak = 0;
    dbg_rdmsb( &Mach );
    if( Mach.msb_protmf ) {
        //loadret->flags = LD_FLAG_IS_32 | LD_FLAG_IS_FLAT | LD_FLAG_IS_PROT;
        _DBG(("LD_FLAG_IS_PROT!!!\r\n"));
        ret->flags = LD_FLAG_IS_32 | LD_FLAG_IS_PROT;
        ret->task_id = 4;
        CheckForPE( name );
    } else {
        _DBG(("Not Protected mode?!!!\r\n"));
        ret->flags = LD_FLAG_IS_32;
        ret->task_id = Mach.msb_ds;
    }
    ret->mod_handle = 0;
    InitialSS = Mach.msb_ss;
    InitialCS = Mach.msb_cs;
    Mach.msb_event = -1;
    return( sizeof( *ret ) );
}

#pragma aux finit = ".387" "finit" "wait"
extern void finit( void );

unsigned ReqProg_kill()
{
    prog_kill_ret       *ret;

    _DBG(("AccKillProg\r\n"));
    ret = GetOutPtr( 0 );
    SaveStdIn = NIL_DOS_HANDLE;
    SaveStdOut = NIL_DOS_HANDLE;
    AtEnd = TRUE;
    if( RealNPXType != X86_NO ) {
        /* mask ALL floating point exception bits */
        finit();
        Mach.msb_87ctrl = 0x37f;
        dbg_wrmsb( &Mach );
    }
    SetMSW( SaveMSW );
    dbg_kill();
    HavePSP = FALSE;
    ret->err = 0;
    Mach.msb_event = -1;
    return( sizeof( *ret ) );
}


int MapReturn()
{
    switch( Mach.msb_event )
    {
    case 1:
        if( Mach.msb_dreg[ 6 ] & DR6_BS ) {
            return( COND_TRACE );
        } else if( Mach.msb_dreg[ 6 ] & ( DR6_B0+DR6_B1+DR6_B2+DR6_B3 ) ) {
            return( COND_WATCH );
        } else {
            return( COND_EXCEPTION );
        }
    case 3:
        Mach.msb_eip--;
        return( COND_BREAK );
    case 32:
    case 33:
        AtEnd = TRUE;
        return( COND_TERMINATE );
    case 34: /* new linear base address */
        return( 0 );
    default:
        return( COND_EXCEPTION );
    }
}


static void FixFakeBreak()
{
    PTR386      addr;

    addr.selector = Mach.msb_cs;
    addr.offset = Mach.msb_eip;
    ReadWrite( WriteMemory, &addr, (char *)&SavedByte, 1 );
}


static int Execute()
{
    int         err;
    int         trap;

    if( !GrabVects() ) return( COND_EXCEPTION );
    err = RunProgram();
    if( err != 0 ) {
        AtEnd = TRUE;
        return( COND_EXCEPTION );
    }
    if( dbg_rdmsb( &Mach ) != 0 ) {
        AtEnd = TRUE;
        return( COND_EXCEPTION );
    }
    ReleVects();
    trap = MapReturn();
    if( FakeBreak ) {
        FixFakeBreak();
        FakeBreak = FALSE;
        if( !AtEnd ) trap = COND_USER;
    }
    if( AtEnd ) return( COND_TERMINATE );
    return( trap );
}


unsigned ReqSet_watch()
{
    dword        l;
    watch        *curr;
    set_watch_req       *acc;
    set_watch_ret       *ret;
    int                 i,needed;
    ULONG       linear;

    _DBG(("AccSetWatch\r\n"));
    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ret->err = 1;
    ret->multiplier = 10000;
    if( WatchCount < MAX_WP ) {
        ret->err = 0;
        ReadMemory( &acc->watch_addr, 4UL, &l );
        curr = WatchPoints + WatchCount;
        curr->addr.segment = acc->watch_addr.segment;
        curr->addr.offset = acc->watch_addr.offset;
        curr->value = l;
        dbg_ptolin( &acc->watch_addr, &linear );
        curr->linear = linear;
        curr->len = acc->size;
        curr->linear &= ~(curr->len-1);
        curr->dregs = ( linear & (curr->len-1) ) ? 2 : 1;
        ++WatchCount;
        needed = 0;
        for( i = 0; i < WatchCount; ++i ) {
            needed += WatchPoints[ i ].dregs;
        }
        if( needed <= 4 ) ret->multiplier |= USING_DEBUG_REG;
    }
    return( sizeof( *ret ) );
}

unsigned ReqClear_watch()
{
    WatchCount = 0;
    return( 0 );
}

unsigned ReqSet_break()
{
    byte             ch;
    set_break_req       *acc;
    set_break_ret       *ret;

    _DBG(("AccSetBreak\r\n"));
    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ReadMemory( &acc->break_addr, 1UL, &ch );
    ret->old = ch;
    ch = 0xCC;
    WriteMemory( &acc->break_addr, 1UL, &ch );
    return( sizeof( *ret ) );
}


unsigned ReqClear_break()
{
    byte                 ch;
    clear_break_req     *acc;

    _DBG(("AccRestoreBreak\r\n"));
    acc = GetInPtr( 0 );
    ch = acc->old;
    WriteMemory( &acc->break_addr, 1UL, &ch );
    return( 0 );
}

static void SetDRnBW( int dr, ULONG linear, int len ) /* Set DRn for break on write */
{
    Mach.msb_dreg[ dr ] = linear;
    Mach.msb_dreg[ 7 ] |= ( (DRLen( len )+DR7_BWR) << DR7_RWLSHIFT( dr ) )
                       |  ( DR7_GEMASK << DR7_GLSHIFT( dr ) );
}


static bool SetDebugRegs()
{
    int         needed;
    int         i;
    int         dr;
    watch       *wp;

    needed = 0;
    for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) {
        needed += wp->dregs;
    }
    if( needed > 4 ) return( FALSE );
    dr = 0;
    Mach.msb_dreg[ 7 ] = DR7_GE;
    for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) {
        SetDRnBW( dr, wp->linear, wp->len );
        ++dr;
        if( wp->dregs == 2 ) {
            SetDRnBW( dr, wp->linear+wp->len, wp->len );
            ++dr;
        }
    }
    return( TRUE );
}


static unsigned ProgRun( bool step )
{
    watch       *wp;
    int         i;
    dword       value;
    prog_go_ret *ret;

    ret = GetOutPtr( 0 );
    Mach.msb_dreg[ 6 ] = 0;
    Mach.msb_dreg[ 7 ] = 0;
    if( AtEnd ) {
        ret->conditions = COND_TERMINATE;
    } else if( step ) {
        Mach.msb_eflags |= EF_TF;
        ret->conditions = Execute();
        Mach.msb_eflags &= ~EF_TF;
    } else if( WatchCount != 0 ) {
        if( SetDebugRegs() ) {
            ret->conditions = Execute();
            Mach.msb_dreg[ 6 ] = 0;
            Mach.msb_dreg[ 7 ] = 0;
        } else {
            for( ;; ) {
                Mach.msb_eflags |= EF_TF;
                ret->conditions = Execute();
                if( ret->conditions & COND_TERMINATE ) break;
                if( Mach.msb_event != 1 ) break;
                if( !( Mach.msb_dreg[6] & DR6_BS ) ) break;
                for( wp = WatchPoints, i = WatchCount; i > 0; ++wp, --i ) {
                    ReadMemory( &wp->addr, 4UL, &value );
                    if( value != wp->value ) {
                        ret->conditions = COND_WATCH;
                        Mach.msb_eflags &= ~EF_TF;
                        goto leave;
                    }
                }
            }
        }
    } else {
        ret->conditions = Execute();
    }
leave:
    ret->conditions |= COND_CONFIG;
    ret->program_counter.offset = Mach.msb_eip;
    ret->program_counter.segment = Mach.msb_cs;
    ret->stack_pointer.offset = Mach.msb_esp;
    ret->stack_pointer.segment = Mach.msb_ss;
    WatchCount = 0;
    return( sizeof( *ret ) );
}

unsigned ReqProg_go()
{
    _DBG(("AccProgGo\r\n"));
    return( ProgRun( FALSE ) );
}

unsigned ReqProg_step()
{
    _DBG(("AccProgStep\r\n"));
    return( ProgRun( TRUE ) );
}

unsigned ReqGet_next_alias()
{
    get_next_alias_ret  *ret;

    _DBG(("AccGetNextAlias\r\n"));
    ret = GetOutPtr( 0 );
    if( !ReportedAlias ) {
        _DBG(("acc->seg == 0\r\n"));
        ret->seg = Mach.msb_cs;
        ret->alias = Mach.msb_ds;
        ReportedAlias = TRUE;
    } else {
        _DBG(("acc->seg == other\r\n"));
        ret->seg = 0;
        ret->alias = 0;
    }
    return( sizeof( *ret ) );
}

static unsigned Redirect( bool input )
{
    int             std_hndl;
    int             *var;
    int             handle;
    char            *name;
    redirect_stdout_ret *ret;

    ret = GetOutPtr( 0 );
    if( !HavePSP ) {
        ret->err = 1;
        return( sizeof( *ret ) );
    }
    SetPSP( _dil_global._chpsp );
    name = GetInPtr( sizeof( redirect_stdout_req ) );
    ret->err = 0;
    if( input ) {
        std_hndl = 0;
        var = &SaveStdIn;
    } else {
        std_hndl = 1;
        var = &SaveStdOut;
    }
    if( *name == '\0' ) {
        if( *var != NIL_DOS_HANDLE ) {
            if( dup2( *var, std_hndl ) == -1 ) {
                ret->err = 1;
            } else {
                close( *var );
                *var = NIL_DOS_HANDLE;
            }
        }
    } else {
        if( *var == NIL_DOS_HANDLE ) {
            *var = dup( std_hndl );
        }
        if( input ) {
            handle = open( name, O_BINARY | O_RDWR, 0 );
        } else {
            handle = open( name, O_BINARY | O_RDWR | O_TRUNC | O_CREAT, 0 );
        }
        if( handle == -1 ) {
            ret->err = 1;
        } else {
            dup2( handle, std_hndl );
            close( handle );
        }
    }
    SetPSP( _dil_global._psp );
    return( sizeof( *ret ) );
}

unsigned ReqRedirect_stdin()
{
    _DBG(("AccRedirectStdin\r\n"));
    return( Redirect( TRUE ) );
}

unsigned ReqRedirect_stdout()
{
    _DBG(("AccRedirectStdOut\r\n"));
    return( Redirect( FALSE ) );
}

unsigned ReqGet_err_text()
{
    static char *DosErrMsgs[] = {
#include "dosmsgs.h"
    };
    int            err;
    get_err_text_req    *acc;
    char                *err_txt;

    #define MAX_CODE (sizeof( DosErrMsgs ) / sizeof( char * ) - 1)

    _DBG(("AccErrText\r\n"));
    acc = GetInPtr( 0 );
    err_txt = GetOutPtr( 0 );
    if( acc->err > MAX_CODE ) {
        err = acc->err - DBE_BASE;
        strcpy( err_txt, DBG_ERROR );
        err_txt += sizeof( DBG_ERROR ) - 1;
        if( err < -DBE_MIN && err > -DBE_MAX ) {
            strcpy( err_txt, DBErrors[ err ] );
        } else {
            utoa( acc->err, (char *)err_txt, 16 );
        }
    } else {
        strcpy( err_txt, DosErrMsgs[ acc->err ] );
    }
    return( strlen( GetOutPtr( 0 ) ) + 1 );
}


unsigned ReqGet_message_text()
{
    get_message_text_ret        *ret;
    char                        *err_txt;

    ret = GetOutPtr( 0 );
    err_txt = GetOutPtr( sizeof(*ret) );
    if( Mach.msb_event == (USHORT)-1 ) {
        err_txt[0] = '\0';
    } else {
        ExceptionText( Mach.msb_event, err_txt );
        Mach.msb_event = -1;
    }
    ret->flags = MSG_NEWLINE | MSG_ERROR;
    return( sizeof( *ret ) + strlen( err_txt ) + 1 );
}

unsigned ReqGet_lib_name()
{
    char                *ch;
    get_lib_name_ret    *ret;

    ret = GetOutPtr( 0 );
    ret->handle = 0;
    ch = GetOutPtr( sizeof( *ret ) );
    *ch = '\0';
    return( sizeof( *ret ) + 1 );
}


trap_version TRAPENTRY TrapInit( char *parm, char *err, bool remote )
{
    trap_version        ver;
    int                 error_num;

    _DBG(( "in TrapInit\r\n" ));
    remote = remote; parm = parm;
    err[0] = '\0'; /* all ok */
    ver.major = TRAP_MAJOR_VERSION;
    ver.minor = TRAP_MINOR_VERSION;
    ver.remote = FALSE;
    //ver.is_32 = TRUE;
    SaveStdIn = NIL_DOS_HANDLE;
    SaveStdOut = NIL_DOS_HANDLE;
    SaveMSW = GetMSW();
    RealNPXType = NPXType();
    _8087 = 0;
    HavePSP = FALSE;
    WatchCount = 0;
    FakeBreak = FALSE;
    if( getenv( "DBDB" ) ) {
        _DBG(( "Calling dbg_edebug()\r\n" ));
        dbg_edebug();
    }
    _DBG(( "about to dbg_init\r\n" ));
    error_num = dbg_init( &SelBlk );
    _DBG(( "back from dbg_init\r\n" ));
    GrabPrtScrn();
    if( error_num != 0 ) {
        strcpy( err, DBG_ERROR );
        strcpy( err + sizeof( DBG_ERROR )-1, DBErrors[ -error_num ] );
    }
    Mach.msb_event = -1;
    _DBG(( "outof TrapInit\r\n" ));
    return( ver );
}

void TRAPENTRY TrapFini()
{
    RelePrtScrn();
    dbg_exit();
}

⌨️ 快捷键说明

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