示例#1
0
/*
 * Gets a symbol scope table record.
 * Returns pointer to a hll_ssr_common structure on success.
 */
void *VMSsRecord( imp_image_handle *ii, hll_dir_entry *hde, unsigned_32 rec_off,
                  unsigned_32 *next_rec, unsigned_16 *sizep )
{
    unsigned_16 size = 0;
    unsigned_8 *p = NULL;

    if( rec_off + 2 <= hde->cb) {
        p = VMBlock( ii, hde->lfo + rec_off, 2 );
        if( p != NULL ) {
            size = *p;
            if( size & 0x80 ) {
                size = (size & 0x7f) << 8;
                size |= p[1];
                rec_off++;
            }
            rec_off++;
            if( rec_off + size <= hde->cb ) {
                p = VMBlock( ii, hde->lfo + rec_off, size );
            }
        }
    }
    if( sizep ) {
        *sizep = size;
    }
    if( next_rec ) {
        *next_rec = rec_off + size;
    }
    return( p );
}
示例#2
0
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 );
}
示例#3
0
search_result SearchFile( imp_image_handle              *ii,
                          address                       addr,
                          imp_cue_handle                *ic,
                          virt_mem                      file_base,
                          cv_directory_entry            *cde,
                          addr_off                      *best_offset)
{
    cv_sst_src_module_file_table        *fp;
    cv_sst_src_module_line_number       *lp;
    virt_mem                            line_base;
    off_range                           *ranges;
    unsigned_32                         *lines;
    unsigned                            num_segs;
    unsigned                            seg_idx;
    address                             curr_addr;
    unsigned                            pair;

    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 );
    ranges = __alloca( num_segs * sizeof( *ranges ) );
    lines  = __alloca( num_segs * sizeof( *lines ) );
    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
          /* The next condition is commented out. Digital Mars tools are known to
           * emit buggy CV4 data where the upper range does not cover all code,
           * causing us to fail finding last addresses within a module.
           */
          /*|| 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 );
        }
    }
    /* We abuse the SR_FAIL return code to really mean SR_CONTINUE (ie. continue
     * searching other files). A SR_CONTINUE code is not defined because it does
     * not make sense as a return value for DIPImpAddrCue()
     */
    return( SR_FAIL );
}
示例#4
0
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;
    unsigned_32                         *files;
    virt_mem                            file_base;
    unsigned                            num_files;
    unsigned                            file_idx;
    addr_off                            best_offset;
    unsigned                            file_tab_size;
    search_result                       rc;

    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;
    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;
        rc = SearchFile( ii, addr, ic, file_base, cde, &best_offset );
        if( rc != SR_FAIL ) return( rc );   /* see comment in SearchFile above */
    }
    if( best_offset == (addr_off)-1UL ) return( SR_NONE );
    return( SR_CLOSEST );
}
示例#5
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 );
        ic->pair = lp->cPair - 1;
    }
}
示例#6
0
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;
    }
}
示例#7
0
void *VMRecord( imp_image_handle *iih, virt_mem rec )
{
    s_common    *p;

    p = VMBlock( iih, rec, sizeof( *p ) );
    if( p != NULL ) {
        p = VMBlock( iih, rec, p->length + sizeof( p->length ) );
    }
    return( p );
}
示例#8
0
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 );
}
示例#9
0
/*
 * Get a block within a section.
 */
void *VMSsBlock( imp_image_handle *ii, hll_dir_entry *hde, unsigned_32 start, size_t len )
{
    if( start < hde->cb && start + len <= hde->cb ) {
        return( VMBlock( ii, hde->lfo + start, len ) );
    }
    return( NULL );
}
示例#10
0
unsigned        DIGENTRY DIPImpModName( imp_image_handle *ii,
                        imp_mod_handle im, char *buff, unsigned buff_size )
{
    cv_directory_entry  *cde;
    cv_sst_module       *mp;
    const char          *name;
    const char          *start;
    const char          *end;
    unsigned            len;

    if( im == IMH_GBL ) {
        return( NameCopy( buff, GBL_NAME, buff_size, sizeof( GBL_NAME ) - 1 ) );
    }
    cde = FindDirEntry( ii, im, sstModule );

    mp = VMBlock( ii, cde->lfo, cde->cb );
    if( mp == NULL ) return( 0 );
    name = (char *)&mp->SegInfo[mp->cSeg];
    len = *(unsigned_8 *)name;
    ++name;
    start = name;
    end = name + len;
    for( ; len != 0; ) {
        if( IS_PATH_CHAR( *name ) ) {
            start = name + 1;
            end = name + len;
        }
        if( *name == EXT_CHAR )
            end = name;
        ++name;
        --len;
    }
    return( NameCopy( buff, start, buff_size, end - start ) );
}
示例#11
0
static walk_result FindAddr( imp_image_handle *ii, cv_directory_entry *cde,
                                void *d )
{
    struct find_mod     *md = d;
    address             *a;
    address             code;
    cv_sst_module       *mp;
    cv_seginfo          *sp;
    int                 left;

    if( cde->subsection != sstModule ) return( WR_CONTINUE );
    a = md->d;
    mp = VMBlock( ii, cde->lfo, cde->cb );
    if( mp == NULL ) return( WR_CONTINUE );
    if( mp->ovlNumber != a->sect_id ) return( WR_CONTINUE );
    sp =  &mp->SegInfo[0];
    left = mp->cSeg;
    for( ;; ) {
        if( left <= 0 ) return( WR_CONTINUE );
        code.mach.segment = sp->Seg;
        code.mach.offset  = sp->offset;
        MapLogical( ii, &code );
        if( code.mach.segment == a->mach.segment &&
            code.mach.offset <= a->mach.offset &&
            (code.mach.offset+sp->cbSeg) > a->mach.offset ) {
            md->im = cde->iMod;
            return( WR_STOP );
        }
        ++sp;
        --left;
    }
}
示例#12
0
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 );
}
示例#13
0
/*
 * Get a 32-bit value.
 */
