watmisc.c

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

C
598
字号
/****************************************************************************
*
*                            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:  Miscellaneous support routines for Watcom debugging format.
*
****************************************************************************/


#include "dipwat.h"
#include "demangle.h"
#include <string.h>
#include "walloca.h"
#if defined(M_I86)
#include <i86.h>
#endif


extern void             InfoUnlock( void );
extern dip_status       InfoRelease( void );
extern void             FiniDemand( void );
extern search_result    LookupLclAddr( imp_image_handle *, address, imp_sym_handle * );
extern search_result    LookupGblAddr( imp_image_handle *, address, imp_sym_handle * );
extern unsigned         SymHdl2CstName( imp_image_handle *, imp_sym_handle *, char *, unsigned );
extern unsigned         SymHdl2TypName( imp_image_handle *, imp_sym_handle *, char *, unsigned );
extern unsigned         SymHdl2MbrName( imp_image_handle *, imp_sym_handle *, char *, unsigned );
extern unsigned         SymHdl2GblName( imp_image_handle *, imp_sym_handle *, char *, unsigned );
extern unsigned         SymHdl2ObjGblName( imp_image_handle *, imp_sym_handle *, char *, unsigned );
extern unsigned         SymHdl2LclName( imp_image_handle *, imp_sym_handle *, char *, unsigned );
extern dip_status       SymHdl2CstValue( imp_image_handle *, imp_sym_handle *, void * );
extern dip_status       SymHdl2CstType( imp_image_handle *, imp_sym_handle *, imp_type_handle * );
extern dip_status       SymHdl2TypType( imp_image_handle *, imp_sym_handle *, imp_type_handle * );
extern dip_status       SymHdl2MbrType( imp_image_handle *, imp_sym_handle *, imp_type_handle * );
extern dip_status       SymHdl2LclType( imp_image_handle *, imp_sym_handle *, imp_type_handle * );
extern dip_status       SymHdl2GblType( imp_image_handle *, imp_sym_handle *, imp_type_handle * );
extern dip_status       SymHdl2MbrLoc( imp_image_handle *, imp_sym_handle *, location_context *, location_list * );
extern dip_status       SymHdl2LclLoc( imp_image_handle *, imp_sym_handle *, location_context *, location_list * );
extern dip_status       SymHdl2GblLoc( imp_image_handle *, imp_sym_handle *, location_list * );
extern dip_status       SymHdl2GblInfo( imp_image_handle *, imp_sym_handle *, sym_info * );
extern dip_status       SymHdl2LclInfo( imp_image_handle *, imp_sym_handle *, sym_info * );
extern dip_status       SymHdl2MbrInfo( imp_image_handle *, imp_sym_handle *, sym_info *, location_context *  );
extern dip_status       SymHdl2LclParmLoc( imp_image_handle *, imp_sym_handle *, location_context *, location_list *, unsigned );
extern search_result    SearchGbl( imp_image_handle *, imp_mod_handle, imp_mod_handle, lookup_item *, void * );
extern search_result    SearchLclScope( imp_image_handle *, imp_mod_handle, address *, lookup_item *, void * );
extern search_result    SearchLclMod( imp_image_handle *, imp_mod_handle, lookup_item *, void * );
extern search_result    SearchEnumName( imp_image_handle *, imp_mod_handle, lookup_item *, void * );
extern search_result    SearchTypeName( imp_image_handle *, imp_mod_handle, lookup_item *, void * );
extern search_result    SearchMbr( imp_image_handle *, imp_type_handle *, lookup_item *, void * );
extern dip_status       WalkLclModSymList( imp_image_handle *, imp_mod_handle, IMP_SYM_WKR *, imp_sym_handle *, void *, walk_result * );
extern walk_result      WalkGblModSymList( imp_image_handle *, imp_mod_handle, IMP_SYM_WKR *, imp_sym_handle *, void * );
extern walk_result      WalkScopedSymList( imp_image_handle *, address *, IMP_SYM_WKR *, imp_sym_handle *, void * );
extern walk_result      WalkBlockSymList( imp_image_handle *, scope_block *, IMP_SYM_WKR *, imp_sym_handle *, void * );
extern walk_result      WalkTypeSymList( imp_image_handle *, imp_type_handle *, IMP_SYM_WKR *, imp_sym_handle *, void * );
extern void             KillLclLoadStack(void);
extern void             KillTypeLoadStack(void);
extern dip_status       Lcl2GblHdl( imp_image_handle *, imp_sym_handle *, imp_sym_handle * );


