Beispiel #1
0
dip_status InitDemand( imp_image_handle *ii )
{
    struct walk_demand  d;

    d.max_size = 0;
    MyWalkModList( ii, WlkDmnd, &d );
    if( d.max_size >= (0x10000UL - sizeof( demand_ctrl )) ) {
        DCStatus( DS_ERR|DS_INFO_INVALID );
        return( DS_ERR|DS_INFO_INVALID );
    }
    if( d.max_size <= LastDmndSize )
        return( DS_OK );
    if( LastDemand != NULL ) {
        Unload( LastDemand );
        DCFree( LastDemand );
    }
    LastDmndSize = d.max_size;
    LastDemand = DCAlloc( _demand_size( d.max_size ) );
    if( LastDemand == NULL ) {
        DCStatus( DS_ERR|DS_NO_MEM );
        return( DS_ERR|DS_NO_MEM );
    }
    LastDemand->link = NULL;
    LastDemand->owner = NULL;
    LastDemand->clear = NULL;
    LastDemand->locks = 0;
    return( DS_OK );
}
Beispiel #2
0
/*
    Adjust the 'src' cue by 'adj' amount and return the result in 'dst'.
    That is, If you get called with "DIPImpCueAdjust( ii, src, 1, dst )",
    the 'dst' handle should be filled in with implementation cue handle
    representing the source cue immediately following the 'src' cue.
    Passing in an 'adj' of -1 will get the immediately preceeding source
    cue. The list of source cues for each file are considered a ring,
    so if 'src' is the first cue in a file, an 'adj' of -1 will return
    the last source cue FOR THAT FILE. The cue adjust never crosses a
    file boundry. Also, if 'src' is the last cue in a file, and 'adj' of
    1 will get the first source cue FOR THAT FILE. If an adjustment
    causes a wrap from begining to end or vice versa, you should return
    DS_WRAPPED status (NOTE: DS_ERR should *not* be or'd in, nor should
    DCStatus be called in this case). Otherwise DS_OK should be returned
    unless an error occurred.
*/
dip_status      DIPENTRY DIPImpCueAdjust( imp_image_handle *ii,
                imp_cue_handle *src, int adj, imp_cue_handle *dst )
/*****************************************************************/
{
    dr_handle       stmts;
    dfline_search   start_state;
    dfline_find     find;
    dip_status      ret;
    imp_mod_handle  imx;
    cue_item        cue;
    cue_list        *cue_map;
    address         map_addr;

    imx = src->imx;
    DRSetDebug( ii->dwarf->handle );    /* must do at each call into DWARF */
    stmts  =  ii->mod_map[imx].stmts;
    if( stmts == 0 ) {
        DCStatus( DS_FAIL );
        return( DS_ERR|DS_FAIL  );
    }
    cue_map= ii->cue_map;
    if( cue_map->imx != imx ) {
        ResetCueInfo( cue_map );
        cue_map->imx = imx;
        map_addr = NilAddr;
        LoadCueMap( stmts, &map_addr, cue_map );
    }
    if( adj < 0 ) {
        start_state = LOOK_LOW;
        adj = -adj;
    } else {
        start_state = LOOK_HIGH;
    }
    cue.fno = src->fno;
    cue.line = src->line;
    cue.col = src->col;
    while( 0 != adj ) {
        find =  FindCue( cue_map, &cue, start_state );
        if( find == LINE_NOT ) break;
        --adj;
    }
    dst->imx = imx;
    dst->fno  =  cue.fno;
    dst->line =  cue.line;
    dst->col  =  cue.col;
    dst->a.mach = cue.mach;
    switch( find ) {
    case LINE_NOT:
        DCStatus( DS_FAIL );
        ret = DS_ERR | DS_FAIL;
        break;
    case LINE_WRAPPED:
        ret = DS_WRAPPED;
        break;
    case LINE_FOUND:
        ret = DS_OK;
        break;
    }
    return( ret );
}
Beispiel #3
0
dip_status hllLocationManyReg( imp_image_handle *iih, unsigned count,
                               const unsigned_8 *reg_list,
                               location_context *lc, location_list *ll )
{
    unsigned            i;
    byte                j;
    unsigned            idx;
    const reg_entry     *reg;
    location_list       reg_ll;
    dip_status          ds;

    j = 0;
    for( i = count; i-- > 0; ) {
        idx = reg_list[i];
        switch( iih->mad ) {
        case MAD_X86:
            if( idx >= CV_X86_AL && idx <= CV_X86_EFLAGS ) {
                reg = &X86_CPURegTable[idx-CV_X86_AL];
            } else if( idx >= CV_X86_ST0 && idx <= CV_X86_STATUS ) {
                reg = &X86_FPURegTable[idx-CV_X86_ST0];
            } else {
                DCStatus( DS_ERR | DS_FAIL );
                return( DS_ERR | DS_FAIL );
            }
            break;
        case MAD_AXP:
            if( !(idx >= CV_AXP_f0 && idx <= CV_AXP_fltfsr) ) {
                DCStatus( DS_ERR | DS_FAIL );
                return( DS_ERR | DS_FAIL );
            }
            reg = &AXP_RegTable[idx-CV_AXP_f0];
            if( reg->ci == CI_LAST ) {
                DCStatus( DS_ERR | DS_FAIL );
                return( DS_ERR | DS_FAIL );
            }
            break;
        default:
            DCStatus( DS_ERR | DS_FAIL );
            return( DS_ERR | DS_FAIL );
        }
        ds = DCItemLocation( lc, reg->ci, &reg_ll );
        if( ds != DS_OK ) {
            DCStatus( ds );
            return( ds );
        }
        memcpy( &ll->e[j], &reg_ll.e[0], reg_ll.num * sizeof( reg_ll.e[0] ) );
        ll->e[j].bit_start += BYTES2BITS( reg->start );
        ll->e[j].bit_length = BYTES2BITS( reg->len );
        j += reg_ll.num;
        ll->flags |= reg_ll.flags;
    }
    ll->num = j;
    return( DS_OK );
}
Beispiel #4
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 );
}
Beispiel #5
0
size_t DIPIMPENTRY( CueFile )( imp_image_handle *ii, imp_cue_handle *ic,
                                          char *buff, size_t buff_size )
/************************************************************************/
{
    char            *name;
    file_walk_name  wlk;
    size_t          len;
    drmem_hdl       stmts;
    drmem_hdl       cu_tag;
    int             i;
    mod_info        *modinfo;

    DRSetDebug( ii->dwarf->handle );    /* must do at each call into dwarf */
    modinfo = IMH2MODI( ii, ic->im );
    stmts = modinfo->stmts;
    cu_tag = modinfo->cu_tag;
    if( stmts == DRMEM_HDL_NULL || cu_tag == DRMEM_HDL_NULL ) {
        DCStatus( DS_FAIL );
        return( 0 );
    }
    wlk.index = ic->fno;
    wlk.ret = NULL;
    wlk.num_dirs = 0;
    wlk.dirs = NULL;
    DRWalkLFiles( stmts, ACueFile, &wlk, ACueDir, &wlk );
    name = wlk.ret;

    // Free directory and file table information
    for( i = 0; i < wlk.num_dirs; i++ ) {
        DCFree( wlk.dirs[i].name );
    }
    DCFree( wlk.dirs );

    if( name == NULL ) {
        DCStatus( DS_FAIL );
        return( 0 );
    }
    // If compilation unit has a DW_AT_comp_dir attribute, we need to
    // stuff that in front of the file pathname, unless that is absolute
    len = DRGetCompDirBuff( cu_tag, buff, buff_size );
    if( ( len > 1 ) && IsRelPathname( name ) ) {  // Ignore empty comp dirs
        len = NameCopy( buff, "/", buff_size, len );
    } else {
        len = 0;
    }
    len = NameCopy( buff, name, buff_size, len );
    DCFree( name );
    return( len );
}
Beispiel #6
0
dip_status     InitModMap( imp_image_handle *ii )
/***********************************************/
// Make the imp_mod_handle  to  dr_handle map
{
    mod_list    list;
    dip_status  ret;

    ret = DS_OK;
    ii->mod_count = 0;
    InitModList( &list );
    InitAddrSym( ii->addr_sym );
    DRSetDebug( ii->dwarf->handle ); /* set dwarf to image */
    DRIterateCompileUnits( &list, ModFill );
    DRDbgClear( ii->dwarf->handle ); /* clear some mem */
    ii->mod_count = list.count;
    ii->mod_map = FiniModInfo( &list );
    if( list.version == VER_V1 ) {
        DRDbgOldVersion( ii->dwarf->handle, 1 );
    } else if( list.version == VER_V2 ) {
        DRDbgOldVersion( ii->dwarf->handle, 2 );
    } else if( list.version == VER_ERROR ) {
        DCStatus( DS_INFO_BAD_VERSION );
        ret = DS_FAIL | DS_INFO_BAD_VERSION;
    }
    return( ret );
}
Beispiel #7
0
walk_result     DIPENTRY DIPImpWalkFileList( imp_image_handle *ii,
                    imp_mod_handle im, IMP_CUE_WKR *wk, imp_cue_handle *ic,
                    void *d )