bool VMGetU32( imp_image_handle *ii, virt_mem start, unsigned_32 *valp )
{
    unsigned_32 *ptr = VMBlock( ii, start, sizeof(*valp) );
    if( ptr ) {
        *valp = *ptr;
        return( TRUE );
    }
    return( FALSE );
}
示例#14
0
/*
 * Get a 32-bit value.
 */
bool VMSsGetU32( imp_image_handle *ii, hll_dir_entry *hde, unsigned_32 start, unsigned_32 *valp )
{
    if( start <= hde->cb - sizeof(*valp) ) {
        unsigned_32 *ptr = VMBlock( ii, hde->lfo + start, sizeof(*valp) );
        if( ptr ) {
            *valp = *ptr;
            return( TRUE );
        }
    }
    return( FALSE );
}
示例#15
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 );
}
示例#16
0
static dip_status LoadMapping( imp_image_handle *ii )
{
    cv_directory_entry  *cde;
    cv_sst_seg_map      *map;
    size_t              size;

    cde = FindDirEntry( ii, IMH_GBL, sstSegMap );
    if( cde == NULL )
        return( DS_ERR|DS_INFO_INVALID );
    map = VMBlock( ii, cde->lfo, cde->cb );
    if( map == NULL )
        return( DS_ERR|DS_FAIL );
    size = map->cSegLog * sizeof( map->segdesc[0] );
    ii->mapping = DCAlloc( size );
    if( ii->mapping == NULL )
        return( DS_ERR|DS_NO_MEM );
    map = VMBlock( ii, cde->lfo, cde->cb ); /* malloc might have unloaded */
    memcpy( ii->mapping, &map->segdesc[0], size );
    ii->map_count = map->cSegLog;
    return( DS_OK );
}
示例#17
0
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;
    for( i = 0; i < file_tab_count; ++i ) {
        ic->pair = 0;
        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 );
}
示例#18
0
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 ) );
}
示例#19
0
dip_status DIPIMPENTRY( LoadInfo )( dig_fhandle fid, imp_image_handle *ii )
{
    dip_status                  ds;
    unsigned long               off;
    unsigned long               size;
    cv_directory_entry          *cde;
    cv_sst_global_types_header  *hdr;

    memset( ii, 0, sizeof( *ii ) );
    ds = FindCV( fid, &off, &size );
    if( ds != DS_OK )
        return( ds );
    ii->sym_fid = fid;
    ii->bias = off;
    ds = VMInit( ii, size );
    if( ds != DS_OK )
        return( ds );
    ii->next_image = ImageList;
    ImageList = ii;
    ds = LoadDirectory( ii, off + CV_SIG_SIZE );
    if( ds != DS_OK ) {
        DCStatus( ds );
        Cleanup( ii );
        return( ds );
    }
    ds = LoadMapping( ii );
    if( ds != DS_OK ) {
        DCStatus( ds );
        Cleanup( ii );
        return( ds );
    }
    cde = FindDirEntry( ii, IMH_GBL, sstGlobalTypes );
    if( cde != NULL ) {
        hdr = VMBlock( ii, cde->lfo, sizeof( *hdr ) );
        if( hdr == NULL ) {
            Cleanup( ii );
            return( DS_ERR|DS_FAIL );
        }
        ii->types_base = cde->lfo
                         + offsetof(cv_sst_global_types_header, offType )
                         + hdr->cType * sizeof( hdr->offType[0] );
    }
    ds = SetMADType( ii );
    if( ds != DS_OK ) {
        DCStatus( ds );
        Cleanup( ii );
        return( ds );
    }
    return( DS_OK );
}
示例#20
0
/*
 * Gets a symbol scope table record.
 * Returns pointer to a hll_ssr_common structure on success.
 */
void *VMRecord( imp_image_handle *ii, virt_mem rec_off, virt_mem *next_rec, unsigned_16 *sizep )
{
    unsigned_16 size = 0;
    unsigned_8 *p;

    p = VMBlock( ii, rec_off, 2 );
    if( p != NULL ) {
        size = *p;
        if( size & 0x80 ) {
            size = (size & 0x7f) << 8;
            size |= p[1];
            rec_off++;
        }
        rec_off++;
        p = VMBlock( ii, rec_off, size );
    }
    if( sizep ) {
        *sizep = size;
    }
    if( next_rec ) {
        *next_rec = rec_off + size;
    }
    return( p );
}
示例#21
0
address         DIGENTRY DIPImpModAddr( imp_image_handle *ii,
                                imp_mod_handle im )
{
    cv_sst_module       *mp;
    cv_directory_entry  *cde;
    address             addr;

    cde = FindDirEntry( ii, im, sstModule );
    if( cde == NULL ) return( NilAddr );
    mp = VMBlock( ii, cde->lfo, cde->cb );
    if( mp == NULL ) return( NilAddr );
    if( mp->cSeg == 0 ) return( NilAddr );
    addr.mach.segment = mp->SegInfo[0].Seg;
    addr.mach.offset  = mp->SegInfo[0].offset;
    MapLogical( ii, &addr );
    return( addr );
}