📄 dwarf.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: DWARF debug support.
*
****************************************************************************/
#include "cvars.h"
#include "dw.h"
#include "browsio.h"
#include "standard.h"
#include "cg.h"
#include "cgdefs.h"
#include "cgswitch.h"
#include "cgprotos.h"
static dw_client Client;
static dw_loc_handle dummyLoc;
static dw_handle *SymDWHandles;
static int CurFile;
static int CurLine;
extern void InitDebugTypes(); /* from pchdr.c */
typedef enum
{ DC_RETURN = 0x01, // this is a return type
DC_DEFINE = 0x02, // generate definition
DC_DEFAULT = 0x00 // default behaviour
} DC_CONTROL;
static dw_handle dwarfTypeArray( TYPEPTR );
static dw_handle dwarfTypeFunction( TYPEPTR, char * );
static dw_handle dwarfType( TYPEPTR, DC_CONTROL );
static dw_handle dwarfStructUnion( TYPEPTR, DC_CONTROL );
static dw_handle dwarfVariable( SYMPTR );
static void dwarfEmitVariables( SYM_HANDLE sym_handle );
static void type_update( TYPEPTR typ, int mask, dw_handle dh )
/************************************************************/
{
typ->type_flags = (typ->type_flags & ~TF2_DWARF) | mask;
typ->dwarf_type = dh;
}
static void dwarfFile( unsigned filenum )
{
static unsigned short Current_File_Index = ~0;
FNAMEPTR flist;
char *fname;
// if current file changed, call DWDeclFile
if( filenum != Current_File_Index ) {
flist = FileIndexToFName(filenum);
fname = FNameFullPath( flist );
DWDeclFile( Client, fname );
Current_File_Index = filenum;
}
}
static void dwarfLocation( SYMPTR sym )
/*************************************/
{
dwarfFile( sym->defn_file_index );
DWDeclPos( Client, sym->d.defn_line, 0 );
}
static void dwarfStructInfo( TAGPTR tag )
/***************************************/
{
dw_handle dh;
dw_handle fld_dh;
TYPEPTR typ;
FIELDPTR field;
XREFPTR xref;
field = tag->u.field_list;
while( field != NULL ) {
xref = field->xref;
typ = field->field_type;
if( typ->decl_type == TYPE_FIELD || typ->decl_type == TYPE_UFIELD ) {
fld_dh = dwarfType( GetType( typ->u.f.field_type ), DC_DEFAULT );
if( xref != NULL ){ //stupid struct { int x; int y[] ) = init thing
// Also watch for side effects with the DWDeclPos and a dwtype
dwarfFile( xref->filenum );
DWDeclPos( Client, xref->linenum, 0 );
}
dh = DWAddBitField( Client,
fld_dh,
dummyLoc,
TypeSize( typ ),
typ->u.f.field_start,
typ->u.f.field_width,
field->name,
DW_FLAG_PUBLIC );
} else {
fld_dh = dwarfType( typ, DC_DEFAULT );
if( xref != NULL ){ //stupid struct { int x; int y[] ) = init thing
dwarfFile( xref->filenum );
DWDeclPos( Client, xref->linenum, 0 );
}
dh = DWAddField( Client,
fld_dh,
dummyLoc,
field->name,
DW_FLAG_PUBLIC );
}
if( xref != NULL ){
for( ; (xref = xref->next_xref); ) {
dwarfFile( xref->filenum );
DWReference( Client, xref->linenum, 0, dh );
}
FreeXrefs( field->xref );
field->xref = NULL;
}
field = field->next_field;
}
}
static dw_handle dwarfStructUnion( TYPEPTR typ, DC_CONTROL control )
/******************************************************************/
{
dw_handle dh;
TAGPTR tag;
char *name;
char defined;
control = control;
if( typ->type_flags & TF2_DWARF ) {
dh = typ->dwarf_type;
} else {
if( typ->decl_type == TYPE_STRUCT ) {
dh = DWStruct( Client, DW_ST_STRUCT );
} else {
dh = DWStruct( Client, DW_ST_UNION );
}
type_update( typ, TF2_DWARF_FWD, dh );
}
tag = typ->u.tag;
if( typ->type_flags & TF2_DWARF_FWD ) {
type_update( typ, TF2_DWARF_DEF, dh );
if( tag->name[0] == '\0' ) {
name = NULL;
} else {
name = tag->name;
}
defined = (tag->size != 0);
DWBeginStruct( Client,
dh,
tag->size,
name,
0,
(defined ? 0 : DW_FLAG_DECLARATION ) );
if( defined ) {
dwarfStructInfo( tag );
}
DWEndStruct( Client );
}
return( dh );
}
ENUMPTR ReverseEnums( ENUMPTR esym ) /* reverse order of enums */
{
ENUMPTR prev_enum;
ENUMPTR next_enum;
prev_enum = NULL;
while( esym != NULL ) {
next_enum = esym->thread;
esym->thread = prev_enum;
prev_enum = esym;
esym = next_enum;
}
return( prev_enum );
}
static dw_handle dwarfEnum( TYPEPTR typ )
/***************************************/
{
dw_handle dh;
ENUMPTR esym;
ENUMPTR enum_list;
dh = DWBeginEnumeration( Client,
TypeSize( typ->object ),
typ->u.tag->name,
0,
0 );
enum_list = ReverseEnums( typ->u.tag->u.enum_list );
for( esym = enum_list; esym; esym = esym->thread ) {
DWAddConstant( Client, esym->value.u._32[L], esym->name );
}
ReverseEnums( enum_list );
DWEndEnumeration( Client );
type_update( typ, TF2_DWARF_DEF, dh );
return( dh );
}
static dw_handle dwarfTypeArray( TYPEPTR typ )
/********************************************/
{
dw_handle dh;
if( typ->type_flags & TF2_DWARF ) return( typ->dwarf_type );
dh = DWSimpleArray( Client,
dwarfType( typ->object, DC_DEFAULT ),
typ->u.array->dimension );
type_update( typ, TF2_DWARF_DEF, dh );
return( dh );
}
static dw_handle dwarfTypeFunction( TYPEPTR typ, char *name )
/***********************************************************/
{
dw_handle dh;
TYPEPTR *parm_list;
if( typ->type_flags & TF2_DWARF ) return( typ->dwarf_type );
dh = dwarfType( typ->object, DC_RETURN );
dh = DWBeginSubroutineType( Client,
dh,
name,
0,
DW_FLAG_DECLARATION | DW_FLAG_PROTOTYPED );
type_update( typ, TF2_DWARF_DEF, dh );
parm_list = typ->u.parms;
while( parm_list != NULL ) {
typ = *parm_list++;
if( typ == NULL ) break;
if( typ->decl_type == TYPE_DOT_DOT_DOT ) {
DWAddEllipsisToSubroutineType( Client );
} else {
DWAddParmToSubroutineType( Client,
dwarfType( typ, DC_DEFAULT ),
dummyLoc,
dummyLoc,
NULL );
}
}
DWEndSubroutineType( Client );
return( dh );
}
uint dwarfTypeModifier( type_modifiers decl_flags )
/***********************************************/
{
uint modtype = 0;
if( decl_flags & FLAG_CONST ) {
modtype |= DW_MOD_CONSTANT;
}
if( decl_flags & FLAG_VOLATILE ) {
modtype |= DW_MOD_VOLATILE;
}
#if _CPU == 386
if( decl_flags & FLAG_NEAR ) {
modtype |= DW_MOD_NEAR32;
}
if( decl_flags & FLAG_FAR ) {
modtype |= DW_MOD_FAR32;
}
if( decl_flags & FLAG_FAR16 ) {
modtype |= DW_MOD_FAR16;
}
#else
if( decl_flags & FLAG_NEAR ) {
modtype |= DW_MOD_NEAR16;
}
if( decl_flags & FLAG_FAR ) {
modtype |= DW_MOD_FAR16;
}
if( decl_flags & FLAG_HUGE ) {
modtype |= DW_MOD_HUGE16;
}
#endif
return( modtype );
}
static dw_handle dwarfType( TYPEPTR typ, DC_CONTROL control )
/***********************************************************/
{
dw_handle dh = 0;
SYMPTR sym;
if( typ->type_flags & TF2_DWARF ) return( typ->dwarf_type );
switch( typ->decl_type ) {
case TYPE_CHAR:
dh = DWFundamental( Client, "char", DW_FT_SIGNED_CHAR, TypeSize( typ ) );
type_update( typ, TF2_DWARF_DEF, dh );
break;
case TYPE_UCHAR:
dh = DWFundamental( Client, "unsigned char", DW_FT_UNSIGNED_CHAR, TypeSize( typ ) );
type_update( typ, TF2_DWARF_DEF, dh );
break;
case TYPE_WCHAR:
dh = DWFundamental( Client, "wchar_t", DW_FT_UNSIGNED_CHAR, TypeSize( typ ) );
type_update( typ, TF2_DWARF_DEF, dh );
break;
case TYPE_SHORT:
dh = DWFundamental( Client, "signed short", DW_FT_SIGNED, TypeSize( typ ) );
type_update( typ, TF2_DWARF_DEF, dh );
break;
case TYPE_USHORT:
dh = DWFundamental( Client, "unsigned short", DW_FT_UNSIGNED, TypeSize( typ ) );
type_update( typ, TF2_DWARF_DEF, dh );
break;
case TYPE_INT:
dh = DWFundamental( Client, "signed int", DW_FT_SIGNED, TypeSize( typ ) );
type_update( typ, TF2_DWARF_DEF, dh );
break;
case TYPE_UINT:
dh = DWFundamental( Client, "unsigned int", DW_FT_UNSIGNED, TypeSize( typ ) );
type_update( typ, TF2_DWARF_DEF, dh );
break;
case TYPE_LONG:
dh = DWFundamental( Client, "signed long", DW_FT_SIGNED, TypeSize( typ ) );
type_update( typ, TF2_DWARF_DEF, dh );
break;
case TYPE_ULONG:
dh = DWFundamental( Client, "unsigned long", DW_FT_UNSIGNED, TypeSize( typ ) );
type_update( typ, TF2_DWARF_DEF, dh );
break;
case TYPE_LONG64:
dh = DWFundamental( Client, "__int64", DW_FT_UNSIGNED, TypeSize( typ ) );
type_update( typ, TF2_DWARF_DEF, dh );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -