Beispiel #1
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 );
}
Beispiel #2
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;
    }
}
Beispiel #3
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 );
}
Beispiel #4
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 );
}