watlcl.c

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

C
979
字号
        break;
    }
    return( DS_OK );
}


static address DefnAddr( lcl_defn *defn, lclinfo *local )
{
    location_list       ll;

    if( DefnLocation( defn, NULL, &ll, local ) == DS_OK
        && ll.num == 1
        && ll.e[0].type == LT_ADDR ) {
        return( ll.e[0].u.addr );
    } else {
        return( NilAddr );
    }
}


search_result SearchLclMod( imp_image_handle *ii, imp_mod_handle im,
                lookup_item *li, void *d )
{
    lcl_defn            defn;
    int                 (*compare)();
    byte                *ptr;
    byte                *next;
    char                *name;
    unsigned            len;
    imp_sym_handle      *is;
    search_result       sr;
    lclinfo             lclld;
    lclinfo             *local = &lclld;


    if( li->scope.start != NULL ) return( SR_NONE );
    if( LoadLocalSyms( ii, im, &lclld ) != DS_OK ) return( SR_NONE );
    if( li->case_sensitive ) {
        compare = &memcmp;
    } else {
        compare = &memicmp;
    }
    name = li->name.start;
    len = li->name.len;
    sr = SR_NONE;
    ptr = local->start;
    for( ;; ) {
        ptr = ModAddrLkupVar( ptr, local );
        if( ptr == NULL ) break;
        next = ProcDefn( ptr, &defn, local );
        if( len == defn.i.namelen && compare( name, defn.i.name, len ) == 0 ) {
            is = DCSymCreate( ii, d );
            LclCreate( is, ptr, defn.i.name, local );
            sr = SR_EXACT;
        }
        ptr = next;
    }
    PopLoad( local );
    return( sr );
}


static search_result DoLclScope( imp_image_handle *ii, imp_mod_handle im,
                                address addr, lookup_item *li,
                                void *d, lclinfo *local )
{
    lcl_defn            blk;
    lcl_defn            defn;
    byte                *ptr;
    byte                *next;
    unsigned            parent;
    int                 (*compare)();
    char                *name;
    unsigned            len;
    search_result       sr;
    lookup_item         li_type;
    imp_type_handle     it;
    imp_sym_handle      *is;

    if( li->case_sensitive ) {
        compare = memcmp;
    } else {
        compare = memicmp;
    }
    name = li->name.start;
    len  = li->name.len;
    if( li->scope.start != NULL ) {
        li_type.name = li->scope;
        li_type.file_scope = li->file_scope;
        li_type.case_sensitive = li->case_sensitive;
        li_type.scope.start = NULL;
        li_type.type = ST_TYPE;
        sr = LookupTypeName( ii, im, &li_type, &it );
        if( sr == SR_NONE ) return( SR_NONE );
        return( SearchMbr( ii, &it, li, d ) );
    }
    ptr = local->start;
    for( ;; ) {
        ptr = FindBlockRout( ptr, local );
        if( ptr == NULL ) return( SR_NONE );
        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 ) ) {
            break;
        }
    }
    sr = SR_NONE;
    for( ;; ) {
        if( blk.i.class == (CODE_SYMBOL | CODE_MEMBER_SCOPE) ) {
            if( FindTypeHandle( ii, im, blk.i.type_index, &it ) == DS_OK ) {
                sr = SearchMbr( ii, &it, li, d );
            }
        } else {
            for( ;; ) {
                ptr = FindLclVar( ptr, local );
                if( ptr == NULL ) break;
                next = ProcDefn( ptr, &defn, local );
                if( len == defn.i.namelen
                  && compare( name, defn.i.name, len ) == 0 ) {
                    is = DCSymCreate( ii, d );
                    LclCreate( is, ptr, defn.i.name, local );
                    sr = SR_EXACT;
                }
                ptr = next;
            }
        }
        if( sr != SR_NONE ) break;
        parent = blk.b.parent_block;
        if( parent == 0 ) break;
        ptr = ProcDefn( local->start + parent, &blk, local );
    }
    return( sr );
}


search_result SearchLclScope( imp_image_handle *ii, imp_mod_handle im,
                                address *addr, lookup_item *li, void *d )
{
    search_result       sr;
    lclinfo             lclld;
    lclinfo             *local = &lclld;

    if( LoadLocalSyms( ii, im, &lclld ) != DS_OK ) return( SR_NONE );
    sr = DoLclScope( ii, im, *addr, li, d, local );
    PopLoad( local );
    return( sr );
}


search_result LookupLclAddr( imp_image_handle *ii, address addr,
                                imp_sym_handle *is )
{
    lcl_defn            defn;
    address             mod_addr;
    address             close_addr;
    byte                *ptr;
    byte                *next;
    search_result       sr;
    lclinfo             lclld;
    lclinfo             *local = &lclld;

    if( LoadLocalSyms( ii, is->im, &lclld ) != DS_OK ) return( SR_NONE );
    sr = SR_NONE;
    next = local->start;
    for( ;; ) {
        ptr = ModAddrLkupVar( next, local );
        if( ptr == NULL ) break;
        next = ProcDefn( ptr, &defn, local );
        mod_addr = DefnAddr( &defn, local );
        if( DCSameAddrSpace( addr, mod_addr ) == DS_OK ) {
            if( addr.mach.offset >= mod_addr.mach.offset ) {
                /* possible */
                if( sr == SR_NONE
                 || close_addr.mach.offset <= mod_addr.mach.offset ) {
                    LclCreate( is, ptr, defn.i.name, local );
                    close_addr = mod_addr;
                    if( addr.mach.offset == mod_addr.mach.offset ) {
                        sr = SR_EXACT;
                        break;
                    }
                    sr = SR_CLOSEST;
                }
            }
        }
    }
    PopLoad( local );
    return( sr );
}


unsigned SymHdl2LclName( imp_image_handle *ii, imp_sym_handle *is,
                                char *name, unsigned max )
{
    byte        *ptr;
    unsigned    len;
    lclinfo     lclld;
    lclinfo     *local = &lclld;

    if( LoadLocalSyms( ii, is->im, &lclld ) != DS_OK ) return( 0 );
    ptr = local->start + is->u.lcl.offset;
    len = *ptr - is->name_off;
    if( max > 0 ) {
        --max;
        if( max > len ) max = len;
        ptr += is->name_off;
        memcpy( name, ptr, max );
        name[max] = '\0';
    }
    PopLoad( local );
    return( len );
}

static void SetBase( imp_sym_handle *is, lclinfo *local )
{
    local->base_off = is->u.lcl.base;
    if( is->u.lcl.base != NO_BASE ) {
        NewBase( local->start + is->u.lcl.base, local );
    }
}

dip_status SymHdl2LclLoc( 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 );
    SetBase( is, local );
    ProcDefn( local->start + is->u.lcl.offset, &defn, local );
    ret = DefnLocation( &defn, lc, ll, local );
    PopLoad( local );
    return( ret );
}

dip_status SymHdl2LclType( imp_image_handle *ii, imp_sym_handle *is,
                        imp_type_handle *it )
{
    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 );
    ret = FindTypeHandle( ii, is->im, defn.i.type_index, it );
    PopLoad( local );
    return( ret );
}

void SetGblLink( imp_sym_handle *is, void *link )
{
    is->u.lcl.gbl_link = link;
}

dip_status Lcl2GblHdl( imp_image_handle *ii,
                        imp_sym_handle *lcl_is, imp_sym_handle *gbl_is )
{
    lcl_defn            defn;
    dip_status          ret;
    location_list       ll;
    lclinfo             lclld;
    lclinfo             *local = &lclld;

    if( lcl_is->u.lcl.gbl_link != NULL ) {
        return( Link2GblHdl( ii, lcl_is->u.lcl.gbl_link, gbl_is ) );
    }
    ret = LoadLocalSyms( ii, lcl_is->im, &lclld );
    if( ret != DS_OK ) return( ret );
    SetBase( lcl_is, local );
    ProcDefn( local->start + lcl_is->u.lcl.offset, &defn, local );
    ret = DefnLocation( &defn, NULL, &ll, local );
    if( ret != DS_OK ) goto done;
    ret = DS_FAIL;
    if( ll.num != 1 || ll.e[0].type != LT_ADDR ) goto done;
    gbl_is->im = lcl_is->im;
    if( LookupGblAddr( ii, ll.e[0].u.addr, gbl_is ) != SR_EXACT ) goto done;
    ret = DS_OK;
done:
    PopLoad( local );
    return( ret );
}

dip_status SymHdl2LclInfo( imp_image_handle *ii, imp_sym_handle *is,
                        sym_info *si )
{
    lcl_defn            defn;
    byte                *p;
    dip_status          ret;
    lclinfo             lclld;
    lclinfo             *local = &lclld;
    imp_sym_handle      gbl_is;

    ret = LoadLocalSyms( ii, is->im, &lclld );
    if( ret != DS_OK ) return( ret );
    if( Lcl2GblHdl( ii, is, &gbl_is ) == DS_OK ) {
        SymHdl2GblInfo( ii, &gbl_is, si ); /* get the global bit set */
    }
    SetBase( is, local );
    ProcDefn( local->start + is->u.lcl.offset, &defn, local );
    switch( defn.i.class & CLASS_MASK ) {
    case VAR_SYMBOL:
        si->kind = SK_DATA;
        break;
    case CODE_SYMBOL:
        si->kind = SK_PROCEDURE; /* never get handled a block */
        switch( defn.i.class & SUBCLASS_MASK ) {
        case CODE_FAR_ROUT:
        case CODE_FAR_ROUT386:
            si->rtn_far = 1;
            break;
        default:
            si->rtn_far = 0;
            break;
        }
        si->rtn_calloc = 0;
        si->ret_modifier = TM_NONE;
        si->ret_size = 0;
        switch( *defn.i.unparsed ) {
        case IND_REG+IR_RALLOC_NEAR:
            si->ret_modifier = TM_NEAR;
            break;

⌨️ 快捷键说明

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