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

📄 qnxacc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
*
*                            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 interactive 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 <i86.h>
#include <malloc.h>
#include <sys/name.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/console.h>
#include <sys/dev.h>
#include <string.h>
#include "trpimp.h"
#include "trperr.h"
#include "qnxcomm.h"
#include "misc7086.h"
#include "mad.h"
#include "madregs.h"

typedef unsigned short  USHORT;
typedef unsigned long   ULONG;

#define BUFF_SIZE       256

static pid_t            MID;
static pid_t            OrigPGrp;
static char             UtilBuff[BUFF_SIZE];
static struct {
    unsigned long       in;
    unsigned long       out;
    unsigned long       err;
}                       StdPos;

static int ForceFpu32;

enum {
    MH_NONE,
    MH_DEBUGGEE,
    MH_SLIB,
    MH_PROC
};

typedef struct {
        pid_t       tid;
        unsigned    frozen      : 1;
        unsigned    fork        : 1;
        unsigned    dying       : 1;
} thread_info;

typedef struct {
    unsigned    at_end          : 1;
    unsigned    loaded_proc     : 1;
    unsigned    stopped         : 1;
    unsigned    priv_level      : 2;
    unsigned    dbg32           : 1;
    unsigned    proc32          : 1;
    unsigned    fpu32           : 1;
    unsigned    flat            : 1;
    unsigned    fork            : 1;
    pid_t       pid;
    nid_t       nid;
    pid_t       proc;
    pid_t       mid;
    pid_t       son;
    int         sig;
    unsigned    version;
    long        cpu;
    long        fpu;
    long        sflags;
    int         save_in;
    int         save_out;
    addr48_ptr  magic;
    addr48_off  code_offset;
    addr48_off  data_offset;
    unsigned_32 last_eax;
    unsigned    max_threads;
    thread_info *thread;
}  process_info;


#define THREAD_GROW     10

static process_info ProcInfo;

#define PRIV_MASK   3

#define MAX_WP  32
struct _watch_struct    WatchPoints[ MAX_WP ];
short   WatchCount = 0;

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

void OutNum( unsigned long i )
{
    char numbuff[16];
    char *ptr;

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

#define MAX_MEM_TRANS   256
static unsigned MoveMem( int op, char *data, addr_seg segv, addr_off offv,
                unsigned size )
{
    unsigned            length;
    unsigned            trans;
    unsigned            amount;
    struct _seginfo     info;

    if( ProcInfo.pid == 0 ) return( 0 );
    if( qnx_segment_info( ProcInfo.proc, ProcInfo.pid, segv, &info ) == -1 ) {
        info.nbytes = 0;
    }
    if( offv >= info.nbytes ) {
        size = 0;
    } else if( offv + size > info.nbytes ) {
        size = info.nbytes - offv;
    }
    length = size;
    for( ;; ) {
        if( length == 0 ) break;
        trans = (length > MAX_MEM_TRANS) ? MAX_MEM_TRANS : length;
        if( __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, op, data, trans, offv, segv ) != 0 ) {
            /* something went wrong. need to find out how much trans'ed */
            //NYI
            amount = 0;
        } else {
            amount = trans;
        }
        data += amount;
        offv += amount;
        length -= amount;
        if( amount != trans ) break;
    }
    return( size - length );
}


static unsigned WriteBuffer( char *data, addr_seg segv, addr_off offv,
            unsigned size )
{
    return( MoveMem( _DEBUG_MEM_WR, data, segv, offv, size ) );
}


static unsigned ReadBuffer( char *data, addr_seg segv, addr_off offv,
            unsigned size )
{
    return( MoveMem( _DEBUG_MEM_RD, data, segv, offv, size ) );
}

static thread_info *find_thread(pid_t tid)
{
    thread_info *thread;
    unsigned    new_count;

    for( thread = ProcInfo.thread; thread < &ProcInfo.thread[ProcInfo.max_threads]; thread++ ) {
        if( thread->tid == tid ) {
            if( tid == 0 ) thread->dying = FALSE;
            return( thread );
        }
    }
    if( tid == 0 ) {
        /* need to expand the array */
        new_count = ProcInfo.max_threads + THREAD_GROW;
        thread = realloc( ProcInfo.thread, new_count * sizeof( *thread ) );
        if( thread != NULL ) {
            ProcInfo.thread = thread;
            thread = &thread[ProcInfo.max_threads];
            ProcInfo.max_threads = new_count;
            memset( thread, 0, THREAD_GROW * sizeof( *thread ) );
            return( thread );
        }
    }
    return( NULL );
}

#define THREAD_ALL      (-1)
#define NO_TID          (INT_MAX)

static pid_t next_thread(pid_t last, int state) {
    thread_info         *thread;
    pid_t               tid = NO_TID;
    pid_t               curr;

    for( thread = ProcInfo.thread; thread < &ProcInfo.thread[ProcInfo.max_threads]; thread++ ) {
        if( thread->dying ) continue;
        curr = thread->tid;
        switch( state ) {
        case THREAD_ALL:
            break;
        case THREAD_THAWED:
           if( thread->frozen && (ProcInfo.pid != curr) ) continue;
           break;
        case THREAD_FROZEN:
           if( !thread->frozen ) continue;
           break;
        }
        if( curr > last && curr < tid ) {
            tid = curr;
        }
    }
    if( tid == NO_TID ) return( 0 );
    return( tid );
}


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

    ret = GetOutPtr(0);
    if( ProcInfo.pid == 0 )  {
        qnx_osinfo( 0, &info );
    } else {
        info.version = ProcInfo.version;
        info.cpu = ProcInfo.cpu;
        info.fpu = ProcInfo.fpu;
        info.sflags = ProcInfo.sflags;
    }
    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;
    }
    if( info.sflags & _PSF_PROTECTED ) {
        ret->sys.huge_shift = 3;
    } else {
        ret->sys.huge_shift = 12;
    }
    ret->sys.mad = MAD_X86;
    return( sizeof( *ret ) );
}

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;
    addr32_ptr          slib16;
    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( ProcInfo.nid, _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( __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_MEM_RD, &slib16,
            sizeof( slib16 ), ProcInfo.magic.offset+offsetof(struct _magic,sptrs[0]),
                                                  ProcInfo.magic.segment ) != 0 ) {
            return( slib );
        }
        slib.segment = slib16.segment;
        slib.offset  = slib16.offset;
    }
    return( slib );
}


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

    acc = GetInPtr(0);
    ret = GetOutPtr(0);
    ret->lo_bound = 0;
    ret->hi_bound = ~(addr48_off)0;
    ret->out_addr.offset = acc->in_addr.offset;
    seg = acc->in_addr.segment;
    switch( seg ) {
    case MAP_FLAT_CODE_SELECTOR:
        seg = 0x04;
        break;
    case MAP_FLAT_DATA_SELECTOR:
        seg = 0x0c;
        break;
    }
    if( ProcInfo.pid != 0 ) {
        switch( acc->handle ) {
        case MH_DEBUGGEE:
            if( ProcInfo.flat ) {
                switch( acc->in_addr.segment & ~PRIV_MASK ) {
                case 0x04:
                case MAP_FLAT_CODE_SELECTOR & ~PRIV_MASK:
                /* case MAP_FLAT_DATA_SELECTOR & ~PRIV_MASK: Same as above */
                    ret->out_addr.offset += ProcInfo.code_offset;
                    break;
                default:
                    ret->out_addr.offset += ProcInfo.data_offset;
                    break;
                }
            }
            break;
        case MH_SLIB:
            slib = GetSLibTable( ProcInfo.dbg32 );
            seg += slib.segment - 4;
            break;
        case MH_PROC:
            seg += 0xE0 - 4;
            break;
        }
    }
    if( ProcInfo.sflags & _PSF_PROTECTED ) {
        ret->out_addr.segment = (seg & ~PRIV_MASK) | ProcInfo.priv_level;
    }
    return( sizeof( *ret ) );
}


unsigned ReqChecksum_mem()
{
    addr_off            offv;
    USHORT              length;
    USHORT              size;
    int                 i;
    USHORT              amount;
    ULONG               sum;
    checksum_mem_req    *acc;
    checksum_mem_ret    *ret;

    acc = GetInPtr(0);
    ret = GetOutPtr(0);
    sum = 0;
    if( ProcInfo.pid != 0 ) {
        length = acc->len;
        offv = acc->in_addr.offset;
        for( ;; ) {
            if( length == 0 ) break;
            size = (length > sizeof( UtilBuff )) ? sizeof( UtilBuff ) : length;
            amount = MoveMem( _DEBUG_MEM_RD, UtilBuff, acc->in_addr.segment,
                                offv, size );

⌨️ 快捷键说明

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