dipinter.c

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

C
1,022
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "dbgdefn.h"
#undef AddrMod
#undef AddrSym
#undef AddrScope
#undef AddrCue
#include "dbglit.h"
#include "dbgmem.h"
#include "dbginfo.h"
#include "dbgio.h"
#include "dipcli.h"
#include "dipimp.h"
#include "dipwv.h"
#include "dbgreg.h"
#include "mad.h"
#include <string.h>
#include <stddef.h>


extern unsigned         CueFile( cue_handle *ch, char *file, unsigned max );
extern unsigned long    CueLine( cue_handle *ch );
extern int              SectIsLoaded( unsigned, int );
extern void             AddrSection( address *, unsigned );
extern bool             SameAddrSpace( address, address );
extern void             LocationCreate( location_list *, location_type, void * );
extern dip_status       LocationAssign( location_list *, location_list *, unsigned long, bool );
extern void             LocationSet( location_list *, unsigned, unsigned );
extern mad_reg_info     *LookupRegName( mad_reg_info *, lookup_item * );
extern wv_sym_entry     *LookupInternalName( lookup_item * );
extern wv_sym_entry     *LookupUserName( lookup_item * );
extern void             InternalValue( unsigned, void * );
extern void             PurgeUserNames(void);
extern void             StartupErr( char * );
extern void             FreeImage( image_entry * );
extern void             MapAddrForImage( image_entry *, addr_ptr * );
extern image_entry      *ImageEntry( mod_handle );
extern char             *Format( char *buff, char *fmt, ... );
extern address          DefAddrSpaceForAddr( address );
extern int              AddrComp( address, address );
extern void             DeAlias( addr_ptr * );
extern char             *StrCopy( char *, char *);

extern address          NilAddr;
extern dip_status       DIPStatus;
extern char             *DipFiles[];
extern char             *TxtBuff;
extern system_config    SysConfig;

/*
 * Client support routines
 */

void DIGCLIENT DIPCliImageUnload( mod_handle mh )
{
    image_entry         *image;

    image = ImageEntry( mh );
    if( image != NULL && !image->nofree ) {
        FreeImage( image );
    }
}

void DIGCLIENT DIPCliMapAddr( addr_ptr *addr, void *d )
{
    image_entry         *id = d;

    MapAddrForImage( id, addr );
}

sym_handle *DIGCLIENT DIPCliSymCreate( void *d )
{
    sym_list    **sl_head = d;
    sym_list    *new;

    _ChkAlloc( new, sizeof(sym_list)-sizeof(byte) + sym_SIZE, LIT( ERR_NO_MEMORY_FOR_DEBUG ) );//
    new->next = *sl_head;
    *sl_head = new;
    return( SL2SH( new ) );
}

void MadTypeToDipTypeInfo( mad_type_handle mt, type_info *ti )
{
    mad_type_info       mti;

    MADTypeInfo( mt, &mti );
    ti->size = mti.b.bits / BITS_PER_BYTE;
    ti->modifier = TM_NONE;
    switch( mti.b.kind ) {
    case MTK_INTEGER:
        if( mti.i.nr == MNR_UNSIGNED ) {
            ti->modifier = TM_UNSIGNED;
        } else {
            ti->modifier = TM_SIGNED;
        }
        ti->kind = TK_INTEGER;
        break;
    case MTK_ADDRESS:
        if( mti.a.seg.bits != 0 ) {
            ti->modifier = TM_FAR;
        } else {
            ti->modifier = TM_NEAR;
        }
        ti->kind = TK_ADDRESS;
        break;
    case MTK_FLOAT:
        ti->kind = TK_REAL;
        break;
    }
}

dip_status RegLocation( machine_state *regs, mad_reg_info const *ri, location_list *ll )
{

    if( regs == NULL || ri == NULL ) return( DS_ERR|DS_CONTEXT_ITEM_INVALID );
    LocationCreate( ll, LT_INTERNAL, &regs->mr );
    LocationSet( ll, ri->bit_start, ri->bit_size );
    ll->flags = ri->flags << LLF_REG_FLAGS_SHIFT;
    return( DS_OK );
}

