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