dfsym.c

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

C
1,799
字号
        }
    }
    if( ctl->root != NULL ) {
        node = FindScope( ctl->root, addr.mach.offset );
        if( node != NULL ) {
            scope->start = addr;
            scope->start.mach.offset = node->start;
            scope->len = node->end - node->start;
            DCMapAddr( &scope->start.mach, ii->dcmap );
            scope->unique = node->what;
            scope->unique -= ii->mod_map[imx].cu_tag;   /* make relative */
            ret = SR_CLOSEST;
        }
    }
    return( ret );
}


search_result   DIPENTRY DIPImpAddrScope( imp_image_handle *ii,
                imp_mod_handle im, address addr, scope_block *scope )
/*******************************************************************/
{
    /* Find the range of the lexical scope block enclosing 'addr' in
     * module 'im'. If there is no such scope, return SR_NONE. Otherwise
     * fill in scope->start with the address of the start of the lexical
     * block and scope->len with the size of the block. Fill in
     * scope->unique with something that uniquely identifies the lexical
     * block in question. This is used to disamibiguate between blocks
     * that start at the same address and have the same length. The value
     * should be chosen so that
     *         1. It remains valid and consistant across a DIPUnloadInfo
     *            and DIPLoadInfo of the same information.
     *         2. It remains the same whether the scope_block was obtained
     *            by DIPImpAddrScope or DIPImpScopeOuter.
     * Then return SR_EXACT/SR_CLOSEST as appropriate.
     */
    return( DFAddrScope( ii, IM2IMX( im ), addr, scope ) );
}


static search_result   DFScopeOuter( imp_image_handle *ii,
                im_idx imx, scope_block *in, scope_block *out )
/*************************************************************/
{
    /* Given the scope_block pointed to by 'in' in the module 'im', find
     * the parent lexical block of it and fill in the scope_block pointed
     * to by 'out' with the information. Return SR_EXACT/SR_CLOSEST as
     * appropriate. Return SR_NONE if there is no parent block.
     * Make sure that the case where 'in' and 'out' point to the same
     * address is handled.
     */
    dr_handle           what;
    search_result       ret;
    address             addr;
    scope_ctl           *ctl;
    scope_node          *node;

    ret = SR_NONE;
    addr =  in->start;
    Real2Map( ii->addr_map, &addr );
    ctl = &ii->scope;
    if( !IsInScope( ctl, addr ) ) {
        addrsym_info        info;
        seg_list            *addr_sym;

        addr_sym = DFLoadAddrSym( ii, imx );
        if( FindAddrSym( addr_sym, &addr.mach, &info ) >= 0 ) {
            DRSetDebug( ii->dwarf->handle );    /* must do at each interface */
            if( DRIsFunc( info.sym ) ) {
                FiniScope( ctl );
                ctl->base = addr;
                ctl->base.mach.offset = info.map_offset;
                ctl->base.mach.segment = info.map_seg;
                DRWalkScope( info.sym, InBlk, ctl );
            }
        }
    }
    if( ctl->root != NULL ) {
        ret = SR_NONE;
        node = FindScope( ctl->root, addr.mach.offset );
        what = in->unique;
        what += ii->mod_map[imx].cu_tag;    /* make absolute */
        while( node != NULL ) {
            if( node->what == what ) {
                node = node->down;
                break;
            }
            node = node->down;
        }
        if( node != NULL ) {
            out->start = addr;
            out->start.mach.offset = node->start;
            out->len = node->end - node->start;
            DCMapAddr( &out->start.mach, ii->dcmap );
            what = node->what;
            what -= ii->mod_map[imx].cu_tag;
            out->unique = what; /* make relative */
            ret = SR_EXACT;
        }
    }
    return( ret );
}


static dr_handle GetContainingClass( dr_handle curr )
/***************************************************/
{
    dr_tag_type     sc;

    curr = DRGetContaining( curr );
    if( curr != NULL ) {
        curr = DRSkipTypeChain( curr ); /* PCH typedef link */
        sc = DRGetTagType( curr );
        if( sc != DR_TAG_CLASS ) {
            curr = NULL;
        }
    }
    return( curr );
}


search_result   DIPENTRY DIPImpScopeOuter( imp_image_handle *ii,
                imp_mod_handle im, scope_block *in, scope_block *out )
/********************************************************************/
{
    search_result   ret;
    dr_handle       curr;
    dr_tag_type     sc;
    dr_handle       cu_tag;
    im_idx          imx;

    DRSetDebug( ii->dwarf->handle );    /* must do at each interface */
    imx = IM2IMX( im );
    cu_tag = ii->mod_map[imx].cu_tag;
    curr = in->unique + cu_tag;
    sc = DRGetTagType( curr );
    switch( sc ) {
    case DR_TAG_CLASS:
        DCStatus( DS_FAIL );
        ret = SR_NONE;
        break;
    case DR_TAG_FUNCTION:
        curr = GetContainingClass( curr );
        if( curr != NULL ) {
            *out = *in;
             out->unique = curr-cu_tag;
             ret = SR_EXACT;
         } else {
            DCStatus( DS_FAIL );
            ret = SR_NONE;
         }
         break;
    default:
        ret = DFScopeOuter( ii, imx, in, out );
    }
    return( ret );

}

/**********************************************/
/* Walk or Search various scopes for symbols  */
/**********************************************/

typedef struct {
    im_idx              imx;
    imp_image_handle    *ii;
    void                *d;
    dr_handle           containing;
    dr_srch             what;
    bool                cont;   //continue to next scope
    enum {
        WLK_LOOKUP,
        WLK_WLK,
    }                   kind;
} blk_wlk_com;

typedef struct {
    blk_wlk_com         com;
    walk_result         wr;
    IMP_SYM_WKR         *wk;
    imp_sym_handle      *is;
} blk_wlk_wlk;

typedef struct {
    blk_wlk_com         com;
    int                 (*comp)();
    lookup_item         *li;
    search_result       sr;
    char                *buff;
    unsigned            len;
} blk_wlk_lookup;

typedef union {
    blk_wlk_com         com;
    blk_wlk_wlk         wlk;
    blk_wlk_lookup      lookup;
} blk_wlk;

typedef int (*BLKLF)( dr_handle var, int index, void *df );

static dr_srch Dip2DwarfSrch( symbol_type dip )
/*********************************************/
{
    dr_srch     ret;

    switch( dip ) {
    case ST_NONE:
    case ST_OPERATOR:
    case ST_DESTRUCTOR:
        ret = DR_SRCH_func_var;
        break;
    case ST_TYPE:
        ret = DR_SRCH_ctypes;
        break;
    case ST_STRUCT_TAG:
    case ST_CLASS_TAG:
    case ST_UNION_TAG:
        ret = DR_SRCH_class;
        break;
    case ST_ENUM_TAG:
        ret = DR_SRCH_enum;
        break;
    }
    return( ret );
}


static int ASym( dr_handle var, int index, void *_df )
/****************************************************/
{
    blk_wlk_wlk     *df = _df;
    int             cont;
    imp_sym_handle  *is;
    dr_dbg_handle   saved;

    index = index;
    is = df->is;
    is->sclass = SYM_VAR;
    is->imx = df->com.imx;
    is->sym = var;
    is->state = DF_NOT;
    saved = DRGetDebug();
    df->wr = df->wk( df->com.ii, SWI_SYMBOL, is, df->com.d );
    DRSetDebug( saved );
    cont = TRUE;
    if( df->wr != WR_CONTINUE ) {
        cont = FALSE;
    }
    df->com.cont = cont;
    return( cont );
}


static int ASymCont( dr_handle var, int index, void *_df )
/********************************************************/
{
    blk_wlk_wlk     *df = _df;
    dr_handle       contain;
    int             cont;

    cont = TRUE;
    contain = DRGetContaining( var );
    if( contain != NULL ) {
        contain = DRSkipTypeChain( contain );   /* PCH typedef link */
    }
    if( df->com.containing == contain ) {
        cont = ASym( var, index, df );
    }
    return( cont );
}


static int AModSym( dr_handle var, int index, void *_df )
/*******************************************************/
{
    blk_wlk_wlk     *df = _df;
    int             cont;
    imp_sym_handle  *is;
    dr_tag_type     sc;
    dr_dbg_handle   saved;

    index = index;
    sc = DRGetTagType( var );
    if( sc == DR_TAG_NAMESPACE ) {
        DRWalkBlock( var, df->com.what, AModSym, df );
        cont = TRUE;
    } else {
        is = df->is;
        is->sclass = SYM_VAR;
        is->imx = df->com.imx;
        is->sym = var;
        is->state = DF_NOT;
        saved = DRGetDebug();
        df->wr = df->wk( df->com.ii, SWI_SYMBOL, is, df->com.d );
        DRSetDebug( saved );
        cont = TRUE;
    }
    if( df->wr != WR_CONTINUE ) {
        cont = FALSE;
    }
    df->com.cont = cont;
    return( cont );
}


