dbsyms.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 982 行 · 第 1/2 页
C
982 行
/****************************************************************************
*
* 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: Emit debug information for debugging locals.
*
****************************************************************************/
#include "standard.h"
#include "hostsys.h"
#include "coderep.h"
#include "pattern.h"
#include "procdef.h"
#include "cgdefs.h"
#include "sysmacro.h"
#include "symdbg.h"
#include "model.h"
#include "ocentry.h"
#include "objrep.h"
#include "zoiks.h"
#include "cgaux.h"
#include "typedef.h"
#include "dbgstrct.h"
#include "dbcue.h"
#define BY_CG
#include "feprotos.h"
#include "cgprotos.h"
#ifndef NDEBUG
#include "echoapi.h"
#endif
#include <string.h>
extern type_def *TypeAddress(cg_type);
extern instruction *MakeNop(void);
extern void AddIns(instruction*);
extern name *AllocRegName(hw_reg_set);
extern seg_id SetOP(seg_id);
extern seg_id AskCodeSeg(void);
extern void EmptyQueue(void);
extern void InputOC(any_oc *);
extern char DBNested( char nested );
extern dbg_loc LocDupl(dbg_loc);
extern dbg_loc LocReg(dbg_loc,name*);
extern dbg_loc LocParm(dbg_loc,name*);
extern dbg_loc DBLocInit(void);
extern dbg_loc DBLocSym(dbg_loc,sym_handle);
extern void DBLocFini(dbg_loc);
#if _TARGET &( _TARG_IAPX86 | _TARG_80386 )
/* WV interface */
extern void WVInitDbgInfo( void );
extern void WVFiniDbgInfo( void );
extern void WVGenStatic( sym_handle sym, dbg_loc loc );
extern void WVObjectPtr( cg_type ptr_type );
extern void WVSetBase( void );
extern void WVBlkEnd( dbg_block *blk, offset lc );
extern void WVRtnEnd( dbg_rtn *rtn, offset lc );
#endif
/* DF interface */
extern void DFInitDbgInfo( void );
extern void DFObjInitInfo( void );
extern void DFFiniDbgInfo( void );
extern void DFObjFiniDbgInfo( void );
extern void DFGenStatic( sym_handle sym, dbg_loc loc );
extern void DFTypedef( char *nm, dbg_type tipe );
extern void DFProEnd( dbg_rtn *rtn, offset lc );
extern void DFBlkBeg( dbg_block *blk, offset lc );
extern void DFBlkEnd( dbg_block *blk, offset lc );
extern void DFEpiBeg( dbg_rtn *blk, offset lc );
extern void DFRtnEnd( dbg_rtn *rtn, offset lc );
/* CV interface */
extern void CVInitDbgInfo( void );
extern void CVObjInitInfo( void );
extern void CVFiniDbgInfo( void );
extern void CVObjFiniDbgInfo( void );
extern void CVGenStatic( sym_handle sym, dbg_loc loc, bool mem );
extern void CVTypedef( char *nm, dbg_type tipe );
extern void CVSetBase( void );
extern void CVRtnBeg( dbg_rtn *rtn, offset lc );
extern void CVProEnd( dbg_rtn *rtn, offset lc );
extern void CVBlkBeg( dbg_block *blk, offset lc );
extern void CVBlkEnd( dbg_block *blk, offset lc );
extern void CVEpiBeg( dbg_rtn *blk, offset lc );
extern void CVRtnEnd( dbg_rtn *rtn, offset lc );
extern source_line_number SrcLine;
extern proc_def *CurrProc;
extern struct opcode_entry DbgInfo[];
static void EmitDbg( byte class, pointer ptr );
static void MkBlock( void );
static void AddBlockInfo( dbg_block *blk, bool start );
cue_ctl LineInfo;
fname_ctl DBFiles;
#define CurrProc_debug ((dbg_rtn *)CurrProc->targ.debug)
static void SrcFileNoInit( void ){
/*****************************/
DBFiles.lst = NULL;
DBFiles.count = 0;
}
static void DBSrcFileFini( void ){
/*****************************/
fname_lst *curr, *old;
curr = DBFiles.lst;
while( curr != NULL ){
old = curr;
curr = curr->next;
_Free( old, sizeof( *old ) );
}
DBFiles.lst = NULL;
}
extern uint _CGAPI DBSrcFile( char *fname ) {
/***********************************************/
int index;
int len;
fname_lst *curr, **lnk;
#ifndef NDEBUG
EchoAPI( "DBSrcFile( %c )", fname );
#endif
lnk = &DBFiles.lst;
curr = *lnk;
index = 0;
while( (curr = *lnk) != NULL ) {
if( strcmp( fname, curr->fname ) == 0 ) {
goto found;
}
++index;
lnk = &curr->next;
}
len = strlen( fname );
_Alloc( curr, sizeof( *curr )+len );
curr->len = len+1;
curr->next = NULL;
strcpy( curr->fname, fname );
++DBFiles.count;
*lnk = curr;
found:
#ifndef NDEBUG
EchoAPI( " -> %i\n", index );
#endif
return( index );
}
extern char *SrcFNoFind( uint fno ){
/****************************************/
int index;
fname_lst *curr;
curr = DBFiles.lst;
index = 0;
while( curr != NULL ){
if( index == fno ){
goto found;
}
++index;
curr = curr->next;
}
return( "unknown" );
found:;
return( curr->fname );
}
static void AddCueBlk( cue_ctl *ctl ){
/**************************************/
cue_blk *new;
new = _Alloc( new, sizeof( *new ) );
new->next = NULL;
*ctl->lnk = new;
ctl->curr = new;
ctl->lnk = &new->next;
ctl->next = &new->info[0];
ctl->end = &new->info[CUES_PER_BLK];
}
static void SourceCueInit( cue_ctl *ctl ){
/*********************************/
ctl->head = NULL;
ctl->lnk = &ctl->head;
ctl->next = &ctl->start[0];
ctl->end = &ctl->start[1];
ctl->state.cue = 0;
ctl->state.fno = -1; /* force change */
ctl->state.line = 0;
ctl->state.col = 0;
ctl->count = 0;
}
extern cue_idx CueAdd( int fno, int line, int col ){
/****************************************************/
enum{
EQUAL = 0x00,
LINE_NO = 0x01,
COL_NO = 0x02,
FNO_NO = 0x04,
}cmp;
cue_ctl *ctl;
long diff;
if( fno == 0 && col == 1 && line < PRIMARY_RANGE ){
return( line );
}
ctl = &LineInfo;
cmp = EQUAL;
if( fno != ctl->state.fno ){
cmp |= FNO_NO;
}
if( col != ctl->state.col ){
cmp |= COL_NO;
}
diff = line - ctl->state.line;
if( diff != 0 ){
cmp |= LINE_NO;
}
if( cmp == LINE_NO && 0 <= diff && diff < MAX_LINE_DELTA ){
ctl->state.line = line;
ctl->state.cue += diff;
cmp = EQUAL;
}
if( cmp ){
if( ctl->next >= ctl->end ){
AddCueBlk( ctl );
}
++ctl->state.cue;
ctl->state.fno = fno;
ctl->state.line = line;
ctl->state.col = col;
*ctl->next = ctl->state;
++ctl->next;
++ctl->count;
}
return( ctl->state.cue + PRIMARY_RANGE );
}
extern bool CueFind( cue_idx cue, cue_state *ret ){
/**************************************************/
cue_ctl *ctl;
cue_blk *blk;
cue_state *hi;
long diff;
ctl = &LineInfo;
if( ctl->count == 0 || cue < PRIMARY_RANGE ){
ret->fno = 0;
ret->line = cue;
ret->col = 1;
return( TRUE );
}
cue -= PRIMARY_RANGE;
if( cue < ctl->start[0].cue ){
Zoiks( ZOIKS_078 ); /* lower than low */
return( FALSE );
}
blk = ctl->head;
hi = &ctl->start[1];
while( blk != NULL ){
if( cue < blk->info[0].cue )break;
hi = &blk->info[CUES_PER_BLK];
blk = blk->next;
}
if( blk == NULL ){
/* if ctl->head == NULL then next is == ctl->start[1] */
/* if cue in last blk next is end of entries in blk */
hi = ctl->next;
if( cue > ctl->state.cue ){ /* high than high */
Zoiks( ZOIKS_078 );
return( FALSE );
}
}
do{
--hi;
}while( ( diff = cue - hi->cue ) < 0 );
*ret = *hi;
ret->line += diff;
return( TRUE );
}
#if 0
static void CueLen( cue_ctl *ctl ){
/***************************/
//Set map number to #cues with entry
cue_ctl *ctl;
cue_blk *blk;
cue_state *curr, *last;
long diff;
blk = ctl->head;
if( ctl->count > 0 ){
last = &ctl->start[0];
}
while( blk != NULL ){
curr = &blk->info[0];
if( blk->next == NULL ){
end = ctl->next;
}else{
end = &blk->info[CUES_PER_BLK];
}
while( curr != end ){
last->map = curr->cue - last->cue;
++curr;
}
blk = blk->next;
}
last->map = ctl->state.cue- last->cue;
}
// the only time we can do this is if
// the cue guy has seen all the cues and no cue numbers have been
// released
static cue_idx CueFMap( cue_ctl *ctl, int fno, cue_idx map ){
/***************************/
//Map cues with same file together
cue_ctl *ctl;
cue_blk *blk;
cue_state *base, *curr, *last;
cue_idx map;
cue_idx len;
blk = ctl->head;
if( ctl->count > 0 ){
curr = &ctl->start[0];
if( curr->fno == fno ){
len = curr->map;
curr->map = map;
map += len;
}
}
while( blk != NULL ){
curr = &blk->info[0];
if( blk->next == NULL ){
end = ctl->next;
}else{
end = &blk->info[CUES_PER_BLK];
}
while( curr != end ){
if( curr->fno == fno ){
len = curr->map;
curr->map = map;
map += len;
}
++curr;
}
blk = blk->next;
}
return( map );
}
extern void CueMap( cue_ctl *ctl, cue_state *base ){
/***************************/
//Add a map number so cues from the same file
//can be re-written on a continueum
cue_ctl *ctl;
cue_blk *blk;
cue_state *base, *curr, *last;
int fno;
cue_idx curr_idx;
ctl = &LineInfo;
CueLen( ctl ); /* add lengths */
curr_idx = 0;
for( fno = 0; fno < DBFiles.count; ++fno ){
curr_idx = CueFMap( ctl, fno, curr_idx );
}
return( TRUE );
}
#endif
#if 0
extern DmpCue( cue_idx cue ){
cue_state state;
char *fname;
if( CueFind( cue, &state ) ){
fname = SrcFNoFind( state.fno );
printf( "out %s %d %d\n" , fname, state.line, state.col );
}else{
printf( "bad cue %d\n", cue );
}
}
#endif
static void SourceCueFini( cue_ctl *ctl ){
/*****************************************/
cue_blk *old, *list;
list = ctl->head;
while( list != NULL ){
old = list;
list = list->next;
_Free( old, sizeof( *old ) );
}
ctl->head = NULL;
}
extern void InitDbgInfo() {
/******************************/
cue_idx idx;
char *fname;
uint fno;
SrcFileNoInit();
DBNested( FALSE ); /* set nesting */
SourceCueInit( &LineInfo );
fname = FEAuxInfo( NULL, SOURCE_NAME );
fno = DBSrcFile( fname );
idx = CueAdd( fno, 1, 1 );
SrcLine = 1;
if( _IsModel( DBG_DF ) ) {
DFInitDbgInfo();
}else if( _IsModel( DBG_CV ) ) {
CVInitDbgInfo();
}else{
#if _TARGET &( _TARG_IAPX86 | _TARG_80386 )
WVInitDbgInfo();
#endif
}
}
extern void FiniDbgInfo() {
/******************************/
DBSrcFileFini();
SourceCueFini( &LineInfo );
if( _IsModel( DBG_DF ) ) {
DFFiniDbgInfo();
}else if( _IsModel( DBG_CV ) ) {
CVFiniDbgInfo();
}else{
#if _TARGET &( _TARG_IAPX86 | _TARG_80386 )
WVFiniDbgInfo();
#endif
}
}
extern void _CGAPI DBLineNum( uint no ) {
/*******************************************/
#ifndef NDEBUG
EchoAPI( "\nDBLineNum( %i )\n", no );
#endif
SrcLine = no;
}
extern void _CGAPI DBSrcCue( uint fno, uint line, uint col ) {
/*****************************************************************/
cue_idx idx;
bool hasxcue;
// char *fname;
#ifndef NDEBUG
EchoAPI( "\nDBsrcCue( %i, %i, %i )\n", fno, line, col );
#endif
// fname = SrcFNoFind( fno );
// printf( "in %s %d %d\n", fname, line, col );
hasxcue = _IsntModel( DBG_TYPES ); // Just OMF line nums
if( hasxcue ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?