cvcue.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 458 行 · 第 1/2 页

C
458
字号
/****************************************************************************
*
*                            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:  CodeView source line cues.
*
****************************************************************************/


#include <stddef.h>
#include <string.h>
#include "walloca.h"
#include "cvinfo.h"


typedef struct {
    unsigned_32 start;
    unsigned_32 end;
} off_range;

walk_result     DIPENTRY DIPImpWalkFileList( imp_image_handle *ii,
                    imp_mod_handle im, IMP_CUE_WKR *wk, imp_cue_handle *ic,
                    void *d )
{
    cv_directory_entry                  *cde;
    cv_sst_src_module_header            *hdr;
    cv_sst_src_module_file_table        *fp;
    unsigned_32                         *file_off;
    unsigned                            file_tab_size;
    unsigned                            file_tab_count;
    unsigned                            i;
    walk_result                         wr;

    if( im == MH_GBL ) return( WR_CONTINUE );

    cde = FindDirEntry( ii, im, sstSrcModule );
    if( cde == NULL ) return(  WR_CONTINUE );
    hdr = VMBlock( ii, cde->lfo, sizeof( *hdr ) );
    if( hdr == NULL ) return( WR_FAIL );
    file_tab_count = hdr->cFile;
    file_tab_size = file_tab_count * sizeof( unsigned_32 );
    hdr = VMBlock( ii, cde->lfo, sizeof( *hdr ) + file_tab_size );
    /*
        Make a copy of the file table offset so that we don't have to worry
        about the VM system throwing it out.
    */
    file_off = __alloca( file_tab_size );
    memcpy( file_off, &hdr->baseSrcFile[0], file_tab_size );
    ic->im = im;
    ic->pair = 0;
    for( i = 0; i < file_tab_count; ++i ) {
        ic->file = cde->lfo + file_off[i];
        fp = VMBlock( ii, ic->file, sizeof( *fp ) );
        if( fp == NULL ) return( WR_FAIL );
        ic->line = cde->lfo + fp->baseSrcLn[0];
        wr = wk( ii, ic, d );
        if( wr != WR_CONTINUE ) return( wr );
    }
    return( WR_CONTINUE );
}

imp_mod_handle  DIPENTRY DIPImpCueMod( imp_image_handle *ii,
                                imp_cue_handle *ic )
{
    ii = ii;
    return( ic->im );
}

unsigned        DIPENTRY DIPImpCueFile( imp_image_handle *ii,
                        imp_cue_handle *ic, char *buff, unsigned max )
{
    void                                *p;
    unsigned_16                         name_len;
    cv_sst_src_module_file_table        *fp;
    virt_mem                            offset;


    offset = ic->file;
    fp = VMBlock( ii, offset, sizeof( *fp ) );
    if( fp == 0 ) return( 0 );
    offset += offsetof( cv_sst_src_module_file_table, baseSrcLn )
                    + (fp->cSeg * (sizeof( unsigned_32 ) * 3));
    p = VMBlock( ii, offset, sizeof( unsigned_16 ) );
    if( p == NULL ) return( 0 );
    /* Doc says the length is unsigned_16, cvpack says 8. */
    name_len = *(unsigned_8 *)p;
    p = VMBlock( ii, offset + sizeof( unsigned_8 ), name_len );
    if( p == NULL ) return( 0 );
    return( NameCopy( buff, p, max, name_len ) );
}

cue_file_id     DIPENTRY DIPImpCueFileId( imp_image_handle *ii,
                        imp_cue_handle *ic )
{
    ii = ii;
    return( ic->file );
}

unsigned long   DIPENTRY DIPImpCueLine( imp_image_handle *ii,
                        imp_cue_handle *ic )
{
    cv_sst_src_module_line_number       *lp;
    unsigned long                       offset;
    unsigned_16                         *num;

    lp = VMBlock( ii, ic->line, sizeof( *lp ) );
    if( lp == NULL ) return( 0 );
    if( lp->cPair == 0 ) return( 0 );
    offset = offsetof( cv_sst_src_module_line_number, offset )
                + (unsigned long)lp->cPair * sizeof( unsigned_32 )
                + ic->pair * sizeof( unsigned_16 );
    num = VMBlock( ii, ic->line + offset, sizeof( unsigned_16 ) );
    if( num == NULL ) return( 0 );
    return( *num );
}