/*************************************************************************/
{
    file_walk_cue   wlk;
    im_idx          imx;
    dr_handle       stmts;

    imx = IM2IMX( im );
    DRSetDebug( ii->dwarf->handle );    /* must do at each call into DWARF */
    stmts  =  ii->mod_map[imx].stmts;
    if( stmts == 0 ) {
        DCStatus( DS_FAIL );
        return( WR_CONTINUE );
    }
    wlk.stmts = stmts;
    wlk.ii = ii;
    wlk.imx = imx;
    wlk.wk = wk;
    wlk.ic = ic;
    wlk.d  = d;
    wlk.wr =  WR_CONTINUE;
    DRWalkLFiles( stmts, ACueFileNum, &wlk, ACueDir, NULL );
    return( wlk.wr );
}
Beispiel #8
0
char    *DIGENTRY DIPImpModSrcLang( imp_image_handle *ii, imp_mod_handle im )
{
    char       *ret = NULL;

    if( im == IMH_NOMOD ) {
        DCStatus( DS_FAIL );
        return( NULL );
    }
    switch( IM2MODI( ii, im )->lang ) {
    case DR_LANG_UNKNOWN:
//      ret = "unknown";
        ret = "c";
        break;
    case DR_LANG_CPLUSPLUS:
        ret = "cpp";
        break;
    case DR_LANG_FORTRAN:
        ret = "fortran";
        break;
    case DR_LANG_C:
        ret = "c";
        break;
    }
    return( ret );
}
Beispiel #9
0
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 );
}
Beispiel #10
0
static bool InitPageDir( imp_image_handle *ii, unsigned dir_idx )
{
    ii->virt[dir_idx] = DCAllocZ( sizeof( virt_page * ) * DIR_SIZE );
    if( ii->virt[dir_idx] == NULL ) {
        DCStatus( DS_ERR | DS_NO_MEM );
        return( FALSE );
    }
    return( TRUE );
}
Beispiel #11
0
dip_status      DIGENTRY DIPImpTypeArrayInfo( imp_image_handle *ii,
        imp_type_handle *array, location_context *lc,
        array_info *ai, imp_type_handle *index )
{
    /*
        Given an implemenation type handle that represents an array type,
        get information about the array shape and index type. The location
        context is for variable dimensioned arrays again. The 'index'
        parameter is filled in with the type of variable used to subscript
        the array. It may be NULL, in which case no information is returned.
    */

    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    if( array->state == DF_NOT ) {
        InitTypeHandle( ii, array, lc );
    }
    if( array->state == DF_NOT ) {
        DCStatus( DS_ERR | DS_BAD_PARM );
        return( DS_ERR | DS_BAD_PARM  );
    }
    if( array->typeinfo.kind != DR_TYPEK_ARRAY ) {
        DCStatus( DS_ERR | DS_BAD_PARM );
        return( DS_ERR | DS_BAD_PARM  );
    }
    ai->low_bound = array->array.low;
    ai->num_elts = array->array.num_elts;
    ai->num_dims = array->array.dims;
    ai->column_major = array->array.column_major;
    ai->stride = array->array.base_stride;
    if( index != NULL ) {
        index->im = array->im;
        if( array->array.index == DR_HANDLE_NUL ) { //Fake a type up
            index->state = DF_SET;
            index->type  = DR_HANDLE_NUL;
            index->typeinfo.size = 0;
            index->typeinfo.kind = DR_TYPEK_NONE;
            index->typeinfo.mclass = DR_MOD_NONE;
        } else {
            index->state = DF_NOT;
            index->type = array->array.index;
        }
    }
    return( DS_OK );
}
Beispiel #12
0
dip_status VMInit( imp_image_handle *ii, unsigned long size )
{
    ii->vm_dir_num = BLOCK_FACTOR( size, DIR_SIZE * VM_PAGE_SIZE );
    ii->virt = DCAllocZ( ii->vm_dir_num * sizeof( ii->virt ) );
    if( ii->virt == NULL ) {
        DCStatus( DS_ERR|DS_NO_MEM );
        return( DS_ERR|DS_NO_MEM );
    }
    return( DS_OK );
}
Beispiel #13
0
static int InitPageDir( imp_image_handle *iih, unsigned dir_idx )
{
    iih->virt[dir_idx] = DCAlloc( sizeof( virt_page * ) * DIR_SIZE );
    if( iih->virt[dir_idx] == NULL ) {
        DCStatus( DS_ERR | DS_NO_MEM );
        return( 0 );
    }
    memset( iih->virt[dir_idx], 0, sizeof( virt_page * ) * DIR_SIZE );
    return( 1 );
}
Beispiel #14
0
search_result SearchMbr( imp_image_handle *ii, imp_type_handle *it, lookup_item *li, void *d )
//Search for matching lookup item
{
    dr_handle       btype;
    type_wlk_lookup df;
    df_cleaner      cleanup;

    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    if( it->state == DF_NOT ) {
        if( DRGetTypeInfo( it->type, &it->typeinfo ) ) {
            it->state = DF_SET;
        }
    }
    if( it->state == DF_NOT ) {
        return( SR_NONE );
    }
    df.com.im = it->im;
    df.com.ii = ii;
    df.com.d = d;
    df.com.root = it->type;
    df.com.inh = DR_HANDLE_NUL;
    df.com.vbase = NULL;
    cleanup.rtn = FreeBases;   //push cleanup
    cleanup.d = &df.com.vbase;
    cleanup.prev = Cleaners;
    Cleaners = &cleanup;
    btype = DRSkipTypeChain( it->type );
    if( li->case_sensitive ) {
        df.comp = memcmp;
    } else {
        df.comp = memicmp;
    }
    df.li = li;
    df.sr = SR_NONE;
    switch( it->typeinfo.kind ) {
    case DR_TYPEK_ENUM:
        df.com.sclass = SYM_ENUM;
        df.com.einfo.size = it->typeinfo.size;
        df.com.einfo.sign = it->typeinfo.modifier.sign;
        DRWalkEnum( btype, AEnumMemLookup, &df );
        break;
    case DR_TYPEK_STRUCT:
    case DR_TYPEK_UNION:
    case DR_TYPEK_CLASS:
        df.com.sclass = SYM_MEM;
        DRWalkStruct( btype, StrucWlkLookup, &df );
        break;
    default:
        DCStatus( DS_ERR | DS_BAD_PARM );
        df.sr = SR_FAIL;
    }
    FreeBases( &df.com.vbase ); // free virtual base list
    Cleaners = cleanup.prev; // pop cleanup
    return( df.sr );
}
Beispiel #15
0
size_t      DIGENTRY DIPImpModName( imp_image_handle *ii,
                        imp_mod_handle im, char *buff, size_t buff_size )
{
    char        *name;
    size_t      len;

    if( im == IMH_NOMOD || (name = IMH2MODI( ii, im )->name) == NULL ) {
        DCStatus( DS_FAIL );
        return( 0 );
    }
    len = NameCopy( buff, name, buff_size, 0 );
    return( len );
}
Beispiel #16
0
unsigned    DIGENTRY DIPImpModName( imp_image_handle *ii,
                        imp_mod_handle im, char *buff, unsigned max )
{
    char        *name;
    unsigned    len;

    if( im == IMH_NOMOD || (name = IM2MODI( ii, im )->name) == NULL ) {
        DCStatus( DS_FAIL );
        return( 0 );
    }
    len = NameCopy( buff, name, max );
    return( len );
}
Beispiel #17
0
extern walk_result WalkTypeSymList( imp_image_handle *ii, imp_type_handle *it,
                                    IMP_SYM_WKR *wk, imp_sym_handle *is, void *d ) {
    dr_handle       btype;
    type_wlk_wlk    df;
    df_cleaner      cleanup;

    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    if( it->state == DF_NOT ) {
        if(  DRGetTypeInfo( it->type, &it->typeinfo ) ) {
            it->state = DF_SET;
        }
    }
    if( it->state == DF_NOT ) {
        return( WR_STOP );
    }
    df.com.im = it->im;
    df.com.ii = ii;
    df.com.d = d;
    df.com.root = it->type;
    df.com.inh = DR_HANDLE_NUL;
    df.com.vbase = NULL;
    cleanup.rtn = FreeBases;   //push cleanup
    cleanup.d = &df.com.vbase;
    cleanup.prev = Cleaners;
    Cleaners = &cleanup;
    btype = DRSkipTypeChain( it->type );
    df.is = is;
    df.wk = wk;
    df.wr = WR_CONTINUE;
    switch( it->typeinfo.kind ) {
    case DR_TYPEK_ENUM:
        df.com.sclass = SYM_ENUM;
        df.com.einfo.size = it->typeinfo.size;
        df.com.einfo.sign = it->typeinfo.modifier.sign;
        DRWalkEnum( btype, AEnumMem, &df );
        break;
    case DR_TYPEK_STRUCT:
    case DR_TYPEK_UNION:
    case DR_TYPEK_CLASS:
        df.com.sclass = SYM_MEM;
        DRWalkStruct( btype, StrucWlk, &df );
        break;
    default:
        DCStatus( DS_ERR | DS_BAD_PARM );
        df.wr = WR_STOP;
    }
    FreeBases( &df.com.vbase ); // free virtual base list
    Cleaners = cleanup.prev; // pop cleanup
    return( df.wr );
}
Beispiel #18
0
dip_status  DIGENTRY DIPImpModInfo( imp_image_handle *ii,
                                imp_mod_handle im, handle_kind hk )
{
    /*
        Return DS_OK if the module has the kind of information indicated
        by 'hk', DS_FAIL if it does not.
    */
    dip_status  ret;
    dr_handle   stmts;
    mod_info    *modinfo;

    ret = DS_FAIL;
    if( im == IMH_NOMOD ) {
        DCStatus( ret );
        return( ret );
    }
    modinfo = IM2MODI( ii, im );
    switch( hk ) {
    case HK_IMAGE:
        break;
    case HK_TYPE:
        if( modinfo->stmts != 0 ) {
            ret = DS_OK;
        }
        break;
    case HK_CUE:
        stmts = modinfo->stmts;
        if( stmts != 0 ) {  // need to get rid of stmts for file with no cues
            l_walk_info walk;
            address     a;

            walk.ii = ii;
            walk.im = im;
            walk.ret = &a;
            DRSetDebug( ii->dwarf->handle ); /* set dwarf to image */
            if( !DRWalkLines( stmts, SEG_CODE, ALineCue, &walk ) ) {
                ret = DS_OK;
            }
        }
        break;
    case HK_SYM: /* if no lang assumed linker generated */
        if( modinfo->lang != DR_LANG_UNKNOWN ) {
            ret = DS_OK;
        }
        break;
    default:
        break;
    }
    return( ret );
}
Beispiel #19
0
address DIGENTRY DIPImpModAddr( imp_image_handle *ii, imp_mod_handle im )
{
    l_walk_info walk;
    address     a;
    dr_handle   stmts;

    if( im != IMH_NOMOD && (stmts = IM2MODI( ii, im )->stmts) != 0 ) {
        DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
        walk.ii = ii;
        walk.im = im;
        walk.ret = &a;
        if( !DRWalkLines( stmts, SEG_CODE, AModAddr, &walk ) ) {
            // found
            return( a );
        }
    }
    DCStatus( DS_FAIL );
    return( NilAddr );
}
Beispiel #20
0
static bool AMemLookup( dr_handle var, int index, void *_d )
/**********************************************************/
{
    type_wlk_lookup *d = _d;
    imp_sym_handle  *is;
    char            *name;
    unsigned        len;

    name =  DRGetName( var );
    if( name == NULL ) {
        DCStatus( DS_FAIL );
        return( FALSE );
    }
    len = strlen( name );
    if( len == d->li->name.len && d->comp( name, d->li->name.start, len ) == 0 ) {
        is = DCSymCreate( d->com.ii, d->com.d );
        SetSymHandle( (type_wlk *)d, is );
        is->sym = var;
        switch( index ) {
        case 0:
            is->sclass = SYM_MEM;
            break;
        case 2:
            is->sclass = SYM_MEMVAR;     // static member
            break;
        case 3:
            if( DRGetVirtuality( var ) == DR_VIRTUALITY_VIRTUAL  ) {
                is->sclass = SYM_VIRTF;   // virtual func
            } else if( !DRIsSymDefined( var ) ) {
                is->sclass = SYM_MEMF;    // memfunc decl
            } else {
                is->sclass = SYM_MEMVAR;   // inlined defn treat like a var
            }
            break;
        }
        d->sr = SR_EXACT;
    }
    DCFree( name );
    return( TRUE );
}
Beispiel #21
0
walk_result DIPIMPENTRY( WalkFileList )( imp_image_handle *ii,
                    imp_mod_handle im, DIP_IMP_CUE_WALKER *wk, imp_cue_handle *ic,
                    void *d )
