cvcue.c

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

C
458
字号
        ic->pair = lp->cPair - 1;
    }
}

dip_status      DIPENTRY DIPImpCueAdjust( imp_image_handle *ii,
                imp_cue_handle *ic, int adj, imp_cue_handle *aic )
{
    cv_directory_entry  *cde;
    dip_status          status;
    dip_status          ok;

    cde = FindDirEntry( ii, ic->im, sstSrcModule );
    if( cde == NULL ) {
        DCStatus( DS_ERR|DS_INFO_INVALID );
        return( DS_ERR|DS_INFO_INVALID );
    }
    *aic = *ic;
    ok = DS_OK;
    while( adj > 0 ) {
        status = AdjForward( ii, cde->lfo, aic );
        if( status & DS_ERR ) return( status );
        if( status != DS_OK ) ok = status;
        --adj;
    }
    while( adj < 0 ) {
        status = AdjBackward( ii, cde->lfo, aic );
        if( status & DS_ERR ) return( status );
        if( status != DS_OK ) ok = status;
        ++adj;
    }
    return( ok );
}

search_result   DIPENTRY DIPImpLineCue( imp_image_handle *ii,
                imp_mod_handle im, cue_file_id file, unsigned long line,
                unsigned column, imp_cue_handle *ic )
{
    cv_directory_entry                  *cde;
    cv_sst_src_module_header            *hdr;
    cv_sst_src_module_file_table        *fp;
    cv_sst_src_module_line_number       *lp;
    unsigned_32                         *line_off;
    unsigned                            num_segs;
    unsigned                            seg_idx;
    unsigned long                       best_line;
    virt_mem                            line_base;
    virt_mem                            num_base;
    unsigned                            num_pairs;
    unsigned                            pair;
    unsigned_16                         *line_number;

    column = column;
    cde = FindDirEntry( ii, im, sstSrcModule );
    if( cde == NULL ) return( SR_NONE );
    if( file == 0 ) {
        hdr = VMBlock( ii, cde->lfo, sizeof( *hdr ) );
        if( hdr == NULL ) return( SR_NONE );
        file = hdr->baseSrcFile[0] + cde->lfo;
    }
    ic->im = im;
    ic->file = file;
    fp = VMBlock( ii, file, sizeof( *fp ) );
    if( fp == NULL ) return( SR_NONE );
    num_segs = fp->cSeg;
    fp = VMBlock( ii, file, sizeof( *fp ) + num_segs * sizeof( unsigned_32 ) );
    if( fp == NULL ) return( SR_NONE );
    /* make a copy of the line/offset table so that we don't have to worry
       about the VM system throwing it out */
    line_off = __alloca( num_segs * sizeof( unsigned_32 ) );
    memcpy( line_off, &fp->baseSrcLn[0], num_segs * sizeof( unsigned_32 ) );
    best_line = -1UL;
    for( seg_idx = 0; seg_idx < num_segs; ++seg_idx ) {
        line_base = line_off[seg_idx] + cde->lfo;
        lp = VMBlock( ii, line_base, sizeof( *lp ) );
        if( lp == NULL ) return( SR_NONE );
        num_pairs = lp->cPair;
        num_base = line_base
                + offsetof( cv_sst_src_module_line_number, offset )
                + (unsigned long)num_pairs * sizeof( unsigned_32 );
        for( pair = 0; pair < num_pairs; ++pair ) {
            line_number = VMBlock( ii, num_base, sizeof( *line_number ) );
            if( *line_number >= line && *line_number < best_line ) {
                best_line = *line_number;
                ic->line = line_base;
                ic->pair = pair;
                if( best_line == line ) return( SR_EXACT );
            }
            num_base += sizeof( *line_number );
        }
    }
    if( best_line == -1UL ) return( SR_NONE );
    return( SR_CLOSEST );
}

#define NO_IDX  ((unsigned)-1)

unsigned SearchOffsets( imp_image_handle *ii, virt_mem base,
                        unsigned num_off,
                        addr_off  want_off,
                        addr_off *best_off,
                        addr_off  adj_off )
{
    int         lo_idx;
    int         hi_idx;
    int         idx;
    addr_off    lo_off;
    addr_off    hi_off;
    addr_off    off;
    addr_off    *offp;

#define VMADDR( i )     (base + (i)*sizeof(addr_off))

    lo_idx = 0;
    hi_idx = num_off - 1;
    offp = VMBlock( ii, VMADDR( lo_idx ), sizeof( *offp ) );
    if( offp == NULL ) return( NO_IDX );
    lo_off = *offp + adj_off;
    offp = VMBlock( ii, VMADDR( hi_idx ), sizeof( *offp ) );
    if( offp == NULL ) return( NO_IDX );
    hi_off = *offp + adj_off;
    while( lo_idx <= hi_idx ) {
        idx = (lo_idx + hi_idx ) >> 1;
        offp = VMBlock( ii, VMADDR( idx ), sizeof( *offp ) );
        if( offp == NULL ) return( NO_IDX );
        off = *offp + adj_off;
        if( want_off < off ) {
            hi_idx = idx - 1;
            offp = VMBlock( ii, VMADDR( hi_idx ), sizeof( *offp ) );
            if( offp == NULL ) return( NO_IDX );
            hi_off = *offp + adj_off;
        } else if( want_off > off ) {
            lo_idx = idx + 1;
            offp = VMBlock( ii, VMADDR( lo_idx ), sizeof( *offp ) );
            if( offp == NULL ) return( NO_IDX );
            lo_off = *offp + adj_off;
        } else {
            hi_idx = idx;
            hi_off = off;
            break;
        }
    }
    if( hi_idx < 0 ) return( NO_IDX );
    if( hi_off > *best_off ) return( NO_IDX );
    *best_off = hi_off;
    return( hi_idx );
}

