⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os2v1acc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
}


unsigned ReqRead_mem()
{
    read_mem_req        *acc;
    void                *ret;
    unsigned            len;

    acc = GetInPtr(0);
    ret = GetOutPtr(0);

    len = ReadBuffer(ret,acc->mem_addr.segment,acc->mem_addr.offset,acc->len);
    return( len );
}


unsigned ReqWrite_mem()
{
    write_mem_req       *acc;
    write_mem_ret       *ret;
    unsigned            len;

    acc = GetInPtr(0);
    ret = GetOutPtr(0);

    len = GetTotalSize() - sizeof(*acc);

    ret->len = WriteBuffer( GetInPtr(sizeof(*ret)),
                            acc->mem_addr.segment, acc->mem_addr.offset, len );
    return( sizeof( *ret ) );
}

static void ReadCPU( struct x86_cpu *r )
{
    r->eax = Buff.u.r.AX;
    r->ebx = Buff.u.r.BX;
    r->ecx = Buff.u.r.CX;
    r->edx = Buff.u.r.DX;
    r->esi = Buff.u.r.SI;
    r->edi = Buff.u.r.DI;
    r->esp = Buff.u.r.SP;
    r->ebp = Buff.u.r.BP;
    r->eip = Buff.u.r.IP;
    r->efl = Buff.u.r.FL;
    r->ds  = Buff.u.r.DS;
    r->cs  = Buff.u.r.CS;
    r->es  = Buff.u.r.ES;
    r->ss  = Buff.u.r.SS;
}

static void WriteCPU( struct x86_cpu *r )
{
    Buff.u.r.AX = r->eax;
    Buff.u.r.BX = r->ebx;
    Buff.u.r.CX = r->ecx;
    Buff.u.r.DX = r->edx;
    Buff.u.r.SI = r->esi;
    Buff.u.r.DI = r->edi;
    Buff.u.r.SP = r->esp;
    Buff.u.r.BP = r->ebp;
    Buff.u.r.IP = r->eip;
    Buff.u.r.FL = r->efl;
    Buff.u.r.DS = r->ds;
    Buff.u.r.CS = r->cs;
    Buff.u.r.ES = r->es;
    Buff.u.r.SS = r->ss;
}

unsigned ReqRead_cpu()
{
    word                *clr;
    read_cpu_ret        *ret;

    ret = GetOutPtr(0);
    for( clr = (word *)&ret->cpu;
        (char *)clr < (char *)&ret->cpu + sizeof(trap_cpu_regs); ++clr ) {
        *clr = 0;
    }
    if( Pid != 0 ) {
        ReadRegs( &Buff );
        ReadCPU( (struct x86_cpu *)&ret->cpu );
    }
    return( sizeof( read_cpu_ret ) );
}

unsigned ReqRead_fpu()
{
    read_fpu_ret        *ret;
    TID                 save;

    ret = GetOutPtr(0);
    Buff.cmd = PT_CMD_READ_8087;
    Buff.segv = FP_SEG( ret );
    Buff.offv = FP_OFF( ret );
    save = Buff.tid;
    Buff.tid = 1;   /*NYI: OS/2 V1.2 gets upset trying to read other tids */
    DosPTrace( &Buff );
    Buff.tid = save;
    if( Buff.cmd == PT_RET_NO_NPX_YET ) return( 0 );
    FPUExpand( ret );
    return( sizeof( *ret ) );
}

unsigned ReqWrite_cpu()
{
    trap_cpu_regs       *regs;

    regs = GetInPtr(sizeof(write_cpu_req));
    if( Pid != 0 ) {
        WriteCPU( (struct x86_cpu *)regs );
        WriteRegs( &Buff );
    }
    return( 0 );
}

unsigned ReqWrite_fpu()
{
    trap_fpu_regs       *regs;
    TID                 save;

    regs = GetInPtr(sizeof(write_fpu_req));
    Buff.cmd = PT_CMD_WRITE_8087;
    Buff.segv = FP_SEG( regs );
    Buff.offv = FP_OFF( regs );
    FPUContract( regs );
    save = Buff.tid;
    Buff.tid = 1;   /*NYI: OS/2 V1.2 gets upset trying to read other tids */
    DosPTrace( &Buff );
    Buff.tid = save;
    return( 0 );
}