/*************************************************************************/
{
    file_walk_cue   wlk;
    drmem_hdl       stmts;

    DRSetDebug( ii->dwarf->handle );    /* must do at each call into DWARF */
    stmts = IMH2MODI( ii, im )->stmts;
    if( stmts == DRMEM_HDL_NULL ) {
        DCStatus( DS_FAIL );
        return( WR_CONTINUE );
    }
    wlk.stmts = stmts;
    wlk.ii = ii;
    wlk.im = im;
    wlk.wk = wk;
    wlk.ic = ic;
    wlk.d = d;
    wlk.wr = WR_CONTINUE;
    DRWalkLFiles( stmts, ACueFileNum, &wlk, ACueDir, NULL );
    return( wlk.wr );
}
Beispiel #22
0
static bool AEnumMemLookup( dr_handle var, int index, void *_d )
/**************************************************************/
{
    type_wlk_lookup *d = _d;
    imp_sym_handle  *is;
    char            *name;
    unsigned        len;

    index = index;
    name =  DRGetName( var );
    if( name == NULL ) {
        DCStatus( DS_FAIL );
        return( FALSE );
    }
    len = strlen( name );
    if( len == d->li->name.len && d->comp( name, d->li->name.start, len ) == 0 ) {
        is = DCSymCreate( d->com.ii, d->com.d );
        SetSymHandle( (type_wlk *)d, is );
        is->sym = var;
        d->sr = SR_EXACT;
    }
    DCFree( name );
    return( TRUE );
}
Beispiel #23
0
search_result DoLookupSym( imp_image_handle *ii, symbol_source ss,
                         void *source, lookup_item *li, location_context *lc, void *d )
{
    imp_mod_handle      im;
    search_result       sr;
    lookup_item         item;
    char                *buff;
    char                *src;
    char                *dst;
    unsigned            len;
    unsigned            op_len;
    imp_sym_handle      *scope_is;

    if( *li->name.start == SH_ESCAPE ) {
        CollectSymHdl( (byte *)li->name.start, DCSymCreate( ii, d ) );
        return( SR_EXACT );
    }
    if( li->type == ST_NAMESPACE ) return( SR_NONE );
    item = *li;
    if( ss == SS_SCOPESYM ) {
        scope_is = source;
        len = ImpInterface.sym_name( ii, scope_is, NULL, SN_SOURCE, NULL, 0 );
        item.scope.start = __alloca( len + 1 );
        ImpInterface.sym_name( ii, scope_is, NULL, SN_SOURCE, item.scope.start, len + 1 );
        item.scope.len = len;
        ss = SS_MODULE;
        item.mod = scope_is->im;
        source = &item.mod;
    }
    if( item.type == ST_OPERATOR ) {
        src = item.name.start;
        len = item.name.len;
        buff = __alloca( len + 20 );
        dst = buff;
        for( ;; ) {
            if( len == 0 ) break;
            if( src == item.source.start ) {
                op_len = __mangle_operator( src, item.source.len, buff );
                if( op_len == 0 ) {
                    DCStatus( DS_ERR|DS_INVALID_OPERATOR );
                    return( SR_NONE );
                }
                dst += op_len;
                src += item.source.len;
                len -= item.source.len;
            } else {
                *dst++ = *src++;
                --len;
            }
        }
        item.name.len = dst - buff;
        item.name.start = buff;
    }
    sr = SR_NONE;
    switch( ss ) {
    case SS_SCOPED:
        if( ImpInterface.addr_mod( ii, *(address *)source, &im ) == SR_NONE ) {
            im = item.mod;
        } else if( item.mod == NO_MOD || item.mod == im ) {
            if( !item.file_scope && item.type == ST_NONE ) {
                sr = SearchLclScope( ii, im, (address *)source, &item, d );
            }
        } else {
            im = item.mod;
        }
        if( im != NO_MOD && sr == SR_NONE ) {
            sr = SearchFileScope( ii, im, &item, d );
        }
        break;
    case SS_MODULE:
        im = *(imp_mod_handle *)source;
        if( item.mod == NO_MOD || item.mod == im ) {
            sr = SearchFileScope( ii, im, &item, d );
        }
        break;
    case SS_TYPE:
        if( item.mod != NO_MOD ) return( SR_NONE );
        switch( item.type ) {
        case ST_TYPE:
        case ST_STRUCT_TAG:
        case ST_CLASS_TAG:
        case ST_UNION_TAG:
        case ST_ENUM_TAG:
            return( SR_NONE );
        }
        return( SearchMbr( ii, (imp_type_handle *)source, &item, d ) );
    }
    if( sr == SR_NONE ) {
        switch( item.type ) {
        case ST_NONE:
        case ST_DESTRUCTOR:
        case ST_OPERATOR:
            sr = SearchGbl( ii, im, (imp_mod_handle)item.mod, &item, d );
            break;
        }
    }
    return( sr );
}
Beispiel #24
0
/*
    Adjust the 'src' cue by 'adj' amount and return the result in 'dst'.
    That is, If you get called with "DIPImpCueAdjust( ii, src, 1, dst )",
    the 'dst' handle should be filled in with implementation cue handle
    representing the source cue immediately following the 'src' cue.
    Passing in an 'adj' of -1 will get the immediately preceeding source
    cue. The list of source cues for each file are considered a ring,
    so if 'src' is the first cue in a file, an 'adj' of -1 will return
    the last source cue FOR THAT FILE. The cue adjust never crosses a
    file boundry. Also, if 'src' is the last cue in a file, and 'adj' of
    1 will get the first source cue FOR THAT FILE. If an adjustment
    causes a wrap from begining to end or vice versa, you should return
    DS_WRAPPED status (NOTE: DS_ERR should *not* be or'd in, nor should
    DCStatus be called in this case). Otherwise DS_OK should be returned
    unless an error occurred.
*/
dip_status DIPIMPENTRY( CueAdjust )( imp_image_handle *ii,
                imp_cue_handle *src, int adj, imp_cue_handle *dst )
/*****************************************************************/
{
    drmem_hdl       stmts;
    dfline_search   start_state;
    dfline_find     find;
    dip_status      ret;
    cue_item        cue;
    cue_list        *cue_map;
    address         map_addr;

    DRSetDebug( ii->dwarf->handle );    /* must do at each call into DWARF */
    stmts = IMH2MODI( ii, src->im )->stmts;
    if( stmts == DRMEM_HDL_NULL ) {
        DCStatus( DS_FAIL );
        return( DS_ERR|DS_FAIL  );
    }
    cue_map = ii->cue_map;
    if( cue_map->im != src->im ) {
        ResetCueInfo( cue_map );
        cue_map->im = src->im;
        map_addr = NilAddr;
        LoadCueMap( stmts, &map_addr, cue_map );
    }
    if( adj < 0 ) {
        start_state = LOOK_LOW;
        adj = -adj;
    } else {
        start_state = LOOK_HIGH;
    }
    cue.fno = src->fno;
    cue.line = src->line;
    cue.col = src->col;
    cue.mach = src->a.mach;
    find = LINE_NOT;
    while( 0 != adj ) {
        find = FindCue( cue_map, &cue, start_state );
        if( find == LINE_NOT ) break;
        --adj;
    }
    dst->im = src->im;
    dst->fno = cue.fno;
    dst->line = cue.line;
    dst->col = cue.col;
    dst->a.mach = cue.mach;
    ret = DS_FAIL;
    switch( find ) {
    case LINE_NOT:
        DCStatus( DS_FAIL );
        ret = DS_ERR | DS_FAIL;
        break;
    case LINE_WRAPPED:
        ret = DS_WRAPPED;
        break;
    case LINE_FOUND:
        ret = DS_OK;
        break;
    }
    return( ret );
}
Beispiel #25
0
/*
 * AllocLinkTable - allocate the demand load link table
 *
 */
static dip_status AllocLinkTable( section_info *inf, unsigned long num_links,
                                unsigned long first_link )
{
    dword               **lnk_tbl;
    dword               *lnk;
    mod_table           *tbl;
    unsigned            num;
    unsigned long       count;
    unsigned            i;
    unsigned            d;
    mod_info            *mod;
    unsigned            tbl_entries;
    dword               end;
    info_block          *blk;

    tbl_entries = ((num_links+(MAX_LINK_ENTRIES-1)) / MAX_LINK_ENTRIES) + 1;
    lnk_tbl = DCAlloc( tbl_entries * sizeof( dword * ) );
    if( lnk_tbl == NULL ) {
        DCStatus( DS_ERR|DS_NO_MEM );
        return( DS_ERR|DS_NO_MEM );
    }
    for( i = 0; i < tbl_entries; ++i ) lnk_tbl[i] = NULL;
    inf->dmnd_link = lnk_tbl;
    i = 0;
    count = num_links;
    while( count != 0 ) {
        num = (count>MAX_LINK_ENTRIES) ? MAX_LINK_ENTRIES : count;
        lnk = DCAlloc( num*sizeof(dword));
        if( lnk == NULL ) {
            DCStatus( DS_ERR|DS_NO_MEM );
            return( DS_ERR|DS_NO_MEM );
        }
        lnk_tbl[i++] = lnk;
        if( !inf->ctl->v2 ) {
            if( DCRead(inf->ctl->sym_file,lnk,num*sizeof(dword))!=num*sizeof(dword)) {
                DCStatus( DS_ERR|DS_FREAD_FAILED );
                return( DS_ERR|DS_FREAD_FAILED );
            }
        }
        count -= num;
    }
    lnk = *lnk_tbl;
    num = 0;
    count = 0;
    for( d = DMND_FIRST; d < DMND_NUM; ++d ) {
        for( blk = inf->mod_info; blk != NULL; blk = blk->next ) {
            tbl = blk->link;
            for( i = 0; i < tbl->count; ++i ) {
                mod = (mod_info *)((byte *)blk->info + tbl->mod_off[i]);
                if( inf->ctl->v2 ) {
                    if( mod->di[d].u.size != 0 ) {
                        if( num >= MAX_LINK_ENTRIES ) {
                            lnk = *++lnk_tbl;
                            num = 0;
                        }
                        lnk[num] = mod->di[d].info_off;
                        end = lnk[num] + mod->di[d].u.size;
                        mod->di[d].u.entries = 1;
                        mod->di[d].info_off = count;
                        ++num;
                        ++count;
                    }
                } else {
                    if( mod->di[d].u.entries != 0 ) {
                        mod->di[d].info_off =
                        (mod->di[d].info_off-first_link)/sizeof(dword);
                    }
                }
            }
        }
    }
    if( inf->ctl->v2 ) {
        if( num >= MAX_LINK_ENTRIES ) {
            lnk = *++lnk_tbl;
            num = 0;
        }
        lnk[num] = end;
    }
    return( DS_OK );
}
Beispiel #26
0
/*
 * AdjustMods - adjust the demand info offsets in all the modules
 *            - allocate module index table
 *            - allocate demand load link table
 */
dip_status AdjustMods( section_info *inf, unsigned long adjust )
{
    info_block          *blk;
    unsigned            count;
    unsigned            mod_off;
    mod_table           *tbl;
    mod_info            *mod;
    unsigned long       num_links;
    unsigned long       first_link;
    unsigned long       last_link;
    unsigned            d;
    unsigned            num;
    dword               *lnk;
    dword               **lnk_tbl;
    unsigned long       off;
    dip_status          ok;

    last_link = 0;
    first_link = ~0;
    num_links = 1;
    for( blk = inf->mod_info; blk != NULL; blk = blk->next ) {
        count = 0;
        for( mod_off = 0; mod_off < blk->size;
                mod_off += sizeof( mod_info ) + mod->name[0] ) {
            ++count;
            mod = (mod_info *)((byte *)blk->info + mod_off);
        }
        tbl = DCAlloc( sizeof(mod_table) + (count-1)*sizeof(mod_info *) );
        if( tbl == NULL ) {
            DCStatus( DS_ERR|DS_NO_MEM );
            return( DS_ERR|DS_NO_MEM );
        }
        tbl->count = count;
        blk->link = tbl;
        count = 0;
        for( mod_off = 0; mod_off < blk->size;
                mod_off += sizeof( mod_info ) + mod->name[0] ) {
            tbl->mod_off[count++] = mod_off;
            mod = (mod_info *)((byte *)blk->info + mod_off);
            for( d = DMND_FIRST; d < DMND_NUM; ++d ) {
                if( inf->ctl->v2 ) {
                    if( mod->di[d].u.size != 0 ) ++num_links;
                } else {
                    if( mod->di[d].u.entries != 0 ) {
                        num_links = mod->di[d].info_off;
                        if( num_links < first_link ) {
                            first_link = num_links;
                        }
                        num_links += mod->di[d].u.entries
                                        * sizeof(dword);
                        if( num_links > last_link ) {
                            last_link = num_links;
                        }
                    }
                }
            }
        }
    }
    if( !inf->ctl->v2 ) {
        off = first_link + adjust;
        if( DCSeek( inf->ctl->sym_file, off, DIG_ORG) != off ) {
            DCStatus( DS_ERR|DS_FSEEK_FAILED );
            return( DS_ERR|DS_FSEEK_FAILED );
        }
        num_links = (last_link - first_link) / sizeof( dword ) + 2;
    }
    ok = AllocLinkTable( inf, num_links, first_link );
    if( ok != DS_OK ) return( ok );
    num = 0;
    lnk_tbl = inf->dmnd_link;
    lnk = *lnk_tbl;
    for( ;; ) {
        if( num_links == 0 ) break;
        if( num >= MAX_LINK_ENTRIES ) {
            lnk = *++lnk_tbl;
            num = 0;
        }
        /*
         * shift over one bit so as to leave the lower bit
         * clear for testing if it is allocated or not
         */
        lnk[num] = (lnk[num] + adjust) << 1;
        ++num;
        --num_links;
    }
    return( DS_OK );
}
Beispiel #27
0
search_result DIPIMPENTRY( LineCue )( imp_image_handle *ii,
                imp_mod_handle im, cue_fileid file, unsigned long line,
                unsigned column, imp_cue_handle *ic )
/**********************************************************************/
{
    search_result   ret;
    dfline_find     find;
    dfline_search   what;
    drmem_hdl       stmts;
    cue_list        *cue_map;
    address         map_addr;
    cue_item        cue;

    if( im == IMH_NOMOD ) {
        DCStatus( DS_FAIL );
        return( SR_NONE );
    }
    DRSetDebug( ii->dwarf->handle );    /* must do at each call into DWARF */
    stmts = IMH2MODI( ii, im )->stmts;
    if( stmts == DRMEM_HDL_NULL ) {
        return( SR_NONE );
    }
    cue_map= ii->cue_map;
    if( cue_map->im != im ) {
        ResetCueInfo( cue_map );
        cue_map->im = im;
        map_addr = NilAddr;
        LoadCueMap( stmts, &map_addr, cue_map );
    }
    if( file == 0 ) {   // primary file
        cue.fno = 1;
    } else {
        cue.fno = (uint_16)file;
    }
    cue.line = line;
    cue.col = (uint_16)column;
    cue.mach.offset = 0;
    cue.mach.segment = 0;
    ic->a = NilAddr;
    if( line == 0 ) {
        what = LOOK_FILE;
    } else {
        what = LOOK_CLOSEST;
    }
    find = FindCue( cue_map, &cue, what );
    ic->im = im;
    ic->fno = cue.fno;
    ic->line = cue.line;
    ic->col = cue.col;
    ic->a.mach = cue.mach;
    ret = SR_NONE;
    switch( find ) {
    case LINE_CLOSEST:
        ret = SR_CLOSEST;
        break;
    case LINE_FOUND:
        ret = SR_EXACT;
        break;
    case LINE_NOT:
        ret = SR_NONE;
        break;
    }
    return( ret );
}
Beispiel #28
0
static search_result DoLookupSym( imp_image_handle *ii, symbol_source ss,
                         void *source, lookup_item *li, location_context *lc, void *d )
{
    imp_mod_handle      im;
    search_result       sr;
    lookup_item         sym_li;
    char                *buff;
    const char          *src;
    char                *dst;
    size_t              len;
    unsigned            op_len;
    imp_sym_handle      *scope_is;

    lc = lc;
    if( GETU8( li->name.start ) == SH_ESCAPE ) {
        CollectSymHdl( li->name.start, DCSymCreate( ii, d ) );
        return( SR_EXACT );
    }
    if( li->type == ST_NAMESPACE )
        return( SR_NONE );
    sym_li = *li;
    if( ss == SS_SCOPESYM ) {
        char    *scope_name;
        scope_is = source;
        len = ImpInterface.SymName( ii, scope_is, NULL, SN_SOURCE, NULL, 0 );
        scope_name = __alloca( len + 1 );
        ImpInterface.SymName( ii, scope_is, NULL, SN_SOURCE, scope_name, len + 1 );
        sym_li.scope.start = scope_name;
        sym_li.scope.len = len;
        ss = SS_MODULE;
        sym_li.mod = IMH2MH( scope_is->im );
        source = &sym_li.mod;
    }
    if( sym_li.type == ST_OPERATOR ) {
        src = sym_li.name.start;
        len = sym_li.name.len;
        buff = __alloca( len + 20 );
        dst = buff;
        for( ;; ) {
            if( len == 0 )
                break;
            if( src == sym_li.source.start ) {
                op_len = __mangle_operator( src, sym_li.source.len, buff );
                if( op_len == 0 ) {
                    DCStatus( DS_ERR|DS_INVALID_OPERATOR );
                    return( SR_NONE );
                }
                dst += op_len;
                src += sym_li.source.len;
                len -= sym_li.source.len;
            } else {
                *dst++ = *src++;
                --len;
            }
        }
        sym_li.name.len = dst - buff;
        sym_li.name.start = buff;
    }
    sr = SR_NONE;
    im = IMH_NOMOD;
    switch( ss ) {
    case SS_SCOPED:
        if( ImpInterface.AddrMod( ii, *(address *)source, &im ) == SR_NONE ) {
            im = MH2IMH( sym_li.mod );
        } else if( MH2IMH( sym_li.mod ) == IMH_NOMOD || MH2IMH( sym_li.mod ) == im ) {
            if( !sym_li.file_scope && sym_li.type == ST_NONE ) {
                sr = SearchLclScope( ii, im, (address *)source, &sym_li, d );
            }
        } else {
            im = MH2IMH( sym_li.mod );
        }
        if( im != IMH_NOMOD && sr == SR_NONE ) {
            sr = SearchFileScope( ii, im, &sym_li, d );
        }
        break;
    case SS_MODULE:
        im = *(imp_mod_handle *)source;
        if( MH2IMH( sym_li.mod ) == IMH_NOMOD || MH2IMH( sym_li.mod ) == im ) {
            sr = SearchFileScope( ii, im, &sym_li, d );
        }
        break;
    case SS_TYPE:
        if( MH2IMH( sym_li.mod ) != IMH_NOMOD )
            return( SR_NONE );
        switch( sym_li.type ) {
        case ST_TYPE:
        case ST_STRUCT_TAG:
        case ST_CLASS_TAG:
        case ST_UNION_TAG:
        case ST_ENUM_TAG:
            return( SR_NONE );
        }
        return( SearchMbr( ii, (imp_type_handle *)source, &sym_li, d ) );
    }
    if( sr == SR_NONE ) {
        switch( sym_li.type ) {
        case ST_NONE:
        case ST_DESTRUCTOR:
        case ST_OPERATOR:
            sr = SearchGbl( ii, im, MH2IMH( sym_li.mod ), &sym_li, d );
            break;
        }
    }
    return( sr );
}
Beispiel #29
0
search_result DIPIMPENTRY( AddrCue )( imp_image_handle *ii,
                imp_mod_handle im, address addr, imp_cue_handle *ic )
/*******************************************************************/
{
    /* Search for the closest cue in the given module that has an address
     * less then or equal to the given address. If there is no such cue
     * return SR_NONE. If there is one exactly at the address return
     * SR_EXACT. Otherwise, return SR_CLOSEST.
     */
    address         map_addr;
    search_result   ret;
    cue_list        *cue_map;
    cue_item        cue;
    drmem_hdl       stmts;

    if( im == IMH_NOMOD ) {
        DCStatus( DS_FAIL );
        return( SR_NONE );
    }
    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    stmts = IMH2MODI( ii, im )->stmts;
    if( stmts == DRMEM_HDL_NULL ) {
        return( SR_NONE );
    }
    map_addr = addr;
    cue_map = ii->cue_map;
    Real2Map( ii->addr_map, &map_addr );
    if( cue_map->im != im ) {
        ResetCueInfo( cue_map );
        cue_map->im = im;
        LoadCueMap( stmts, &map_addr, cue_map );
    }
    ic->im = im;
    ic->fno = 0;
    ic->line = 0;
    ic->col = 0;
    ic->a = NilAddr;
    ret = SR_NONE;
    if( map_addr.mach.segment == cue_map->last.mach.segment
      && map_addr.mach.offset  >= cue_map->last.mach.offset
      && map_addr.mach.offset  <  cue_map->last.next_offset ) {
        ic->fno = cue_map->last.fno;
        ic->line = cue_map->last.line;
        ic->col = cue_map->last.col;
        ic->a.mach = cue_map->last.mach;
        if( cue_map->last.mach.offset == map_addr.mach.offset ) {
            ret = SR_EXACT;
        } else {
            ret = SR_CLOSEST;
        }
        return( ret );
     }
    if( FindCueOffset( cue_map, &map_addr.mach, &cue ) ) {
        ic->fno = cue.fno;
        ic->line = cue.line;
        ic->col = cue.col;
        ic->a.mach = cue.mach;
        if( cue.mach.offset == map_addr.mach.offset ) {
            ret = SR_EXACT;
        } else {
            ret = SR_CLOSEST;
        }
        cue_map->last = cue;
    }
    return( ret );
}
Beispiel #30
0
/*
 * Load debug info if it's in the HLL/CV format.
 */
dip_status DIGENTRY DIPImpLoadInfo( dig_fhandle h, imp_image_handle *ii )

{
    dip_status      rc;

    /* Init the module handle. */
    memset( ii, 0, sizeof( *ii ) );
    ii->mad = MAD_X86;                  /* No known non-x86 support */
    ii->sym_file = h;
    ii->is_32bit = 1;
    ii->format_lvl = HLL_LVL_NB04;
    ii->next_image = ImageList;
    ImageList = ii;

    /* Read basic HLL and executable image bits. */
    rc = FindHLL( ii );
    if( rc == DS_OK ) {
        rc = VMInit( ii, ii->size );
    }

    /* Make sure we've got segment mappings. (FIXME: scan module headers) */
    if( rc == DS_OK && !ii->segments ) {
        ii->seg_count = 2;
        ii->segments = DCAlloc( sizeof( hllinfo_seg ) * ii->seg_count );
        if( ii->segments != NULL ) {
            memset( ii->segments, 0, sizeof( hllinfo_seg ) * ii->seg_count );
            ii->segments[0].is_executable = 1;
            ii->segments[0].map.segment = 1;
            ii->segments[1].map.segment = 2;
            ii->segments[0].size = ii->segments[1].size = 0x00400000; /* 4MB */
            ii->segments[0].address = ii->segments[1].address = 0;
        } else{
            rc = DS_ERR | DS_NO_MEM;
        }
    }

    /* Locate global types. If none, we've types per module. */
    if( rc == DS_OK ) {
        /* FIXME
        hll_debug_dir *cde;
        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] );
        }
        */
    }

    /* We're done - clean up on failure. */
    if( rc != DS_OK ) {
        DCStatus( rc );
        Cleanup( ii );
    }
    return( rc );
}