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

📄 qnxpmd.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            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 for QNX post-mortem debugging.
*
****************************************************************************/


#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <process.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <sys/proxy.h>
#include <sys/kernel.h>
#include <sys/debug.h>
#include <sys/stat.h>
#include <sys/proc_msg.h>
#include <sys/osinfo.h>
#include <sys/psinfo.h>
#include <sys/seginfo.h>
#include <sys/sched.h>
#include <sys/vc.h>
#include <sys/magic.h>
#include <sys/wait.h>
#include <sys/dumper.h>
#include <sys/console.h>
#include <sys/dev.h>
#include <sys/name.h>
#include "trpimp.h"
#include "qnxcomm.h"
#include "misc7086.h"
#include "mad.h"
#include "madregs.h"

typedef unsigned short  USHORT;
typedef unsigned long   ULONG;

typedef struct {
    word    real_seg;
    word    is_32;
    dword   seg_len;
    dword   file_off;
    dword   mem_off;
} seg_data;

#define DUMP_SIGNATURE  0x706d7564
#define DUMP_VERSION    100

#define NO_FILE         (-1)

enum {
    MH_NONE,
    MH_DEBUGGEE,
    MH_SLIB,
    MH_PROC
};

struct {
    unsigned            loaded              : 1;
    unsigned            ignore_timestamp    : 1;
    unsigned            fpu32               : 1;
    unsigned            read_gdts           : 1;
    unsigned            enable_read_gdts    : 1;
    unsigned            force_read_gdts     : 1;
    unsigned            dbg32               : 1;
    unsigned            mapping_shared      : 1;
    int                 fd;
    struct _dumper_hdr  hdr;
    seg_data            *segs;
} PmdInfo;

#if 0
static void Out( char *str )
{
    write( 1, str, strlen( str ) );
}

static void OutNum( unsigned i )
{
    char numbuff[10];
    char *ptr;

    ptr = numbuff+10;
    *--ptr = '\0';
    do {
        *--ptr = ( i % 10 ) + '0';
        i /= 10;
    } while( i != 0 );
    Out( ptr );
}
#endif


unsigned ReqGet_sys_config()
{
    struct  _osinfo     info;
    get_sys_config_ret  *ret;

    ret = GetOutPtr(0);
    if( PmdInfo.loaded )  {
        info = PmdInfo.hdr.osdata;
    } else {
        qnx_osinfo( 0, &info );
    }
    ret->sys.mad = MAD_X86;
    ret->sys.os = OS_QNX;
    ret->sys.osmajor = info.version / 100;
    ret->sys.osminor = info.version % 100;
    if( info.sflags & _PSF_EMULATOR_INSTALLED ) {
        ret->sys.fpu = X86_EMU;
    } else if( (info.sflags & _PSF_NDP_INSTALLED) == 0 ) {
        ret->sys.fpu = X86_NO;
    } else {
        switch( info.fpu ) {
        case 87:
            ret->sys.fpu = X86_87;
            break;
        case 287:
            ret->sys.fpu = X86_287;
            break;
        case 387:
        default:
            ret->sys.fpu = X86_387;
            break;
        }
    }
    switch( info.cpu ) {
    case 8088:
        ret->sys.cpu = X86_86;
        break;
    case 186:
        ret->sys.cpu = X86_186;
        break;
    case 286:
        ret->sys.cpu = X86_286;
        break;
    case 386:
    default:
        ret->sys.cpu = X86_386;
        break;
    case 486:
        ret->sys.cpu = X86_486;
        break;
    case 586:
        ret->sys.cpu = X86_586;
        break;
    case 686:
        ret->sys.cpu = X86_686;
        break;
    }
    if( info.sflags & _PSF_PROTECTED ) {
        ret->sys.huge_shift = 3;
    } else {
        ret->sys.huge_shift = 12;
    }
    return( sizeof( *ret ) );
}

#define PRIV_MASK 0x03

struct _slib_register {
    msg_t       msgcode;
    short       rsvd1;
    long        rsvd[3];
};
struct _slib_register_reply {
    msg_t       msgcode;
    addr48_ptr  dispatch;
    long        rsvd[2];
};
#define _SLIB_NAME "qnx/syslib"
#define _SLIB_REGISTER  0x1000

