dfsym.c

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

C
1,799
字号
static int WalkBlockSymList( blk_wlk  *df, BLKLF fn, scope_block *scope )
/***********************************************************************/
{
    imp_image_handle    *ii;
    dr_handle           cu_tag;
    im_idx              imx;
    dr_handle           blk;
    dr_tag_type         sc;
    int                 cont;

    ii = df->com.ii;
    if( DFAddrMod( ii, scope->start, &imx ) != SR_NONE ) {
        DRSetDebug( df->com.ii->dwarf->handle );    /* must do at each call into DWARF */
        df->com.imx = imx;
        cu_tag = ii->mod_map[imx].cu_tag;
        blk = scope->unique + cu_tag;
        sc = DRGetTagType( blk );
        if( sc == DR_TAG_CLASS ) {
            imp_type_handle     it;

            it.state = DF_NOT;
            it.type  = blk;
            it.imx   = imx;
            if( df->com.kind == WLK_WLK ) {
                df->wlk.wr = WalkTypeSymList( ii, &it, df->wlk.wk,
                               df->wlk.is, df->com.d );
            } else {
                 df->lookup.sr = SearchMbr( ii, &it,
                                    df->lookup.li, df->com.d );
            }
        } else {
            cont = WalkOneBlock( df, fn, blk );
        }
    } else {
        cont = TRUE;
    }
    return( cont );
}


static int WalkSymSymList( blk_wlk *df, BLKLF fn, imp_sym_handle *is )
/********************************************************************/
{
    imp_image_handle    *ii;
    im_idx              imx;
    int                 cont;

    imx = is->imx;
    ii  = df->com.ii;
    df->com.imx = imx;
    if( df->com.what == DR_SRCH_ctypes
      && ii->mod_map[imx].lang == DR_LANG_CPLUSPLUS ) {
        df->com.what = DR_SRCH_cpptypes;
    }
    cont = WalkOneBlock( df, fn, is->sym );
    return( cont );
}


static walk_result  WalkMyLDSyms( imp_image_handle *ii, im_idx imx, void *_df )
/*****************************************************************************/
{
    blk_wlk     *df = _df;

    df->wlk.com.imx = imx;
    WalkModSymList( df, &ASym, imx );
    return( df->wlk.wr );
}


static walk_result DFWalkSymList( imp_image_handle *ii,
                         symbol_source     ss,
                         void             *source,
                         IMP_SYM_WKR      *wk,
                         imp_sym_handle   *is,
                         void             *d )
/******************************************************/
{
    imp_mod_handle      im;
    walk_result         wr;
    blk_wlk             df;
    int                 cont;

    df.com.ii = ii;
    df.com.d = d;
    df.com.what = DR_SRCH_func_var;
    df.com.containing = 0;
    df.com.cont = TRUE;
    df.com.kind = WLK_WLK;
    df.wlk.wk = wk;
    df.wlk.is = is;
    df.wlk.wr = WR_CONTINUE;
    switch( ss ) {
    case SS_TYPE: /* special case */
        wr = WalkTypeSymList( ii, (imp_type_handle *)source, wk, is, d );
        break;
    case SS_SCOPED:
        cont = WalkScopedSymList( &df, &ASym, (address *)source );
        wr = df.wlk.wr;
        break;
    case SS_SCOPESYM:
        is = (imp_sym_handle *)source;
        WalkSymSymList( &df, &ASym, is );
        if( cont ) {
            df.com.containing = is->sym;
            WalkModSymList( &df, &ASymCont, is->imx );
        }
        wr = df.wlk.wr;
        break;
    case SS_BLOCK:
        WalkBlockSymList( &df, &ASym, (scope_block *)source );
        wr = df.wlk.wr;
        break;
    case SS_MODULE:
        im = *(imp_mod_handle *)source;
        if( im == (imp_mod_handle)NO_MOD ) {
            wr = DFWalkModList( ii, WalkMyLDSyms, &df );
        } else {
           WalkModSymList( &df, &AModSym, IM2IMX( im ) );
           wr = df.wlk.wr;
        }
        break;
    }
    return( wr );
}


walk_result DIPENTRY DIPImpWalkSymList( imp_image_handle *ii,
                                        symbol_source     ss,
                                        void             *source,
                                        IMP_SYM_WKR      *wk,
                                        imp_sym_handle   *is,
                                        void              *d )
/***************************************************************/
{
    return( DFWalkSymList( ii, ss, source, wk, is, d ) );
}