unsigned        DIPENTRY DIPImpCueColumn( imp_image_handle *ii, imp_cue_handle *ic )
{
    ii = ii; ic = ic;
    return( 0 );
}

address         DIPENTRY DIPImpCueAddr( imp_image_handle *ii,
                        imp_cue_handle *ic )
{
    cv_sst_src_module_line_number       *lp;
    address                             addr;
    unsigned long                       offset;
    unsigned_32                         *off_p;

    lp = VMBlock( ii, ic->line, sizeof( *lp ) );
    if( lp == NULL ) return( NilAddr );
    if( lp->cPair == 0 ) return( NilAddr );
    addr.mach.segment = lp->Seg;
    offset = offsetof( cv_sst_src_module_line_number, offset )
                + (unsigned long)ic->pair * sizeof( unsigned_32 );
    off_p = VMBlock( ii, ic->line + offset, sizeof( unsigned_16 ) );
    if( off_p == NULL ) return( NilAddr );
    addr.mach.offset = *off_p;
    MapLogical( ii, &addr );
    return( addr );
}

static dip_status AdjForward( imp_image_handle *ii, unsigned long bias,
                                imp_cue_handle *ic )
{
    cv_sst_src_module_line_number       *lp;
    cv_sst_src_module_file_table        *fp;
    dip_status                          ds;
    unsigned                            i;

    ds = DS_OK;
    ic->pair++;
    for( ;; ) {
        lp = VMBlock( ii, ic->line, sizeof( *lp ) );
        if( lp == NULL ) return( DS_ERR|DS_FAIL );
        if( ic->pair < lp->cPair ) return( ds );
        fp = VMBlock( ii, ic->file, sizeof( *fp ) );
        if( fp == NULL ) return( DS_ERR|DS_FAIL );
        fp = VMBlock( ii, ic->file, sizeof( *fp ) + fp->cSeg * sizeof( unsigned_32 ) );
        if( fp == NULL ) return( DS_ERR|DS_FAIL );
        i = 0;
        for( ;; ) {
            if( (fp->baseSrcLn[i] + bias) == ic->line ) break;
            ++i;
        }
        if( ++i >= fp->cSeg ) {
            i = 0;
            ds = DS_WRAPPED;
        }
        ic->line = fp->baseSrcLn[i] + bias;
        ic->pair = 0;
    }
}

static dip_status AdjBackward( imp_image_handle *ii, unsigned long bias,
                                imp_cue_handle *ic )
{
    cv_sst_src_module_line_number       *lp;
    cv_sst_src_module_file_table        *fp;
    dip_status                          ds;
    unsigned                            i;

    ds = DS_OK;
    ic->pair--;
    lp = VMBlock( ii, ic->line, sizeof( *lp ) );
    if( lp == NULL ) return( DS_ERR|DS_FAIL );
    for( ;; ) {
        /* if ic->pair went negative, the following compare will fail
           because of unsigned comparison */
        if( ic->pair < lp->cPair ) return( ds );
        fp = VMBlock( ii, ic->file, sizeof( *fp ) );
        if( fp == NULL ) return( DS_ERR|DS_FAIL );
        fp = VMBlock( ii, ic->file, sizeof( *fp ) + fp->cSeg * sizeof( unsigned_32 ) );
        if( fp == NULL ) return( DS_ERR|DS_FAIL );
        i = 0;
        for( ;; ) {
            if( (fp->baseSrcLn[i] + bias) == ic->line ) break;
            ++i;
        }
        if( --i >= fp->cSeg ) {
            i = fp->cSeg - 1;
            ds = DS_WRAPPED;
        }
        ic->line = fp->baseSrcLn[i] + bias;
        lp = VMBlock( ii, ic->line, sizeof( *lp ) );
        if( lp == NULL ) return( DS_ERR|DS_FAIL );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?