addr48_ptr GetSLibTable( bool is_32 )
{
    addr48_ptr          slib;
    union {
        struct _slib_register   smsg;
        struct _slib_register_reply     rmsg;
    }                   msg;
    pid_t               pid;
    int                 ret;

    slib.segment = 0;
    slib.offset  = 0;
    /* get shared library function table pointer */
    if( is_32 ) {
        pid = qnx_name_locate( getnid(), _SLIB_NAME, sizeof( msg ), NULL );
        if( pid == -1 ) {
            return( slib );
        }
        msg.smsg.msgcode = _SLIB_REGISTER;
        ret = Send( pid, &msg, &msg, sizeof( msg.smsg ), sizeof( msg.rmsg ) );
        qnx_vc_detach( pid );
        if( ret == -1 || msg.rmsg.msgcode != EOK ) {
            return( slib );
        }
        slib = msg.rmsg.dispatch;
    } else {
        #if 0 //NYI: Don't know how to find 16-bit Slib
        extern int (__far * (__far *__f)) ();

        slib.offset  = FP_OFF( __f );
        slib.segment = FP_SEG( __f );
        /*
            There are 3 different SLib segments, one for each priv level.
            Make the assumption that they're all contiguous and figure out
            the right one based on the difference between the debugger's
            priv level and the debuggee's. Ugh. Talk to QSSL about this.
        */
        slib.segment += ((PmdInfo.segs[0].real_seg & PRIV_MASK)
                        - (FP_SEG( &__f ) & PRIV_MASK)) * 8;
        #endif
    }
    return( slib );
}

unsigned ReqMap_addr()
{
    map_addr_req        *acc;
    map_addr_ret        *ret;
    unsigned            index;
    addr48_ptr          slib;
    unsigned            seg;

    acc = GetInPtr(0);
    ret = GetOutPtr(0);
    ret->lo_bound = 0;
    ret->hi_bound = ~(addr48_off)9;

    seg = acc->in_addr.segment;
    switch( seg ) {
    case MAP_FLAT_CODE_SELECTOR:
        seg = 0x04;
        break;
    case MAP_FLAT_DATA_SELECTOR:
        seg = 0x0c;
        break;
    }
    seg &= ~PRIV_MASK;

    ret->out_addr.offset = acc->in_addr.offset;
    switch( acc->handle ) {
    case MH_DEBUGGEE:
        if( acc->in_addr.segment == MAP_FLAT_DATA_SELECTOR ) {
            index = 0;
        } else {
            index = seg >> 3;
        }
        if( PmdInfo.loaded && index < PmdInfo.hdr.numsegs ) {
            seg = PmdInfo.segs[ seg >> 3 ].real_seg;
            ret->out_addr.offset += PmdInfo.segs[ index ].mem_off;
        }
        break;
    case MH_SLIB:
        slib = GetSLibTable( PmdInfo.dbg32 );
        seg += slib.segment - 4;
        break;
    case MH_PROC:
        seg += 0xE0 - 4;
        break;
    }
    ret->out_addr.segment = seg | (PmdInfo.segs[0].real_seg & PRIV_MASK);
    return( sizeof( *ret ) );
}


unsigned ReqChecksum_mem()
{
    checksum_mem_ret    *ret;

    ret = GetOutPtr(0);
    ret->result = 0;
    return( sizeof( *ret ) );
}

#pragma aux ver_read =  ".286p"         \
                        "verr   ax"     \
                        "jz     L1"     \
                        "xor    ax,ax"  \
                        "L1:"           \
                        parm [ax] value [ax]

extern unsigned short ver_read( unsigned short );

