watlcl.c

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

C
979
字号
        case IND_REG+IR_RALLOC_FAR:
            si->ret_modifier = TM_FAR;
            break;
        case IND_REG+IR_CALLOC_NEAR:
            si->rtn_calloc = 1;
            si->ret_modifier = TM_NEAR;
            break;
        case IND_REG+IR_CALLOC_FAR:
            si->rtn_calloc = 1;
            si->ret_modifier = TM_FAR;
            break;
        }
        switch( si->ret_modifier ) {
        case TM_FAR:
            si->ret_size = sizeof( addr_seg );
            /* fall through */
        case TM_NEAR:
            si->ret_size += RegSize( defn.i.unparsed[1] );
            break;
        }
        si->ret_addr_offset = defn.r.ret_addr_offset;
        p = SkipLocation( defn.i.unparsed );
        si->num_parms = *p;
        si->prolog_size = defn.r.pro_size;
        si->epilog_size = defn.r.epi_size;
        si->rtn_size = defn.b.size;
        break;
    }
    PopLoad( local );
    return( DS_OK );
}

dip_status SymHdl2LclParmLoc( imp_image_handle *ii, imp_sym_handle *is,
                location_context *lc, location_list *ll, unsigned parm )
{
    lcl_defn    defn;
    byte        *p;
    dip_status  ret;
    lclinfo     lclld;
    lclinfo     *local = &lclld;

    ret = LoadLocalSyms( ii, is->im, &lclld );
    if( ret != DS_OK ) return( ret );
    local->base_off = 0;
    ProcDefn( local->start + is->u.lcl.offset, &defn, local );
    if( parm == 0 ) { /* return value */
        ret = EvalLocation( ii, lc, defn.i.unparsed, ll );
        if( ret == (DS_ERR|DS_BAD_LOCATION) ) ret = DS_NO_PARM;
    } else {
        p = SkipLocation( defn.i.unparsed );
        if( parm > *p ) {
            ret = DS_NO_PARM;
        } else {
            ++p;
            for( ;; ) {
                --parm;
                if( parm == 0 ) break;
                p = SkipLocation( p );
            }
            ret = EvalLocation( ii, lc, p, ll );
        }
    }
    PopLoad( local );
    return( ret );
}

dip_status DIPENTRY DIPImpSymObjType( imp_image_handle *ii,
                imp_sym_handle *is, imp_type_handle *it, type_info *ti )
{
    lcl_defn    defn;
    dip_status  ret;
    lclinfo     lclld;
    lclinfo     *local = &lclld;

    ret = LoadLocalSyms( ii, is->im, &lclld );
    if( ret != DS_OK ) return( ret );
    local->base_off = 0;
    ProcDefn( local->start + is->u.lcl.offset, &defn, local );
    if( (defn.i.class & CLASS_MASK) != CODE_SYMBOL ) return( DS_FAIL );
    if( defn.b.parent_block == 0 ) return( DS_FAIL );
    ProcDefn( local->start + defn.b.parent_block, &defn, local );
    if( defn.i.class != (CODE_SYMBOL+CODE_MEMBER_SCOPE) ) return( DS_FAIL );
    if( ti != NULL ) {
        if( defn.i.unparsed == NULL ) {
            ti->kind = TK_NONE;
        } else {
            ti->kind = TK_POINTER;
            switch( *defn.i.unparsed ) {
            case 0:
               ti->size = sizeof( addr32_off );
               ti->modifier = TM_NEAR;
               break;
            case 1:
               ti->size = sizeof( addr32_ptr );
               ti->modifier = TM_FAR;
               break;
            case 6:
               ti->size = sizeof( addr48_off );
               ti->modifier = TM_NEAR;
               break;
            case 7:
               ti->size = sizeof( addr48_ptr );
               ti->modifier = TM_FAR;
               break;
            }
        }
    }
    PopLoad( local );
    return( FindTypeHandle( ii, is->im, defn.i.type_index, it ) );
}

dip_status DIPENTRY DIPImpSymObjLocation( imp_image_handle *ii,
        imp_sym_handle *is, location_context *lc, location_list *ll )
{
    lcl_defn    defn;
    dip_status  ret;
    lclinfo     lclld;
    lclinfo     *local = &lclld;

    ret = LoadLocalSyms( ii, is->im, &lclld );
    if( ret != DS_OK ) return( ret );
    local->base_off = 0;
    ProcDefn( local->start + is->u.lcl.offset, &defn, local );
    if( (defn.i.class & CLASS_MASK) != CODE_SYMBOL ) return( DS_FAIL );
    if( defn.b.parent_block == 0 ) return( DS_FAIL );
    ProcDefn( local->start + defn.b.parent_block, &defn, local );
    if( defn.i.class != (CODE_SYMBOL+CODE_MEMBER_SCOPE) ) return( DS_FAIL );
    if( defn.i.unparsed == NULL ) return( DS_FAIL );
    ret = EvalLocation( ii, lc, defn.i.unparsed + 1, ll );
    PopLoad( local );
    return( ret );
}

static byte *FindBlockScope( byte *ptr, lcl_defn *blk, address *addr, lclinfo *local )
{
    byte        *blk_ptr;

    for( ;; ) {
        ptr = FindBlockRout( ptr, local );
        if( ptr == NULL ) return( NULL );
        blk_ptr = ptr;
        ptr = ProcDefn( ptr, blk, local );
        if( DCSameAddrSpace( blk->b.start, *addr ) == DS_OK
            && (blk->b.start.mach.offset <= addr->mach.offset)
            && (blk->b.start.mach.offset + blk->b.size > addr->mach.offset ) ) {
            return( blk_ptr );
        }
    }
}

static walk_result WalkOneBlock( imp_image_handle *ii, byte *ptr, lcl_defn *blk,
                    IMP_SYM_WKR *wk, imp_sym_handle *is, void *d, lclinfo *local )
{
    imp_type_handle             it;
    byte                        *next;
    lcl_defn                    defn;
    walk_result                 wr;

    switch( blk->i.class ) {
    case CODE_SYMBOL | CODE_MEMBER_SCOPE:
        /* process member list */
        if( FindTypeHandle( ii, local->im, blk->i.type_index, &it ) == DS_OK ) {
            wr = WalkTypeSymList( ii, &it, wk, is, d );
            if( wr != WR_CONTINUE ) return( wr );
        }
        break;
    case CODE_SYMBOL | CODE_BLOCK:
    case CODE_SYMBOL | CODE_BLOCK386:
    case CODE_SYMBOL | CODE_NEAR_ROUT:
    case CODE_SYMBOL | CODE_NEAR_ROUT386:
    case CODE_SYMBOL | CODE_FAR_ROUT:
    case CODE_SYMBOL | CODE_FAR_ROUT386:
        /* process local scope */
        for( ;; ) {
            ptr = FindLclVar( ptr, local );
            if( ptr == NULL ) break;
            next = ProcDefn( ptr, &defn, local );
            LclCreate( is, ptr, defn.i.name, local );
            wr = wk( ii, SWI_SYMBOL, is, d );
            if( wr != WR_CONTINUE ) return( wr );
            ptr = next;
        }
        break;
    }
    return( WR_CONTINUE );
}

walk_result WalkScopedSymList( imp_image_handle *ii, address *addr, IMP_SYM_WKR *wk,
                        imp_sym_handle *is, void *d )
{
    imp_mod_handle      im;
    byte                *ptr;
    lcl_defn            blk;
    lclinfo             lclld;
    lclinfo             *local = &lclld;
    walk_result         wr;

    wr = WR_CONTINUE;
    if( ImpInterface.addr_mod( ii, *addr, &im ) != SR_NONE ) {
        if( LoadLocalSyms( ii, im, &lclld ) == DS_OK ) {
            ptr = FindBlockScope( local->start, &blk, addr, local );
            if( ptr != NULL ) {
                ptr += *ptr;
                for( ;; ) {
                    wr = WalkOneBlock( ii, ptr, &blk, wk, is, d, local );
                    if( wr != WR_CONTINUE ) break;
                    if( blk.b.parent_block == 0 ) break;
                    ptr = local->start + blk.b.parent_block;
                    ptr = ProcDefn( ptr, &blk, local );
                }
            }
            PopLoad( local );
        }
    }
    return( wr );
}