const char DIPImpName[] = "WATCOM";

unsigned DIPENTRY DIPImpQueryHandleSize( handle_kind hk )
{
    static unsigned_8 Sizes[] = {
        sizeof( imp_image_handle ),
        sizeof( imp_type_handle ),
        sizeof( imp_cue_handle ),
        sizeof( imp_sym_handle )
    };

    return( Sizes[ hk ] );
}

dip_status DIPENTRY DIPImpStartup( void )
{
    return( DS_OK );
}

void DIPENTRY DIPImpShutdown( void )
{
    FiniDemand();
}

void DIPENTRY DIPImpCancel( void )
{
    KillLclLoadStack();
    KillTypeLoadStack();
    InfoUnlock();
}

dip_status DIPENTRY DIPImpMoreMem( unsigned size )
{
    size = size;
    return( InfoRelease() );
}

imp_mod_handle DIPENTRY DIPImpSymMod( imp_image_handle *ii, imp_sym_handle *is )
{
    ii = ii;
    return( is->im );
}

search_result DIPENTRY DIPImpAddrSym( imp_image_handle *ii, imp_mod_handle im,
                        address addr, imp_sym_handle *is )
{
    search_result       sr;

    if( im == NO_MOD ) {
        if( ImpInterface.addr_mod( ii, addr, &is->im ) == SR_NONE ) return( SR_NONE );
    } else {
        is->im = im;
    }
    sr = LookupLclAddr( ii, addr, is );
    if( sr != SR_NONE ) return( sr );
    return( LookupGblAddr( ii, addr, is ) );
}

#define SH_ESCAPE       '\xf0'

unsigned DIPENTRY DIPImpSymName( imp_image_handle *ii, imp_sym_handle *is,
                                location_context *lc,
                                symbol_name sn, char *name, unsigned max )
{
    byte                *sp;
    byte                *ep;
    byte                curr;
    unsigned            len;
    char                *buff;
    location_list       ll;
    imp_sym_handle      gbl_is;

    switch( sn ) {
    case SN_EXPRESSION:
        sp = (byte *)is;
        ++is;
        len = 0;
        #define STUFF_IT( c )   if( (len+1) < max ) *ep++ = (c); ++len
        ep = name;
        STUFF_IT( SH_ESCAPE );
        while( sp < (byte *)is ) {
            curr = *sp++;
            switch( curr ) {
            case SH_ESCAPE:
                curr = 1;
                STUFF_IT( SH_ESCAPE );
                break;
            case '\0':
                curr = 2;
                STUFF_IT( SH_ESCAPE );
                break;
            case '`':
                curr = 3;
                STUFF_IT( SH_ESCAPE );
                break;
            }
            STUFF_IT( curr );
        }
        if( max > 0 ) *ep++ = '\0';
        return( len );
    case SN_DEMANGLED:
        len = ImpInterface.sym_name( ii, is, lc, SN_OBJECT, NULL, 0 );
        if( len == 0 ) return( len );
        buff = __alloca( len + 1 );
        ImpInterface.sym_name( ii, is, lc, SN_OBJECT, buff, len + 1 );
        if( !__is_mangled( buff, len ) ) return( 0 );
        return( __demangle_l( buff, len, name, max ) );
    case SN_OBJECT:
        switch( is->type ) {
        case SH_LCL:
            if( Lcl2GblHdl( ii, is, &gbl_is ) != DS_OK ) break;
            return( SymHdl2ObjGblName( ii, &gbl_is, name, max ) );
        case SH_MBR:
            if( ImpInterface.sym_location( ii, is, lc, &ll ) != DS_OK ) break;
            if( ll.num != 1 || ll.e[0].type != LT_ADDR ) break;
            if( ImpInterface.addr_mod( ii, ll.e[0].u.addr, &gbl_is.im ) == SR_NONE ) break;
            if( LookupGblAddr(ii,ll.e[0].u.addr,&gbl_is) != SR_EXACT ) break;
            is = &gbl_is;
            /* fall through */
        case SH_GBL:
            return( SymHdl2ObjGblName( ii, is, name, max ) );
        }
        /* fall through */
    case SN_SOURCE:
        switch( is->type ) {
        case SH_GBL:
            return( SymHdl2GblName( ii, is, name, max ) );
        case SH_LCL:
            return( SymHdl2LclName( ii, is, name, max ) );
        case SH_MBR:
            return( SymHdl2MbrName( ii, is, name, max ) );
        case SH_TYP:
            return( SymHdl2TypName( ii, is, name, max ) );
        case SH_CST:
            return( SymHdl2CstName( ii, is, name, max ) );
        }
        break;
    }
    return( 0 );
}


