dbgsem.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,388 行 · 第 1/3 页
C
1,388 行
/****************************************************************************
*
* 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: Semantic actions for SSL-driven grammars.
*
****************************************************************************/
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include "dbglit.h"
#include "dbgdefn.h"
#include "dbginfo.h"
#include "dbgstk.h"
#include "dbgtoken.h"
#include "dbgreg.h"
#include "dbgerr.h"
#include "dbgtoggl.h"
#include "dipwv.h"
#include "dip.h"
#include "i64.h"
#define SSL_VERSION_MAJOR_CURR 0x0100
#define SSL_VERSION_MINOR_CURR 0x0000
#define SSL_VERSION_MAJOR_MASK 0xff00
#define SSL_VERSION_MINOR_MASK 0x00ff
#define TI_KIND_EXTRACT( ti ) (((ti) >> 12) & 0xf)
#define TI_MOD_EXTRACT( ti ) (((ti) >> 8) & 0xf)
#define TI_SIZE_EXTRACT( ti ) ((ti) & 0xff)
#define TI_CREATE( tk, tm, ts ) (((tk) << 12) | ((tm) << 8) | (ts))
enum {
SEM_MISC = 0x00,
SEM_DO = 0x20,
SEM_PUSH_N_POP = 0x40,
SEM_STACK = 0x60,
SEM_NUM = 0x80,
SEM_BITS = 0xa0,
SEM_GET = 0xc0,
SEM_SELECTOR = 0x1f,
SEM_MECHANISM = 0xe0,
};
extern void DoPlus( void );
extern void DoMinus( void );
extern void DoMul( void );
extern void DoDiv( void );
extern void DoMod( void );
extern void DoAnd( void );
extern void DoOr( void );
extern void DoXor( void );
extern void DoShift( void );
extern void DoAddr( void );
extern void DoFAddr( void );
extern void DoPoints( type_kind );
extern void DoConvert( void );
extern void DoLConvert( void );
extern void DoMakeComplex( void );
extern void DoStringConcat( void );
extern void DoField( void );
extern void DoScope( void );
extern void DoAssign( void );
extern void DoCall( unsigned int, bool );
extern void DupStack( void );
extern void SwapStack( int );
extern unsigned TstEQ( unsigned int );
extern unsigned TstLT( unsigned int );
extern unsigned TstTrue( unsigned int );
extern unsigned TstExist( unsigned int );
extern void PushName( lookup_item * );
extern void PushNum( long );
extern void PushNum64( unsigned_64 );
extern void PushRealNum( xreal );
extern void PushAddr( address );
extern void PushLocation( location_list *, type_info * );
extern void PushString( void );
extern void PushType( type_handle * );
extern void PushInt( int );
extern void PopEntry( void );
extern void MakeAddr( void );
extern void ExprValue( stack_entry * );
extern bool NameResolve( stack_entry *, bool );
extern void LValue( stack_entry * );
extern void RValue( stack_entry * );
extern void LRValue( stack_entry * );
extern void ParseRegSet( bool, location_list *, type_info * );
extern void Recog( unsigned int );
extern bool ScanQuote( char **, unsigned * );
extern void Scan( void );
extern char *ScanPos( void );
extern unsigned ScanLen( void );
extern char *NamePos( void );
extern unsigned NameLen( void );
extern unsigned_64 IntNumVal( void );
extern xreal RealNumVal( void );
extern void MoveSP( int );
extern stack_entry *StkEntry( int );
extern char *ReScan( char * );
extern mod_handle LookupModName( mod_handle, char *, int );
extern unsigned SetCurrRadix( unsigned int );
extern void AddChar( void );
extern void AddCEscapeChar( void );
extern void AddActualChar( char );
extern void ConvertTo( stack_entry *, type_kind, type_modifier, unsigned );
extern void FreePgmStack( bool );
extern void MarkArrayOrder( bool );
extern void StartSubscript( void );
extern void AddSubscript( void );
extern void EndSubscript( void );
extern address GetDotAddr( void );
extern sym_list *LookupSymList( symbol_source, void *, bool, lookup_item * );
extern void PurgeSymHandles( void );
extern void LocationAdd( location_list *, long );
extern bool IsInternalMod( mod_handle );
extern sym_list *Disambiguate( sym_list * );
extern void FreeSymHandle( sym_list * );
extern image_entry *ImagePrimary( void );
extern mod_handle LookupImageName( char *, unsigned );
extern void GetMADTypeDefault( mad_type_kind, mad_type_info * );
extern tokens CurrToken;
extern stack_entry *ExprSP;
extern unsigned SkipCount;
extern mod_handle CodeAddrMod;
extern bool scan_string;
extern unsigned StringLength;
extern unsigned ScanCCharNum;
extern unsigned NestedCallLevel;
extern int PgmStackUsage[ MAX_NESTED_CALL ];
extern unsigned ExprAddrDepth;
#define type_bitsII int
/* SSL Table Variables */
static type_bitsII Bits;
static unsigned Num;
static unsigned EvalSubstring;
static struct {
lookup_item li;
unsigned multi_module : 1;
unsigned any_image : 1;
enum { GET_NAME, GET_OPERATOR, GET_LNUM } kind;
} CurrGet;
#define MAX_SCANSAVE_PTRS 20
static char *CurrScan[MAX_SCANSAVE_PTRS];
int ScanSavePtr;
enum { false=0, true=1 }; /* values for bools from the parse table */
//NYI: begin temp until SSL files can be updated
typedef enum {
STK_VOID = 0x0000,
STK_BOOL = 0x0001,
STK_ENUM = 0x0002,
STK_CHAR = 0x0003,
STK_INT = 0x0004,
STK_NEAR_PTR = 0x0005,
STK_FAR_PTR = 0x0006,
STK_ADDR = 0x0007, /* just a raw address */
STK_REAL = 0x0008,
STK_STRUCT = 0x0009,
STK_ARRAY = 0x000a,
STK_FUNC = 0x000b,
STK_TYPE = 0x000c, /* have a type name */
STK_NAME = 0x000d, /* have a symbol name */
STK_COMPLEX = 0x000f,
STK_STRING = 0x0010,
STK_OPERATOR = 0x0011,
STK_END_PURGE= 0x003f,
#define BASE_TYPE 0x003f
STK_UNSIGNED = 0x0100, /* meaningful for int & char only */
STK_LONG = 0x0200, /* int (short/long);
real (float/double),
complex (single/double precision)
addresses (286 / 386)
*/
} stack_class;
static stack_class TypeInfoToClass( type_info *ti )
{
stack_class c;
c = STK_VOID;
switch( ti->kind ) {
case TK_INTEGER:
c = STK_INT;
if( ti->modifier == TM_UNSIGNED ) c |= STK_UNSIGNED;
if( ti->size == 4 ) c |= STK_LONG;
break;
case TK_POINTER:
c = STK_FAR_PTR;
if( ti->size == 6 ) c |= STK_LONG;
break;
case TK_ADDRESS:
c = STK_ADDR;
if( ti->size == 6 ) c |= STK_LONG;
break;
case TK_ARRAY:
c = STK_ARRAY;
break;
case TK_STRING:
c = STK_STRING;
break;
case TK_FUNCTION:
c = STK_FUNC;
break;
}
return( c );
}
static void ClassToTypeInfo( stack_class c, type_info *ti )
{
switch( c ) {
case STK_INT | STK_UNSIGNED:
ti->kind = TK_INTEGER;
ti->modifier = TM_UNSIGNED;
ti->size = 2;
break;
case STK_INT | STK_UNSIGNED | STK_LONG:
ti->kind = TK_INTEGER;
ti->modifier = TM_UNSIGNED;
ti->size = 4;
break;
case STK_FAR_PTR:
ti->kind = TK_POINTER;
ti->modifier = TM_FAR;
ti->size = 4;
break;
case STK_FAR_PTR | STK_LONG:
ti->kind = TK_POINTER;
ti->modifier = TM_FAR;
ti->size = 6;
break;
case STK_ADDR:
ti->kind = TK_ADDRESS;
ti->modifier = TM_FAR;
ti->size = 4;
break;
case STK_ADDR | STK_LONG:
ti->kind = TK_ADDRESS;
ti->modifier = TM_FAR;
ti->size = 6;
break;
case STK_ARRAY:
ti->kind = TK_ARRAY;
ti->modifier = TM_NONE;
ti->size = 0;
break;
case STK_FUNC:
ti->kind = TK_FUNCTION;
ti->modifier = TM_NONE;
ti->size = 0;
break;
case STK_STRING:
ti->kind = TK_STRING;
ti->modifier = TM_NONE;
ti->size = 0;
break;
}
}
#define SSL_CASE_SENSITIVE 0x00000001UL // must be 0x01 - see dbgintr.ssl
#define SSL_SIDE_EFFECT 0x00000002UL // must be 0x02 - see dbgintr.ssl
#define SSL_32_BIT 0x00000004UL // must be 0x04 - see dbgintr.ssl
//NYI: end temp
static void FillInDefaults( type_info *info )
{
mad_type_info mti;
switch( info->kind ) {
case TK_INTEGER:
if( info->modifier == TM_NONE ) info->modifier = TM_SIGNED;
if( info->size == 0 ) {
if( ModDefault( CodeAddrMod, DK_INT, info ) != DS_OK ) {
GetMADTypeDefault( MTK_INTEGER, &mti );
info->size = mti.b.bits / BITS_PER_BYTE;
}
}
break;
case TK_POINTER:
case TK_CODE:
case TK_DATA:
if( info->modifier == TM_NONE ) {
if( ModDefault( CodeAddrMod, (info->kind == TK_CODE) ? DK_CODE_PTR : DK_DATA_PTR, info ) != DS_OK ) {
info->modifier = TM_NONE;
info->size = 0;
}
}
if( info->modifier == TM_NONE || info->size == 0 ) {
GetMADTypeDefault( MTK_ADDRESS, &mti );
if( info->modifier == TM_NONE ) {
if( mti.a.seg.bits != 0 ) {
info->modifier = TM_FAR;
} else {
info->modifier = TM_NEAR;
}
}
if( info->size == 0 ) {
if( info->modifier == TM_NEAR ) mti.b.bits -= mti.a.seg.bits;
info->size = mti.b.bits / BITS_PER_BYTE;
}
}
break;
}
}
static unsigned MechMisc( unsigned select, unsigned parm )
{
long value;
unsigned result;
mad_type_info mti;
switch( select ) {
case 0:
ExprAddrDepth += parm;
result = ExprAddrDepth;
break;
case 1:
if( _IsOn( SW_EXPR_IS_CALL ) && ExprAddrDepth == 0 ) {
result = TRUE;
} else {
result = FALSE;
}
break;
case 2:
SkipCount += parm;
break;
case 3:
result = SkipCount;
break;
case 4:
//never called
break;
case 5:
if( ScanSavePtr >= MAX_SCANSAVE_PTRS )
Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANSAVE ) );
CurrScan[ScanSavePtr++] = ScanPos();
break;
case 6:
if( ScanSavePtr <= 0 ) Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANRESTORE ) );
ReScan( CurrScan[--ScanSavePtr] );
break;
case 7:
if( ScanSavePtr <= 0 ) Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANRESTORE ) );
--ScanSavePtr;
break;
case 8:
if( parm ) { /* start scan string */
scan_string = TRUE;
ReScan( ScanPos() );
} else { /* end scan string */
scan_string = FALSE;
ReScan( ScanPos() );
}
break;
case 9:
ReScan( ScanPos() + (int)parm );
break;
case 10:
AddChar();
break;
case 11:
AddCEscapeChar();
break;
case 12:
AddActualChar( '\0' );
break;
case 13:
ScanCCharNum = parm;
break;
case 14:
if( NestedCallLevel == MAX_NESTED_CALL - 1 ) {
Error( ERR_NONE, LIT( ERR_TOO_MANY_CALLS ) );
} else {
PgmStackUsage[ ++NestedCallLevel ] = 0;
}
break;
case 15:
RValue( ExprSP );
ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, 4 );
value = U32FetchTrunc( ExprSP->v.uint ) - 1;
PopEntry();
if( ExprSP->info.kind == TK_STRING ) {
if( value < 0 || value >= ExprSP->info.size ) {
Error( ERR_NONE, LIT( ERR_BAD_SUBSTRING_INDEX ) );
}
LocationAdd( &ExprSP->v.string.loc, value*8 );
ExprSP->info.size -= value;
ExprSP->v.string.ss_offset = value;
} else {
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
}
break;
case 16:
RValue( ExprSP );
ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, 4 );
value = U32FetchTrunc( ExprSP->v.sint ) - 1;
PopEntry();
if( ExprSP->info.kind == TK_STRING ) {
value -= ExprSP->v.string.ss_offset;
if( value < 0 || value >= ExprSP->info.size ) {
Error( ERR_NONE, LIT( ERR_BAD_SUBSTRING_INDEX ) );
}
ExprSP->info.size = value;
} else {
Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
}
break;
case 17:
EvalSubstring = parm;
if( parm ) ExprSP->v.string.ss_offset = 0;
break;
case 18:
result = EvalSubstring;
break;
case 19:
FreePgmStack( TRUE );
break;
case 20:
switch( parm ) { // nyi - begin temp
case SSL_CASE_SENSITIVE:
_SwitchOn( SW_CASE_SENSITIVE );
break;
case SSL_SIDE_EFFECT:
_SwitchOn( SW_SIDE_EFFECT );
break;
//case SSL_32_BIT:
// _SwitchOn( SW_32_BIT );
// break;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?