walk_result DIPENTRY DIPImpWalkSymListEx( imp_image_handle *ii,
                                          symbol_source     ss,
                                          void             *source,
                                          IMP_SYM_WKR      *wk,
                                          imp_sym_handle   *is,
                                          location_context *lc,
                                           void             *d )
/*****************************************************************/
{
    lc = lc;
    return( DFWalkSymList( ii, ss, source, wk, is, d ) );
}


#define SH_ESCAPE       '\xf0'
static void CollectSymHdl( byte *ep, imp_sym_handle *is )
/*******************************************************/
{
    byte        *sp;
    byte        curr;
    static byte escapes[] = { SH_ESCAPE, '\0', '`' };

    ++ep;
    sp = (byte *)is;
    ++is;
    while( sp < (byte *)is ) {
        curr = *ep++;
        if( curr == SH_ESCAPE ) curr = escapes[ *ep++ - 1 ];
        *sp++ = curr;
    }
}


typedef struct {
    imp_image_handle    *ii;
    void                *d;
    int                 (*compare)(char const *, char const *);
    char                *name;
    dr_handle           sym;
} hash_look_data;

static int AHashItem( void *_find, dr_handle sym, char *name )
/************************************************************/
{
    hash_look_data  *find = _find;
    imp_sym_handle  *is;

    if( find->compare( name, find->name ) == 0 ) {
        find->sym = sym;
        is = DCSymCreate( find->ii, find->d );
        is->imx = DwarfModIdx( find->ii, sym );
        is->sclass = SYM_VAR;
        is->sym = sym;
        is->state = DF_NOT;
    }
    return( TRUE );
}

typedef struct {
    char    *p;
    int     len;
} strv;

static int StrVCopy( strv *dst, strv *src )
/*****************************************/
{
    /* Copy source until null char or source runs out
     * to dest until it runs out, return total length of source
     */
    int     total;

    total = src->len;
    for( ;; ) {
        if( src->len == 0 ) break;
        if( *src->p == '\0' ) break;
        if( dst->len > 0 ) {
            *dst->p = *src->p;
            ++dst->p;
            --dst->len;
        }
        ++src->p;
        --src->len;
    }
    total -= src->len;
    return( total );
}


static int QualifiedName( char *buff, lookup_item  *li, int max )
/***************************************************************/
{
    int     total;
    strv    curr;
    strv    dst;
    strv    tmp;

    curr.p   = li->scope.start;
    curr.len = li->scope.len;
    dst.p   = buff;
    dst.len = max;
    total = 0;
    while( curr.len > 0 ) {
        total += StrVCopy( &dst, &curr );
        if( *curr.p == '\0' ) {
            ++curr.p;
            --curr.len;
        }
        tmp.p = "::";
        tmp.len = 2;
        total += StrVCopy( &dst, &tmp );
    }
    curr.p = li->name.start;
    curr.len = li->name.len;
    total += StrVCopy( &dst, &curr );
    if( dst.len > 0 ) {
        *dst.p = '\0';
    }
    total += 1;
    return( total );
}


static search_result HashSearchGbl( imp_image_handle *ii,
                                    lookup_item      *li, void *d )
/*****************************************************************/
{
    char                buff[256];
    int                 len;
    search_result       sr;
    hash_look_data      data;
    name_wlk            wlk;

    sr = SR_NONE;
    data.ii  = ii;
    data.compare = li->case_sensitive ? &strcmp : &stricmp;
    data.sym  = NULL;
    len = QualifiedName(  buff, li, sizeof( buff ) );
    if( len <= sizeof( buff ) ) {
        data.name = buff;
    } else {
        data.name = DCAlloc( len + 1 );
        len = QualifiedName(  data.name, li, len + 1 );
    }
    data.d  = d;
    wlk.fn = AHashItem;
    wlk.name = data.name;
    wlk.d = &data;
    DRSetDebug( ii->dwarf->handle );    /* must do at each call into DWARF */
    FindHashWalk( ii->name_map, &wlk );
    if( data.sym != NULL ) {
        sr = SR_EXACT;
    }
    if( data.name != buff ) {
        DCFree( data.name );
    }
    return( sr );
}


extern search_result   DoLookupSym( imp_image_handle *ii,
                symbol_source ss, void *source, lookup_item *li,
                location_context *lc, void *d )