static void CollectSymHdl( byte *ep, imp_sym_handle *is )
{
    byte        *sp;
    byte        curr;
    static byte escapes[] = { SH_ESCAPE, '\0', '`' };

    ++ep;
    sp = (byte *)is;
    ++is;
    while( sp < (byte *)is ) {
        curr = *ep++;
        if( curr == SH_ESCAPE ) curr = escapes[ *ep++ - 1 ];
        *sp++ = curr;
    }
}

static search_result SearchFileScope( imp_image_handle *ii,
                        imp_mod_handle im, lookup_item *li, void *d )
{
    search_result       sr;

    if( im == (imp_mod_handle)NO_MOD ) return( SR_NONE );
    switch( li->type ) {
    case ST_NONE:
        sr = SearchLclMod( ii, im, li, d );
        if( sr != SR_NONE ) return( sr );
        return( SearchEnumName( ii, im, li, d ) );
    case ST_DESTRUCTOR:
    case ST_OPERATOR:
        return( SR_NONE );
    default:
        return( SearchTypeName( ii, im, li, d ) );
    }
}

search_result DoLookupSym( imp_image_handle *ii, symbol_source ss,
                         void *source, lookup_item *li, location_context *lc, void *d )
{
    imp_mod_handle      im;
    search_result       sr;
    lookup_item         item;
    char                *buff;
    char                *src;
    char                *dst;
    unsigned            len;
    unsigned            op_len;
    imp_sym_handle      *scope_is;

    if( *li->name.start == SH_ESCAPE ) {
        CollectSymHdl( li->name.start, DCSymCreate( ii, d ) );
        return( SR_EXACT );
    }
    if( li->type == ST_NAMESPACE ) return( SR_NONE );
    item = *li;
    if( ss == SS_SCOPESYM ) {
        scope_is = source;
        len = ImpInterface.sym_name( ii, scope_is, NULL, SN_SOURCE, NULL, 0 );
        item.scope.start = __alloca( len + 1 );
        ImpInterface.sym_name( ii, scope_is, NULL, SN_SOURCE, item.scope.start, len + 1 );
        item.scope.len = len;
        ss = SS_MODULE;
        item.mod = scope_is->im;
        source = &item.mod;
    }
    if( item.type == ST_OPERATOR ) {
        src = item.name.start;
        len = item.name.len;
        buff = __alloca( len + 20 );
        dst = buff;
        for( ;; ) {
            if( len == 0 ) break;
            if( src == item.source.start ) {
                op_len = __mangle_operator( src, item.source.len, buff );
                if( op_len == 0 ) {
                    DCStatus( DS_ERR|DS_INVALID_OPERATOR );
                    return( SR_NONE );
                }

⌨️ 快捷键说明

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