📄 cdebug.c
字号:
/****************************************************************************
*
* 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 "cvars.h"
#include "cgdefs.h"
#include "cgswitch.h"
#include "cg.h"
#include "standard.h"
#include "cgprotos.h"
static dbug_type DBTypeStruct();
static dbug_type DBTypeEnum();
static void InitDBType( void );
//void RevTypeList();
extern int CGenType( TYPEPTR );
extern int PtrType( TYPEPTR typ, int flags );
extern void SymGet(SYMPTR,SYM_HANDLE);
extern SYMPTR SymGetPtr(SYM_HANDLE);
static void InitDBType( void )
{
TYPEPTR typ;
ScopeStruct = DBScope( "struct" );
ScopeUnion = DBScope( "union" );
ScopeEnum = DBScope( "enum" );
typ = GetType( TYPE_PLAIN_CHAR );
if( typ->decl_type == TYPE_UCHAR ){
typ->debug_type = DBScalar( "char", T_UINT_1 );
}else{
typ->debug_type = DBScalar( "char", T_INT_1 );
}
B_Int_1 = DBScalar( "signed char", T_INT_1 );
B_UInt_1 = DBScalar( "unsigned char", T_UINT_1 );
B_Short = DBScalar( "short", T_INT_2 );
B_UShort = DBScalar( "unsigned short", T_UINT_2 );
#if TARGET_INT == 4
B_Int = DBScalar( "int", T_INT_4 );
B_UInt = DBScalar( "unsigned int", T_UINT_4 );
#else
B_Int = DBScalar( "int", T_INT_2 );
B_UInt = DBScalar( "unsigned int", T_UINT_2 );
#endif
B_Int32 = DBScalar( "long", T_INT_4 );
B_UInt32 = DBScalar( "unsigned long", T_UINT_4 );
B_Int64 = DBScalar( "__int64", T_INT_8 );
B_UInt64 = DBScalar( "unsigned __int64", T_UINT_8 );
DebugNameList = NULL;
}
#if 0
static void RevTypeList()
{
TYPEPTR previous, current, following;
previous = NULL;
current = TypeHead;
following = current->next_type;
for(; following ;) {
current->next_type = previous;
previous = current;
current = following;
following = current->next_type;
}
current->next_type = previous;
TypeHead = current;
}
#endif
static int SimpleTypedef( TYPEPTR typ )
{
TYPEPTR *typp;
while( typ != NULL ) {
switch( typ->decl_type ) {
case TYPE_TYPEDEF:
case TYPE_ARRAY:
case TYPE_POINTER:
typ = typ->object;
break;
case TYPE_FUNCTION:
if( typ->u.parms != NULL ) {
for( typp = typ->u.parms; *typp != NULL; ++typp ) {
if( !SimpleTypedef( *typp ) ) return( FALSE );
}
}
typ = typ->object;
break;
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_ENUM:
return( FALSE );
default:
return( TRUE );
}
}
return( TRUE );
}
static void EmitADBType( TYPEPTR typ )
{
switch( typ->decl_type ) {
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_ENUM:
if( !CompFlags.dump_types_with_names ) break;
if( typ->u.tag->name[0] == '\0' ) break;
goto dump_type;
case TYPE_TYPEDEF:
if( !(CompFlags.dump_types_with_names
|| SimpleTypedef( typ )) ) break;
if( CompFlags.no_debug_type_names ) break;
dump_type:
#if 0
if( DebugFlag >= 2 ) {
DumpType( typ, 0 );
printf( "\n" );
}
#endif
DBType( typ );
break;
default:
break;
}
}
void EmitDBType()
{
// RevTypeList();
InitDBType();
WalkTypeList( EmitADBType );
}
static dbug_type DBIntegralType( int decl_type )
{
dbug_type ret_val;
switch( decl_type ) {
case TYPE_CHAR:
ret_val = B_Int_1;
break;
case TYPE_UCHAR:
ret_val = B_UInt_1;
break;
case TYPE_SHORT:
ret_val = B_Short;
break;
case TYPE_USHORT:
ret_val = B_UShort;
break;
case TYPE_INT:
default:
ret_val = B_Int;
break;
case TYPE_UINT:
ret_val = B_UInt;
break;
case TYPE_LONG:
ret_val = B_Int32;
break;
case TYPE_ULONG:
ret_val = B_UInt32;
break;
case TYPE_LONG64:
ret_val = B_Int64;
break;
case TYPE_ULONG64:
ret_val = B_UInt64;
break;
}
return( ret_val );
}
static dbug_type DoBasedPtr( TYPEPTR typ, predefined_cg_types cg_pnt_mod )
{
dbug_type ret_val = 0;
dbg_loc dl;
SYM_HANDLE sym_handle;
auto SYM_ENTRY sym;
int have_retval = 0;
dl = DBLocInit();
sym_handle = typ->u.p.based_sym;
if( sym_handle == 0 ) {
dl = DBLocConst( dl, 0 );
dl = DBLocOp( dl, DB_OP_MK_FP, 0 );
} else {
if( sym_handle == Sym_CS ) { /* 23-jan-92 */
ret_val = DBPtr( cg_pnt_mod, DBType( typ->object ) );
have_retval = 1;
} else if( sym_handle == Sym_SS ) { /* 13-dec-92 */
ret_val = DBPtr( cg_pnt_mod, DBType( typ->object ) );
have_retval = 1;
} else {
SymGet( &sym, sym_handle );
if( sym.name[0] == '.' ) { /* if segment label 15-mar-92 */
ret_val = DBPtr( cg_pnt_mod, DBType( typ->object ) );
have_retval = 1;
} else {
dl = DBLocSym( dl, sym_handle );
dl = DBLocOp( dl, DB_OP_POINTS, T_UINT_2 );
dl = DBLocConst( dl, 0 );
dl = DBLocOp( dl, DB_OP_MK_FP, 0 );
}
}
}
if (!have_retval) {
ret_val = DBBasedPtr( cg_pnt_mod, DBType( typ->object ), dl );
}
DBLocFini( dl );
return( ret_val );
}
dbug_type DBType( TYPEPTR typ )
{
dbug_type ret_val;
dbg_proc pr;
TYPEPTR *pparms;
unsigned long size;
auto SYM_ENTRY sym;
auto struct debug_fwd_types fwd_info, *fip;
predefined_cg_types cg_pnt_mod;
if( typ->debug_type == DBG_FWD_TYPE ) {
fip = DebugNameList;
while( fip->typ != typ ) fip = fip->next;
if( fip->debug_name == NULL ) {
fip->debug_name = DBBegName( "", fip->scope );
}
typ->debug_type = DBForward( fip->debug_name );
}
if( typ->debug_type != DBG_NIL_TYPE ) return( typ->debug_type );
fwd_info.next = DebugNameList;
fwd_info.typ = typ;
fwd_info.debug_name = NULL;
fwd_info.scope = DBG_NIL_TYPE;
/* default is INT */
ret_val = B_Int;
switch( typ->decl_type ) {
case TYPE_VOID:
ret_val = DBScalar( "void", TY_DEFAULT );
break;
case TYPE_FLOAT:
ret_val = DBScalar( "float", T_SINGLE );
break;
case TYPE_DOUBLE:
ret_val = DBScalar( "double", TY_DOUBLE );
break;
case TYPE_LONG_DOUBLE:
ret_val = DBScalar( "long double", TY_DOUBLE );
break;
case TYPE_ARRAY:
size = TypeSize( typ );
if( size != 0 ) {
--size;
}
ret_val = DBIntArrayCG( CGenType(typ), size, DBType( typ->object ) );
break;
case TYPE_POINTER:
cg_pnt_mod = PtrType( typ->object, typ->u.p.decl_flags );
if( typ->u.p.decl_flags & FLAG_BASED ) {
ret_val = DoBasedPtr( typ, cg_pnt_mod );
} else {
ret_val = DBPtr( cg_pnt_mod, DBType( typ->object ) );
}
break;
case TYPE_STRUCT:
case TYPE_UNION:
fwd_info.scope = (typ->decl_type == TYPE_STRUCT)
? ScopeStruct : ScopeUnion;
if( typ->u.tag->name[0] != '\0' ) {
fwd_info.debug_name = DBBegName( typ->u.tag->name,
fwd_info.scope );
}
DebugNameList = &fwd_info;
typ->debug_type = DBG_FWD_TYPE;
ret_val = DBTypeStruct( typ );
if( fwd_info.debug_name != NULL ) {
ret_val = DBEndName( fwd_info.debug_name, ret_val );
}
DebugNameList = fwd_info.next;
break;
case TYPE_FUNCTION:
cg_pnt_mod = T_CODE_PTR;
pr = DBBegProc( cg_pnt_mod, DBType( typ->object ) );
for( pparms = typ->u.parms; pparms; pparms++ ) {
if( (*pparms == NULL) ) break;
if( (*pparms)->decl_type == TYPE_DOT_DOT_DOT ) break;
DBAddParm( pr, DBType( *pparms ));
}
ret_val = DBEndProc( pr );
break;
case TYPE_TYPEDEF:
if( typ->type_flags & TF2_DUMMY_TYPEDEF ) {
ret_val = DBType( typ->object );
} else {
SymGet( &sym, typ->u.typedefn );
if( !CompFlags.no_debug_type_names ) {
fwd_info.debug_name = DBBegName( sym.name, DBG_NIL_TYPE );
}
typ->debug_type = DBG_FWD_TYPE;
DebugNameList = &fwd_info;
ret_val = DBType( typ->object );
if( fwd_info.debug_name != NULL ) {
ret_val = DBEndName( fwd_info.debug_name, ret_val );
if( GenSwitches & DBG_CV ){
DBTypeDef( sym.name, ret_val ); //get codeview typedef out
}
}
DebugNameList = fwd_info.next;
}
break;
case TYPE_ENUM:
ret_val = DBTypeEnum( typ );
break;
default:
ret_val = DBIntegralType( typ->decl_type );
break;
}
typ->debug_type = ret_val;
return( ret_val );
}
static void DumpFieldList( dbg_struct st, unsigned long bias,
FIELDPTR pfield, TYPEPTR field_obj )
{
TYPEPTR field_typ;
for( ; pfield; pfield = pfield->next_field ) {
field_typ = pfield->field_type;
if( pfield->name[0] == '\0' ) {
/* anonymous struct/union -- suck up to this level */
while( field_typ->decl_type == TYPE_TYPEDEF ) {
field_typ = field_typ->object;
}
DumpFieldList( st, bias + pfield->offset,
field_typ->u.tag->u.field_list, NULL );
} else if(( field_typ->decl_type == TYPE_FIELD ) ||
( field_typ->decl_type == TYPE_UFIELD ) ) {
field_typ->debug_type = DBIntegralType(field_typ->u.f.field_type);
DBAddBitField( st, bias + pfield->offset,
field_typ->u.f.field_start,
field_typ->u.f.field_width, pfield->name,
field_typ->debug_type );
} else if( field_obj != NULL
&& field_typ->decl_type == TYPE_ARRAY
&& field_typ->u.array->dimension == 0 ){
DBAddField( st, bias + pfield->offset,
pfield->name, DBType( field_obj ));
} else {
DBAddField( st, bias + pfield->offset,
pfield->name, DBType( pfield->field_type ));
}
}
}
static dbug_type DBTypeStruct( TYPEPTR typ )
{
dbug_type ret_val;
dbg_struct st;
TYPEPTR obj;
if( typ->object != NULL ) { /* 17-mar-92 */
/* structure has a zero length array as last field */
obj = typ->object; /* 14-jun-94 */
} else {
obj = NULL;
}
st = DBBegNameStruct( typ->u.tag->name, CGenType( typ ),
typ->decl_type==TYPE_STRUCT );
ret_val = DBStructForward( st );
if( ret_val != DBG_NIL_TYPE ) {
typ->debug_type = ret_val;
}
DumpFieldList( st, 0, typ->u.tag->u.field_list, obj );
ret_val = DBEndStruct( st );
return( ret_val );
}
static dbug_type DBTypeEnum( TYPEPTR typ )
{
dbug_type ret_val;
dbg_enum e;
ENUMPTR ep;
e = DBBegEnum( CGenType( typ->object ) );
for( ep = typ->u.tag->u.enum_list; ep; ep = ep->thread ) {
DBAddConst64( e, ep->name, ep->value );
}
ret_val = DBEndEnum( e );
if( typ->u.tag->name[0] != '\0' ) {
DBEndName( DBBegName( typ->u.tag->name, ScopeEnum ), ret_val );
}
return( ret_val );
}
dbug_type FEDbgType( CGSYM_HANDLE cgsym_handle )
{
SYM_HANDLE sym_handle = cgsym_handle;
return( DBType( SymGetPtr( sym_handle )->sym_type ) );
}
dbug_type FEDbgRetType( CGSYM_HANDLE cgsym_handle )
{
SYM_HANDLE sym_handle = cgsym_handle;
TYPEPTR typ;
typ = SymGetPtr( sym_handle )->sym_type;
if( typ->decl_type == TYPE_FUNCTION ) {
return( DBType( typ->object ) );
} else {
return( DBG_NIL_TYPE );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -