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 + -
显示快捷键?