unsigned ReqRead_regs()
{
    mad_registers       *mr;
    TID                 save;

    mr = GetOutPtr(0);
    memset( mr, 0, sizeof( mr->x86 ) );
    if( Pid != 0 ) {
        ReadRegs( &Buff );
        ReadCPU( &mr->x86.cpu );

        Buff.cmd = PT_CMD_READ_8087;
        Buff.segv = FP_SEG( mr );
        Buff.offv = FP_OFF( &mr->x86.fpu );
        save = Buff.tid;
        Buff.tid = 1;   /*NYI: OS/2 V1.2 gets upset trying to read other tids */
        DosPTrace( &Buff );
        Buff.tid = save;
        if( Buff.cmd != PT_RET_NO_NPX_YET ) {
            FPUExpand( &mr->x86.fpu );
        }
    }
    return( sizeof( mr->x86 ) );
}

unsigned ReqWrite_regs()
{
    mad_registers       *mr;
    TID                 save;

    mr = GetInPtr(sizeof(write_regs_req));
    if( Pid != 0 ) {
        WriteCPU( &mr->x86.cpu );
        WriteRegs( &Buff );

        Buff.cmd = PT_CMD_WRITE_8087;
        Buff.segv = FP_SEG( mr );
        Buff.offv = FP_OFF( &mr->x86.fpu );
        FPUContract( &mr->x86.fpu );
        save = Buff.tid;
        Buff.tid = 1;   /*NYI: OS/2 V1.2 gets upset trying to read other tids */
        DosPTrace( &Buff );
        Buff.tid = save;
    }
    return( 0 );
}

USHORT LibLoadPTrace( TRACEBUF *buff )
{
    int         cmd;
    int         value;
    USHORT      rv;
    USHORT      offv;
    USHORT      segv;

    cmd = buff->cmd;
    value = buff->value;
    segv = buff->segv;
    offv = buff->offv;
    rv = DosPTrace( buff );
    RecordModHandle( buff->mte );
    for( ;; ) {
        if( buff->cmd != PT_RET_LIB_LOADED ) return( rv );
        RecordModHandle( buff->value );
        buff->value = value;
        buff->cmd = cmd;
        buff->offv = offv;
        buff->segv = segv;
        rv = DosPTrace( buff );
    }
}

#define EXE_IS_FULLSCREEN       0x0100
#define EXE_IS_PMC              0x0200
#define EXE_IS_PM               0x0300


static bool GetExeInfo( USHORT far *pCS, USHORT far *pIP, USHORT far *pExeType,
                        char far *name )
{
    long        open_rc;
    HFILE       handle;
    USHORT      shorty;
    USHORT      read;
    ULONG       new_head;
    ULONG       pos;
    bool        rc;

    open_rc = OpenFile( name, 0, OPEN_PRIVATE );
    if( open_rc < 0 ) return( FALSE );
    handle = open_rc;
    rc = FALSE;
    for( ;; ) { /* guess */
        if( DosChgFilePtr( handle, 0x00, 0, &pos ) != 0 ) break;
        if( DosRead( handle, &shorty, sizeof( shorty ), &read ) != 0 ) break;
        if( read != sizeof( shorty ) ) break;
        if( shorty != 0x5a4d ) break;   /* MZ */

        if( DosChgFilePtr( handle, 0x18, 0, &pos ) != 0 ) break;
        if( DosRead( handle, &shorty, sizeof( shorty ), &read ) != 0 ) break;
        if( read != sizeof( shorty ) ) break;
        if( shorty < 0x40 ) break;      /* offset of relocation header */

        if( DosChgFilePtr( handle, 0x3c, 0, &pos ) != 0 ) break;
        if( DosRead( handle, &new_head, sizeof( new_head ), &read) != 0 ) break;
        if( read != sizeof( new_head ) ) break;

        if( DosChgFilePtr( handle, new_head, 0, &pos ) != 0 ) break;
        if( DosRead( handle, &shorty, sizeof( shorty ), &read ) != 0 ) break;
        if( read != sizeof( shorty ) ) break;
        if( shorty != 0x454e ) break;   /* NE */

        if( DosChgFilePtr( handle, new_head+0x0c, 0, &pos ) != 0 ) break;
        if( DosRead(handle,pExeType,sizeof( *pExeType ),&read) != 0 ) break;
        if( read != sizeof( *pExeType ) ) break;
        *pExeType &= 0x0700;

        if( DosChgFilePtr( handle, new_head+0x14, 0, &pos ) != 0 ) break;
        if( DosRead( handle, pIP, sizeof( *pIP ), &read ) != 0 ) break;
        if( read != sizeof( *pIP ) ) break;

        if( DosChgFilePtr( handle, new_head+0x16, 0, &pos ) != 0 ) break;
        if( DosRead( handle, pCS, sizeof( *pCS ), &read ) != 0 ) break;
        if( read != sizeof( *pCS ) ) break;
        rc = TRUE;
        break;
    }
    DosClose( handle );
    return( rc );
}