static unsigned ReadGDT( read_mem_req *acc, unsigned len, void *ret )
{
    struct _seginfo     info;
    unsigned            segment;

    if( !PmdInfo.read_gdts ) return( 0 );
    segment = acc->mem_addr.segment;
    if( segment & 0x04 ) return( 0 );
    if( segment == 0 ) return( 0 );
    if( !ver_read( segment ) ) return( 0 );
    if(qnx_segment_info(PROC_PID,PROC_PID,segment,&info)==-1) return( 0 );
    if( acc->mem_addr.offset >= info.nbytes ) {
        len = 0;
    } else if( acc->mem_addr.offset+len > info.nbytes ) {
        len = info.nbytes - acc->mem_addr.offset;
    }
    if( len == 0 ) return( 0 );
    _fmemcpy( ret, MK_FP( segment, acc->mem_addr.offset ), len );
    return( len );
}

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

    acc = GetInPtr(0);
    ret = GetOutPtr(0);
    if( !PmdInfo.loaded ) {
        return( 0 );
    }
    len = acc->len;
    for( i = 0; i < PmdInfo.hdr.numsegs; ++i ) {
        if( PmdInfo.segs[i].real_seg == acc->mem_addr.segment ) {
            if( acc->mem_addr.offset >= PmdInfo.segs[i].seg_len ) {
                len = 0;
            } else if( acc->mem_addr.offset+len > PmdInfo.segs[i].seg_len ) {
                len = PmdInfo.segs[i].seg_len - acc->mem_addr.offset;
            }
            if( len != 0 ) {
                lseek( PmdInfo.fd, PmdInfo.segs[i].file_off + acc->mem_addr.offset,
                         SEEK_SET );
                len = read( PmdInfo.fd, ret, len );
                if( len == -1 ) len = 0;
            }
            return( len );
        }
    }
    return( ReadGDT( acc, len, ret ) );
}


unsigned ReqWrite_mem()
{
    write_mem_ret       *ret;

    ret = GetOutPtr(0);
    ret->len = 0;
    return( sizeof( *ret ) );
}


unsigned ReqRead_io()
{
    return( 0 );
}


unsigned ReqWrite_io()
{
    write_io_ret        *ret;

    ret = GetOutPtr(0);
    ret->len = 0;
    return( sizeof( *ret ) );
}

static void ReadCPU( struct x86_cpu *r )
{
    memset( r, 0, sizeof( *r ) );
    if( PmdInfo.loaded ) {
        r->eax = PmdInfo.hdr.reg.ax;
        r->ebx = PmdInfo.hdr.reg.bx;
        r->ecx = PmdInfo.hdr.reg.cx;
        r->edx = PmdInfo.hdr.reg.dx;
        r->esi = PmdInfo.hdr.reg.si;
        r->edi = PmdInfo.hdr.reg.di;
        r->ebp = PmdInfo.hdr.reg.bp;
        r->esp = PmdInfo.hdr.reg.sp;
        r->eip = PmdInfo.hdr.reg.ip;
        r->efl = PmdInfo.hdr.reg.fl;
        r->cs = PmdInfo.hdr.reg.cs;
        r->ds = PmdInfo.hdr.reg.ds;
        r->ss = PmdInfo.hdr.reg.ss;
        r->es = PmdInfo.hdr.reg.es;
        r->fs = PmdInfo.hdr.reg.fs;
        r->gs = PmdInfo.hdr.reg.gs;
    }
}

static void ReadFPU( struct x86_fpu *r )
{
    memset( r, 0, sizeof( *r ) );
    if( PmdInfo.loaded ) {
        memcpy( r, PmdInfo.hdr.x87, sizeof( PmdInfo.hdr.x87 ) );
        if( !PmdInfo.fpu32 ) FPUExpand( r );
    }
}

unsigned ReqRead_cpu()
{
    ReadCPU( GetOutPtr( 0 ) );
    return( sizeof( struct x86_cpu ) );
}

unsigned ReqRead_fpu()
{
    ReadFPU( GetOutPtr( 0 ) );
    return( sizeof( struct x86_fpu ) );
}

unsigned ReqRead_regs( void )
{
    mad_registers       *mr;

    mr = GetOutPtr( 0 );

    ReadCPU( &mr->x86.cpu );
    ReadFPU( &mr->x86.fpu );
    return( sizeof( mr->x86 ) );
}

unsigned ReqWrite_cpu()
{
    return( 0 );
}

⌨️ 快捷键说明

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