dip_status DIGCLIENT DIPCliItemLocation( location_context *lc, context_item ci,
                         location_list *ll )
{
    sym_info            info;
    DIPHDL( sym, sh );

    if( lc == NULL ) return( DS_ERR|DS_NO_CONTEXT );
    switch( ci ) {
    case CI_FRAME:
        if( lc->maybe_have_frame ) {
            lc->maybe_have_frame = FALSE;
            if( DeAliasAddrSym( NO_MOD, lc->execution, sh ) == SR_NONE ) {
                /* nothing to do */
            } else if( SymInfo( sh, NULL, &info ) != DS_OK ) {
                /* nothing to do */
            } else if( info.kind != SK_PROCEDURE ) {
                /* nothing to do */
            } else if( SymLocation( sh, NULL, ll ) != DS_OK ) {
                /* nothing to do */
            } else if( lc->execution.mach.offset
                 < ll->e[0].u.addr.mach.offset + info.prolog_size ) {
                /* nothing to do */
            } else if( lc->execution.mach.offset
                 <= ll->e[0].u.addr.mach.offset+info.rtn_size-info.epilog_size ) {
                lc->have_frame = TRUE;
            }
        }
        if( Context.maybe_have_frame
            && AddrComp( Context.frame, lc->frame ) == 0
            && AddrComp( Context.execution, lc->execution ) == 0 ) {
            /* cache result in global context item */
            Context.have_frame = lc->have_frame;
            Context.maybe_have_frame = FALSE;
        }
        if( !lc->have_frame ) return( DS_ERR|DS_CONTEXT_ITEM_INVALID );
        LocationCreate( ll, LT_ADDR, &lc->frame );
        return( DS_OK );
    case CI_STACK:
        if( !lc->have_stack ) return( DS_ERR|DS_CONTEXT_ITEM_INVALID );
        LocationCreate( ll, LT_ADDR, &lc->stack );
        return( DS_OK );
    case CI_EXECUTION:
        LocationCreate( ll, LT_ADDR, &lc->execution );
        return( DS_OK );
    case CI_OBJECT:
        if( lc->maybe_have_object ) {
            lc->maybe_have_object = FALSE;
            if( DeAliasAddrSym( NO_MOD, lc->execution, sh ) == SR_NONE ) {
                /* nothing to do */
            } else if( SymInfo( sh, NULL, &info ) != DS_OK ) {
                /* nothing to do */
            } else if( info.kind != SK_PROCEDURE ) {
                /* nothing to do */
            } else if( SymObjLocation( sh, lc, &lc->object ) == DS_OK ) {
                lc->have_object = TRUE;
            }
        }
        if( !lc->have_object ) return( DS_ERR|DS_CONTEXT_ITEM_INVALID );
        *ll = lc->object;
        return( DS_OK );
    case CI_DEF_ADDR_SPACE:
        {
            address     addr;

            addr = DefAddrSpaceForAddr( lc->execution );
            LocationCreate( ll, LT_ADDR, &addr );
        }
        return( DS_OK );
    }
    return( RegLocation( lc->regs, MADRegFromContextItem( ci ), ll ) );
}

dip_status DIGCLIENT DIPCliAssignLocation( location_list *dst,
                        location_list *src, unsigned long size )
{
    return( LocationAssign( dst, src, size, FALSE ) );
}

dip_status DIGCLIENT DIPCliSameAddrSpace( address a, address b )
{
    return( SameAddrSpace( a, b ) ? DS_OK : DS_FAIL );
}

void DIGCLIENT DIPCliAddrSection( address *addr )
{
    AddrSection( addr, OVL_MAP_CURR );
}


void DIGCLIENT DIPCliStatus( dip_status status )
{
    DIPStatus = status;
}

mad_handle DIGCLIENT DIPCliCurrMAD( void )
{
    return( SysConfig.mad );
}