/**************************************************************/
{
    imp_mod_handle      im;
    imp_sym_handle      *is;
    search_result       sr;
    char                *src;
    unsigned            len;
    blk_wlk             df;
    char                buff[256];
    int                 cont;

    if( *li->name.start == SH_ESCAPE ) {
        CollectSymHdl( li->name.start, DCSymCreate( ii, d ) );
        return( SR_EXACT );
    }
    if( li->type == ST_OPERATOR ) {
//TODO this operator
        src = li->name.start;
        len = li->name.len;
        return( SR_NONE );
    }
    if( ss ==  SS_TYPE ) {
        if( li->mod != NO_MOD ) {
            sr =  SR_NONE;
        } else {
            sr = SearchMbr( ii, (imp_type_handle *)source, li, d  );
        }
        return( sr );
    }
    df.com.ii = ii;
    df.com.d = d;
    df.com.what = Dip2DwarfSrch( li->type );
    df.com.containing = 0;
    df.com.cont = TRUE;
    df.com.kind = WLK_LOOKUP;
    df.lookup.comp = li->case_sensitive ? &memcmp : &memicmp;
    df.lookup.li = li;
    df.lookup.len =  li->name.len+1;
    if( df.lookup.len <= sizeof( buff ) ) {
        df.lookup.buff = buff;
    } else {
        df.lookup.buff = DCAlloc( df.lookup.len );
    }
    df.lookup.sr = SR_NONE;
    switch( ss ) {
    case SS_SCOPED:
        if( li->scope.len == 0 ) {
            cont = WalkScopedSymList( &df, &ASymLookup, (address *)source );
        } else {
            cont = TRUE;
        }
        sr = df.lookup.sr;
        if( cont ) {
            if( DR_SRCH_func_var == df.com.what ) {
                sr = HashSearchGbl( ii, li, d );
           }
        }
        break;
    case SS_MODULE:
        im = *(imp_mod_handle *)source;
        if( im == (imp_mod_handle)NO_MOD ) {
            if( DR_SRCH_func_var == df.com.what ) {
                sr = HashSearchGbl( ii, li, d );
            }
        } else {
           WalkModSymList( &df, &ASymLookup, IM2IMX( im ) );
           sr = df.lookup.sr;
        }
        break;
    case SS_SCOPESYM:
        is = (imp_sym_handle *)source;
        WalkSymSymList( &df, &ASymLookup, is );
        df.com.containing = is->sym;    //check for out of line defn
        WalkModSymList( &df, &ASymContLookup, is->imx );
        sr = df.lookup.sr;
        break;
    }
    if( df.lookup.buff != buff ) {
        DCFree( df.lookup.buff );
    }
    return( sr );
}


extern search_result   DIPENTRY DIPImpLookupSym( imp_image_handle *ii,
                symbol_source ss, void *source, lookup_item *li, void *d )
/************************************************************************/
{
    return( DoLookupSym( ii, ss, source, li, NULL, d ) );
}


extern search_result   DIPENTRY DIPImpLookupSymEx( imp_image_handle *ii,
                symbol_source ss, void *source, lookup_item *li,
                location_context *lc, void *d )
/**********************************************************************/
{
    return( DoLookupSym( ii, ss, source, li, lc, d ) );
}


int DIPENTRY DIPImpSymCmp( imp_image_handle *ii, imp_sym_handle *is1,
                                imp_sym_handle *is2 )
/*******************************************************************/
{
    /* Compare two sym handles and return 0 if they refer to the same
     * information. If they refer to differnt things return either a
     * positive or negative value to impose an 'order' on the information.
     * The value should obey the following constraints.
     * Given three handles H1, H2, H3:
     *         - if H1 < H2 then H1 is always < H2
     *         - if H1 < H2 and H2 < H3 then H1 is < H3
     * The reason for the constraints is so that a client can sort a
     * list of handles and binary search them.
     */
    long    diff;

    ii = ii;
    diff = is1->sym - is2->sym;
    return( diff );
}


dip_status DIPENTRY DIPImpSymAddRef( imp_image_handle *ii, imp_sym_handle *is )
/*****************************************************************************/
{
    ii = ii;
    is = is;
    return( DS_OK );
}


dip_status DIPENTRY DIPImpSymRelease( imp_image_handle *ii, imp_sym_handle *is )
/******************************************************************************/
{
    ii = ii;
    is = is;
    return( DS_OK );
}


dip_status DIPENTRY DIPImpSymFreeAll( imp_image_handle *ii )
/**********************************************************/
{
    ii = ii;
    return( DS_OK );
}

⌨️ 快捷键说明

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