typedef struct {
        USHORT  phmod[2];               /* offset-segment */
        USHORT  mod_name[2];            /* offset-segment */
        USHORT  fail_len;
        PSZ     fail_name;              /* offset-segment */
        USHORT  hmod;
        BYTE    load_name[2];
} loadstack_t;

#define LOAD_THIS_DLL_SIZE      6
static bool CausePgmToLoadThisDLL( USHORT startCS, USHORT startIP )
{

    char        savecode[LOAD_THIS_DLL_SIZE];
    USHORT      codesize;
    USHORT      len;
    loadstack_t far *loadstack;
    USHORT      dll_name_len;
    char        this_dll[BUFF_SIZE];

    /* save a chunk of the program's code */
    if( DosGetModName( ThisDLLModHandle, BUFF_SIZE, this_dll ) != 0 ) {
        return( FALSE );
    }
    codesize = (char *)EndLoadThisDLL - (char *)LoadThisDLL;
    if( codesize > LOAD_THIS_DLL_SIZE ) return( FALSE );
    len = ReadBuffer( savecode, startCS, startIP, codesize );
    if( Buff.cmd != PT_RET_SUCCESS ) return( FALSE );
    if( len != codesize ) return( FALSE );

    /* write the routine LoadThisDLL into program's code */
    len = WriteBuffer( (char far *)LoadThisDLL, startCS, startIP, codesize );
    if( len != codesize ) return( FALSE );

    /* set up the stack for the routine LoadThisDLL */

    dll_name_len = ( strlen( this_dll ) + 1 ) & ~1;
    loadstack = Automagic( sizeof( loadstack_t ) + dll_name_len );
    Buff.u.r.SP -= sizeof( loadstack_t ) + dll_name_len;
    strcpy( loadstack->load_name, this_dll );
    loadstack->fail_name = NULL;
    loadstack->fail_len = 0;
    loadstack->mod_name[0] = Buff.u.r.SP + offsetof( loadstack_t, load_name );
    loadstack->mod_name[1] = Buff.u.r.SS;
    loadstack->phmod[0] = Buff.u.r.SP + offsetof( loadstack_t, hmod );
    loadstack->phmod[1] = Buff.u.r.SS;
    len = WriteBuffer( (char far *)loadstack, Buff.u.r.SS,
                 Buff.u.r.SP, sizeof( loadstack_t ) + dll_name_len );
    if( len != sizeof( loadstack_t ) + dll_name_len ) return( FALSE );

    /* execute LoadThisDLL on behalf of the program */

    WriteRegs( &Buff );
    ExecuteCode( &Buff );
    if( Buff.cmd != PT_RET_BREAK ) {
        WriteBuffer( savecode, startCS, startIP, codesize );
        return( FALSE );
    } else {
        WriteBuffer( savecode, startCS, startIP, codesize );
        return( TRUE );
    }
}


static void ExecuteUntil( USHORT CS, USHORT IP )
{
    byte        saved;
    byte        breakpt = 0xCC;

    ReadBuffer( &saved, CS, IP, sizeof( byte ) );
    WriteBuffer( &breakpt, CS, IP, sizeof( byte ) );
    do {
        Buff.cmd = PT_CMD_GO;
        LibLoadPTrace( &Buff );
        ReadRegs( &Buff );
    } while( Buff.u.r.CS != CS || Buff.u.r.IP != IP );
    WriteBuffer( &saved, CS, IP, sizeof( byte ) );
}