/*
 * Dealiasing cover routines
 */

search_result DeAliasAddrMod( address a, mod_handle *mh )
{
    DeAlias( &a.mach );
    return( AddrMod( a, mh ) );
}

search_result DeAliasAddrSym( mod_handle mh, address a, sym_handle *sh )
{
    DeAlias( &a.mach );
    return( AddrSym( mh, a, sh ) );
}

search_result DeAliasAddrScope( mod_handle mh, address a, scope_block *sb )
{
    DeAlias( &a.mach );
    return( AddrScope( mh, a, sb ) );
}

search_result DeAliasAddrCue( mod_handle mh, address a, cue_handle *ch )
{
    DeAlias( &a.mach );
    return( AddrCue( mh, a, ch ) );
}

/*
 * Internal symbol table interface routines
 */

static char     WVName[] = "Debugger Internal";

static unsigned DIGREGISTER WVHandleSize( handle_kind hk )
{
    static const unsigned_8 Sizes[] = {
        0, sizeof( imp_type_handle ), 0, sizeof( imp_sym_handle )
    };
    return( Sizes[hk] );
}

static dip_status DIGREGISTER WVMoreMem( unsigned amount )
{
    amount = amount;
    return( DS_FAIL );
}

#if 0
static dip_status DIGREGISTER WVStartup()
{
    return( DS_OK );
}
#endif

static void DIGREGISTER WVShutdown( void )
{
}

static void DIGREGISTER WVCancel( void )
{
}

static dip_status DIGREGISTER WVLoadInfo( dig_fhandle f, imp_image_handle *ii )
{
    f = f;
    ii = ii;
    return( DS_FAIL );
}

static void DIGREGISTER WVMapInfo( imp_image_handle *ii, void *d )
{
    ii = ii; d = d;
}

static void DIGREGISTER WVUnloadInfo( imp_image_handle *ii )
{
    ii = ii;
}

static walk_result DIGREGISTER WVWalkModList( imp_image_handle *ii, IMP_MOD_WKR *wk, void *d )
{
    return( wk( ii, WV_INT_MH, d ) );
}

static const char InternalName[] = "_dbg";

static unsigned DIGREGISTER WVModName( imp_image_handle *ii, imp_mod_handle im,
                                char *name, unsigned max )
{
    unsigned len;

    ii = ii; im = im;
    len = sizeof( InternalName ) - 1;
    if( max > 0 ) {
        --max;
        if( max > len ) max = len;
        memcpy( name, InternalName, max );
        name[max] = '\0';
    }
    return( len );
}


static char *DIGREGISTER WVModSrcLang( imp_image_handle *ii, imp_mod_handle im )
{
    ii = ii; im = im;
    return( LIT( Empty ) );
}

static dip_status DIGREGISTER WVModInfo( imp_image_handle *ii, imp_mod_handle im,
                        handle_kind hk )
{
    static const dip_status Kinds[] = { DS_FAIL, DS_OK, DS_FAIL, DS_OK };

    ii = ii; im = im;
    return( Kinds[hk] );
}

static dip_status DIGREGISTER WVModDefault( imp_image_handle *ii, imp_mod_handle im,
                        handle_kind dk, type_info *ti )
{
    /* never called */
    ii = ii; im = im; dk = dk, ti = ti;
    return( DS_FAIL );
}

static search_result DIGREGISTER WVAddrMod( imp_image_handle *ii, address a, imp_mod_handle *imp )
{
    ii = ii; a = a; imp = imp;
    return( SR_NONE );
}

static address DIGREGISTER WVModAddr( imp_image_handle *ii, imp_mod_handle im )
{
    ii = ii; im = im;
    return( NilAddr );
}


static walk_result DIGREGISTER WVWalkTypeList( imp_image_handle *ii, imp_mod_handle im,
                        IMP_TYPE_WKR *wk, imp_type_handle * it, void *d )
{
    ii = ii; im = im; wk = wk, it=it, d = d;
    return( WR_CONTINUE );
}

static imp_mod_handle DIGREGISTER WVTypeMod( imp_image_handle *ii, imp_type_handle *it )
{
    ii = ii; it = it;
    return( WV_INT_MH );
}

static dip_status DIGREGISTER WVTypeInfo( imp_image_handle *ii, imp_type_handle *it,
                        location_context *lc, type_info *ti )
{

    ii = ii; lc = lc;
    if( it->ri != NULL ) {
        MadTypeToDipTypeInfo( it->ri->type, ti );
    } else {
        ti->kind = it->t.k;
        ti->modifier = it->t.m;
        ti->size = it->t.s;
    }
    return( DS_OK );
}

static dip_status DIGREGISTER WVTypeBase( imp_image_handle *ii, imp_type_handle *src,
                                imp_type_handle *dst )
{
    ii = ii;
    *dst = *src;
    return( DS_FAIL );
}

static dip_status DIGREGISTER WVTypeBaseLocation( imp_image_handle *ii, imp_type_handle *src,
                    imp_type_handle *dst, location_context *lc, location_list *ll )
{
    ii = ii; lc = lc; ll = ll;
    *dst = *src;
    return( DS_FAIL );
}

static dip_status DIGREGISTER WVTypeArrayInfo( imp_image_handle *ii, imp_type_handle *it,
                location_context *lc, array_info *ai, imp_type_handle *index )
{
    /* will never get called */
    ii = ii; it = it; lc = lc; ai = ai; index = index;
    return( DS_FAIL );
}

static dip_status DIGREGISTER WVTypeProcInfo( imp_image_handle *ii, imp_type_handle *it,
                imp_type_handle *parm_it, unsigned parm )
{
    /* will never get called */
    ii = ii; it = it; parm_it = parm_it; parm = parm;
    return( DS_FAIL );
}

static dip_status DIGREGISTER WVTypePtrAddrSpace( imp_image_handle *ii, imp_type_handle *it,
                        location_context *lc, address *addr )
{
    /* will never get called */
    ii = ii; it = it; lc = lc; addr = addr;
    return( DS_FAIL );
}

static dip_status DIGREGISTER WVTypeThunkAdjust( imp_image_handle *ii, imp_type_handle *obj,
                imp_type_handle *member, location_context *lc, address *a )
{
    /* will never get called */
    ii = ii; obj = obj; member = member; lc = lc; a = a;
    return( DS_FAIL );
}

static walk_result DIGREGISTER WVWalkSymList( imp_image_handle *ii, symbol_source ss,
                    void *src, IMP_SYM_WKR *wk, imp_sym_handle *is, void *d )
{
    ii = ii; ss = ss; src = src; wk = wk; is = is; d = d;
    return( WR_CONTINUE );
}

static walk_result DIGREGISTER WVWalkSymListEx( imp_image_handle *ii, symbol_source ss,
                    void *src, IMP_SYM_WKR *wk, imp_sym_handle *is,
                    location_context *lc, void *d )
{
    ii = ii; ss = ss; src = src; wk = wk; is = is; lc = lc; d = d;
    return( WR_CONTINUE );
}

static imp_mod_handle DIGREGISTER WVSymMod( imp_image_handle *ii, imp_sym_handle *is )
{
    ii = ii; is = is;
    return( WV_INT_MH );
}

static unsigned DIGREGISTER WVSymName( imp_image_handle *ii, imp_sym_handle *is,
                        location_context *lc,
                        symbol_name sn, char *name, unsigned max )
{
    unsigned    len;
    char  const *p;

    ii = ii; lc = lc;
    if( sn == SN_DEMANGLED ) return( 0 );
    if( is->ri != NULL ) {
        p   = is->ri->name;
        len = strlen( p );
    } else {
        p   = &is->p->name[1];
        len =  is->p->name[0];
    }
    if( max > 0 ) {
        --max;
        if( max > len ) max = len;
        memcpy( name, p, max );
        name[max] = '\0';
    }
    return( len );
}

⌨️ 快捷键说明

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