static int ASymLookup( dr_handle var, int index, void *_df )
/**********************************************************/
{
    blk_wlk_lookup  *df = _df;
    imp_sym_handle  *is;
    int             len;

    len = DRGetNameBuff( var, df->buff, df->len );
    if( len == df->len
      && df->comp( df->buff, df->li->name.start, df->li->name.len ) == 0 ) {
        /* Found symbol by name */
        if( !DRIsFunc( var ) && !DRIsStatic( var ) && !DRIsSymDefined( var ) ) {
            /* If symbol is a global variable declaration, ignore it; it
             * won't have location information and will likely be found in
             * another module.
             */
        } else {
            is = DCSymCreate( df->com.ii, df->com.d );
            is->sclass = SYM_VAR;
            is->imx = df->com.imx;
            is->sym = var;
            is->state = DF_NOT;
            df->sr = SR_EXACT;
            df->com.cont = FALSE;
        }
    }
    return( TRUE );
}


static int ASymContLookup( dr_handle var, int index, void *_df )
/**************************************************************/
{
    blk_wlk_lookup  *df = _df;
    dr_handle       contain;
    int             cont;

    cont = TRUE;
    contain = DRGetContaining( var );
    if( contain != NULL ) {
        contain = DRSkipTypeChain( contain );   /* PCH typedef link */
    }
    if( df->com.containing == contain ) {
        cont = ASymLookup( var, index, df );
    }
    return( cont );
}


static int WalkOneBlock( blk_wlk *df, BLKLF fn, dr_handle blk )
/*************************************************************/
{
    DRSetDebug( df->com.ii->dwarf->handle );    /* must do at each call into DWARF */
    DRWalkBlock( blk, df->com.what, fn, df );
    return( df->com.cont );
}


static int WalkModSymList( blk_wlk *df, BLKLF fn, im_idx imx )
/************************************************************/
{
    imp_image_handle    *ii;
    dr_handle           cu_tag;
    int                 cont;

    df->com.imx = imx;
    ii = df->com.ii;
    cu_tag = ii->mod_map[imx].cu_tag;
    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, cu_tag );
    return( cont );
}


static int WalkScopedSymList( blk_wlk *df, BLKLF fn, address *addr )
/******************************************************************/
{
    /* Walk inner to outer function scopes, then containing class
     * if present, then module scope.
     */
    imp_image_handle    *ii;
    scope_block         scope;
    dr_handle           cu_tag;
    dr_tag_type         sc;
    im_idx              imx;
    dr_handle           curr;
    int                 cont;

    ii = df->com.ii;
    cont = TRUE;
    if( DFAddrMod( ii, *addr, &imx ) != SR_NONE ) {
        if( DFAddrScope( ii, imx, *addr, &scope ) != SR_NONE ) {
            df->com.imx = imx;
            cu_tag = ii->mod_map[imx].cu_tag;
            for( ;; ) {
                curr = scope.unique + cu_tag;
                cont = WalkOneBlock( df, fn, curr );
                if( !cont ) break;
                if( DFScopeOuter( ii, imx, &scope, &scope ) == SR_NONE ) {
                    cont = TRUE;
                    break;
                }
            }
            if( cont ) {
                sc = DRGetTagType( curr );
                if( sc == DR_TAG_FUNCTION ) {
                    imp_type_handle     it;

                    curr = GetContainingClass( curr );
                    if( curr != NULL ) {
                        it.state = DF_NOT;
                        it.type = curr;
                        it.imx =  imx;
                        if( df->com.kind == WLK_WLK ) {
                            df->wlk.wr = WalkTypeSymList( ii, &it,
                                 df->wlk.wk, df->wlk.is, df->com.d );
                            if( df->wlk.wr != WR_CONTINUE ) {
                                cont = FALSE;
                            }
                        } else {
                            df->lookup.sr = SearchMbr( ii, &it,
                                          df->lookup.li, df->com.d );
                            if( df->lookup.sr == SR_EXACT ) {
                                cont = FALSE;
                            }
                        }
                    }
                }
            }
        }
        if( cont ) {
            cont = WalkModSymList( df, fn, imx );
        }
        if( cont && ii->mod_map[imx].dbg_pch != NULL ) {
            imx = CuTag2ModIdx( ii, ii->mod_map[imx].dbg_pch );
            cont = WalkModSymList( df, fn, imx );
        }
    }
    return( cont );
}


⌨️ 快捷键说明

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