void AppSession()
{
    DosSelectSession( SID, 0 );
}

void DebugSession()
{
    DosSelectSession( 0, 0 );
}

unsigned ReqProg_load()
{
    NEWSTARTDATA        start;
    char                *parms;
    char                *end;
    char                *prog;
    TRACEBUF            save;
    char                exe_name[255];
    USHORT              startCS, startIP;
    USHORT              exe_type;
    prog_load_ret       *ret;
    char                appname[200];

    ret = GetOutPtr( 0 );

    ExceptNum = -1;
    AtEnd = FALSE;
    prog = GetInPtr( sizeof( prog_load_req ) );
    if( FindFilePath( prog, exe_name, OS2ExtList ) != 0 ) {
        exe_name[0] = '\0';
    }
    parms = AddDriveAndPath( exe_name, UtilBuff );
    while( *prog != '\0' ) ++prog;
    ++prog;
    end = (char *)GetInPtr( GetTotalSize()-1 ) + 1;
    MergeArgvArray( prog, parms, end - prog );
    CanExecTask = TRUE;
    if( !GetExeInfo( &startCS, &startIP, &exe_type, UtilBuff ) ) {
        CanExecTask = FALSE;
        exe_type = EXE_IS_FULLSCREEN;
    }
    start.Length = 50;
    start.Related = 1;
    start.FgBg = !Remote;
    start.TraceOpt = 1;
    strcpy( appname, TRP_The_WATCOM_Debugger );
    strcat( appname, ": " );
    strcat( appname, exe_name );
    start.PgmTitle = appname;
    start.PgmName = UtilBuff;
    start.PgmInputs = parms;
    start.TermQ = 0;
    start.Environment = NULL;
    start.InheritOpt = 1;
    start.IconFile = NULL;
    start.PgmHandle = 0;
    start.PgmControl = 0;
    if( exe_type == EXE_IS_PM ) {
        start.SessionType = SSF_TYPE_PM;
    } else {
        start.SessionType = SessionType; /* set by TaskInit */
    }

    ret->err = DosStartSession( (PSTARTDATA)&start, &SID, &Pid );
    switch( ret->err ) {
    case ERROR_SMG_START_IN_BACKGROUND:
        /* this one's OK */
        ret->err = 0;
        break;
    }
    ret->flags = LD_FLAG_IS_PROT;
    ret->task_id = Pid;
    Buff.pid = Pid;
    Buff.tid = 1;
    if( ret->err != 0 ) {
        Pid = 0;
    } else {
        Buff.cmd = PT_CMD_STOP;
        LibLoadPTrace( &Buff );
        if( Buff.cmd != PT_RET_SUCCESS ) {
            ret->err = 14; /* can't load */
            return( sizeof( *ret ) );
        }
        ReadRegs( &Buff );
        if( CanExecTask ) {
            Buff.cmd = PT_CMD_SEG_TO_SEL;
            Buff.value = startCS;
            Buff.mte = ModHandles[ 0 ];
            DosPTrace( &Buff );
            if( Buff.cmd == PT_RET_SUCCESS ) {
                Buff.mte = ModHandles[ 0 ];
                startCS = Buff.value;
                if( startCS != Buff.u.r.CS || startIP != Buff.u.r.IP ) {
                    ExecuteUntil( startCS, startIP );
                    ReadRegs( &Buff );
                }
                save.pid = Pid;
                save.tid = 1;
                ReadRegs( &save );
                if( !CausePgmToLoadThisDLL( startCS, startIP ) ) {
                    CanExecTask = FALSE;
                }
                WriteRegs( &save );
            } else {
                CanExecTask = FALSE;
            }
        }
        Buff.pid = Pid;
        Buff.tid = 1;
        ReadRegs( &Buff );
    }
    ret->flags |= LD_FLAG_HAVE_RUNTIME_DLLS;
    ret->mod_handle = 0;
    CurrModHandle = 1;
    return( sizeof( *ret ) );
}

unsigned ReqProg_kill()
{
    prog_kill_ret       *ret;

    ret = GetOutPtr( 0 );

⌨️ 快捷键说明

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