search_result   DIPENTRY DIPImpAddrCue( imp_image_handle *ii,
                imp_mod_handle im, address addr, imp_cue_handle *ic )
{
    cv_directory_entry                  *cde;
    cv_sst_src_module_header            *hdr;
    cv_sst_src_module_file_table        *fp;
    cv_sst_src_module_line_number       *lp;
    off_range                           *ranges;
    unsigned_32                         *files;
    unsigned_32                         *lines;
    virt_mem                            line_base;
    virt_mem                            file_base;
    unsigned                            num_files;
    unsigned                            num_segs;
    unsigned                            file_idx;
    unsigned                            seg_idx;
    address                             curr_addr;
    addr_off                            best_offset;
    unsigned                            pair;
    unsigned                            file_tab_size;

    cde = FindDirEntry( ii, im, sstSrcModule );
    if( cde == NULL ) return( SR_NONE );
    hdr = VMBlock( ii, cde->lfo, sizeof( *hdr ) );
    if( hdr == NULL ) return( SR_NONE );
    ic->im = im;
    ranges = __alloca( hdr->cSeg * sizeof( *ranges ) );
    lines  = __alloca( hdr->cSeg * sizeof( *lines ) );
    num_files = hdr->cFile;
    file_tab_size = num_files * sizeof( unsigned_32 );
    hdr = VMBlock( ii, cde->lfo, sizeof( *hdr ) + file_tab_size );
    files = __alloca( file_tab_size );
    memcpy( files, &hdr->baseSrcFile[0], file_tab_size );
    best_offset = (addr_off)-1UL;
    for( file_idx = 0; file_idx < num_files; ++file_idx ) {
        file_base = files[file_idx] + cde->lfo;
        fp = VMBlock( ii, file_base, sizeof( *fp ) );
        if( fp == NULL ) return( SR_NONE );
        num_segs = fp->cSeg;
        fp = VMBlock( ii, file_base, sizeof( *fp )
                + num_segs * (sizeof( unsigned_32 ) + sizeof( off_range ) ) );
        if( fp == NULL ) return( SR_NONE );
        memcpy( lines, &fp->baseSrcLn[0], num_segs * sizeof( *lines ) );
        memcpy( ranges, &fp->baseSrcLn[num_segs], num_segs * sizeof( *ranges ) );
        for( seg_idx = 0; seg_idx < num_segs; ++seg_idx ) {
            line_base = lines[seg_idx] + cde->lfo;
            lp = VMBlock( ii, line_base, sizeof( *lp ) );
            if( lp == NULL ) return( SR_NONE );
            curr_addr.mach.segment = lp->Seg;
            curr_addr.mach.offset  = 0;
            MapLogical( ii, &curr_addr );
            if( DCSameAddrSpace( curr_addr, addr ) != DS_OK ) continue;
            if( (ranges[seg_idx].start != 0 || ranges[seg_idx].end != 0)
              && (addr.mach.offset < ranges[seg_idx].start + curr_addr.mach.offset
              || addr.mach.offset > ranges[seg_idx].end + curr_addr.mach.offset) ) {
                continue;
            }
            pair = SearchOffsets( ii, line_base +
                offsetof( cv_sst_src_module_line_number, offset[0] ),
                lp->cPair, addr.mach.offset, &best_offset, curr_addr.mach.offset );
            if( pair != NO_IDX ) {
                ic->file = file_base;
                ic->line = line_base;
                ic->pair = pair;
                if( best_offset == addr.mach.offset ) return( SR_EXACT );
            }
        }
    }
    if( best_offset == (addr_off)-1UL ) return( SR_NONE );
    return( SR_CLOSEST );
}

int DIPENTRY DIPImpCueCmp( imp_image_handle *ii, imp_cue_handle *ic1,
                                imp_cue_handle *ic2 )
{
    ii = ii;
    if( ic1->im != ic2->im ) return( ic1->im - ic2->im );
    if( ic1->line < ic2->line ) return( -1 );
    if( ic1->line > ic2->line ) return( +1 );
    return( ic1->pair - ic2->pair );
}

⌨️ 快捷键说明

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