walk_result WalkBlockSymList( imp_image_handle *ii, scope_block *scope, IMP_SYM_WKR *wk,
                        imp_sym_handle *is, void *d )
{
    imp_mod_handle      im;
    lclinfo             lclld;
    lclinfo             *local = &lclld;
    unsigned_16         base;
    byte                *ptr;
    lcl_defn            blk;
    walk_result         wr;

    wr = WR_CONTINUE;
    if( ImpInterface.addr_mod( ii, scope->start, &im ) != SR_NONE ) {
        if( LoadLocalSyms( ii, im, &lclld ) == DS_OK ) {
            base = scope->unique >> 16;
            local->base_off = base;
            if( base != NO_BASE ) {
                NewBase( local->start + base, local );
            }
            ptr = local->start + (unsigned_16)scope->unique;
            ptr = ProcDefn( ptr, &blk, local );
            wr = WalkOneBlock( ii, ptr, &blk, wk, is, d, local );
            PopLoad( local );
        }
    }
    return( wr );
}

dip_status WalkLclModSymList( imp_image_handle *ii, imp_mod_handle im,
                        IMP_SYM_WKR *wk, imp_sym_handle *is, void *d,
                        walk_result *last )
{
    byte                *curr;
    byte                *next;
    lcl_defn            defn;
    lclinfo             lclld;
    lclinfo             *local = &lclld;
    dip_status          ret;

    *last = WR_CONTINUE;
    ret = LoadLocalSyms( ii, im, &lclld );
    if( ret != DS_OK ) return( ret );
    curr = local->start;
    for( ;; ) {
        curr = ModAddrLkupVar( curr, local );
        if( curr == NULL ) break;
        next = ProcDefn( curr, &defn, local );
        LclCreate( is, curr, defn.i.name, local );
        *last = wk( ii, SWI_SYMBOL, is, d );
        if( *last != WR_CONTINUE ) break;
        curr = next;
    }
    PopLoad( local );
    return( DS_OK );
}


search_result DIPENTRY DIPImpAddrScope( imp_image_handle *ii,
                        imp_mod_handle im, address addr, scope_block *scope )
{
    lcl_defn            blk;
    byte                *curr;
    lclinfo             lclld;
    lclinfo             *local = &lclld;

    if( LoadLocalSyms( ii, im, &lclld ) != DS_OK ) return( SR_NONE );
    curr = FindBlockScope( local->start, &blk, &addr, local );
    if( curr == NULL ) {
        PopLoad( local );
        return( SR_NONE );
    }
    scope->start = blk.b.start;
    scope->len = blk.b.size;
    scope->unique = (curr - local->start) + ((unsigned_32)local->base_off << 16);
    PopLoad( local );
    return( SR_CLOSEST );
}


search_result DIPENTRY DIPImpScopeOuter( imp_image_handle *ii,
                        imp_mod_handle im, scope_block *in, scope_block *out )
{
    lcl_defn            blk;
    byte                *curr;
    lclinfo             lclld;
    lclinfo             *local = &lclld;
    unsigned_16         base;

    if( LoadLocalSyms( ii, im, &lclld ) != DS_OK ) return( SR_NONE );
    base = in->unique >> 16;
    local->base_off = base;
    if( base != NO_BASE ) {
        NewBase( local->start + base, local );
    }
    curr = local->start + (unsigned_16)in->unique;
    ProcDefn( curr, &blk, local );
    if( blk.b.parent_block == 0 ) {
        return( SR_NONE );
    }
    curr = local->start + blk.b.parent_block;
    ProcDefn( curr, &blk, local );
    out->start = blk.b.start;
    out->len = blk.b.size;
    out->unique = (curr - local->start) + ((unsigned_32)local->base_off << 16);
    PopLoad( local );
    return( SR_CLOSEST );
}

⌨️ 快捷键说明

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