hllsym.c

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

C
1,855
字号
static unsigned ImpSymName( imp_image_handle *ii,
                        imp_sym_handle *is, location_context *lc,
                        symbol_name sn, char *buff, unsigned max )
{
    char                *name;
    unsigned            len;
    location_list       ll;
    dip_status          ds;
    imp_sym_handle      global;
    addr_off            dummy_off;
    search_result       sr;

    switch( sn ) {
    case SN_EXPRESSION:
        return( 0 );
    case SN_OBJECT:
    case SN_DEMANGLED:
        ds = ImpSymLocation( ii, is, lc, &ll );
        if( ds != DS_OK ) break;
        if( ll.num != 1 ) break;
        if( ll.e[0].type != LT_ADDR ) break;
        dummy_off = 0;
        sr = TableSearchForAddr( ii, ll.e[0].u.addr, &global,
                            &dummy_off, sstGlobalPub );
        if( sr != SR_EXACT ) break;
        if( SymGetName( ii, &global, &name, &len, NULL ) != DS_OK ) break;
        if( sn == SN_OBJECT ) {
            return( NameCopy( buff, name, max, len ) );
        }
        if( !__is_mangled( name, len ) ) return( 0 );
        return( __demangle_l( name, len, buff, max ) );
    }
    if( sn == SN_DEMANGLED ) return( 0 );
    /* SN_SOURCE: */
    if( SymGetName( ii, is, &name, &len, NULL ) != DS_OK ) return( 0 );
    return( NameCopy( buff, name, max, len ) );
}

unsigned        DIPENTRY DIPImpSymName( imp_image_handle *ii,
                        imp_sym_handle *is, location_context *lc,
                        symbol_name sn, char *buff, unsigned max )
{
    return( ImpSymName( ii, is, lc, sn, buff, max ) );
}

dip_status ImpSymType( imp_image_handle *ii, imp_sym_handle *is, imp_type_handle *it )
{
    s_all       *p;

    if( is->containing_type != 0 ) {
        return( TypeSymGetType( ii, is, it ) );
    }
    p = VMBlock( ii, is->handle, is->len );
    if( p == NULL ) return( DS_FAIL );
    return( TypeIndexFillIn( ii, SymTypeIdx( ii, p ), it ) );
}

dip_status      DIPENTRY DIPImpSymType( imp_image_handle *ii,
                imp_sym_handle *is, imp_type_handle *it )
{
    return( ImpSymType( ii, is, it ) );
}

dip_status      DIPENTRY DIPImpSymLocation( imp_image_handle *ii,
                imp_sym_handle *is, location_context *lc, location_list *ll )
{
    return( ImpSymLocation( ii, is, lc, ll ) );
}

dip_status      ImpSymValue( imp_image_handle *ii,
                imp_sym_handle *is, location_context *lc, void *buff )
{
    s_all               *p;
    numeric_leaf        val;
    dip_status          ds;
    imp_type_handle     it;
    type_info           ti;

    if( is->containing_type != 0 ) {
        return( TypeSymGetValue( ii, is, lc, buff ) );
    }
    p = VMBlock( ii, is->handle, is->len );
    if( p == NULL ) return( DS_FAIL );
    switch( p->common.code ) {
    case S_CONSTANT:
        GetNumLeaf( (unsigned_8 *)p + sizeof( s_constant ), &val );
        memcpy( buff, val.valp, val.size );
        ds = TypeIndexFillIn( ii, SymTypeIdx( ii, p ), &it );
        if( ds != DS_OK ) return( ds );
        ds = ImpTypeInfo( ii, &it, lc, &ti );
        if( ds != DS_OK ) return( ds );
        memset( (unsigned_8 *)buff + val.size, 0, ti.size - val.size );
        return( DS_OK );
    }
    return( DS_FAIL );
}

dip_status      DIPENTRY DIPImpSymValue( imp_image_handle *ii,
                imp_sym_handle *is, location_context *lc, void *buff )
{
    return( ImpSymValue( ii, is, lc, buff ) );
}

dip_status      DIPENTRY DIPImpSymInfo( imp_image_handle *ii,
                imp_sym_handle *is, location_context *lc, sym_info *si )
{
    s_all       *p;

    memset( si, 0, sizeof( *si ) );

    if( is->containing_type != 0 ) {
        return( TypeSymGetInfo( ii, is, lc, si ) );
    }
    p = VMBlock( ii, is->handle, is->len );
    if( p == NULL ) return( DS_FAIL );
    switch( p->common.code ) {
    case S_PUB16:
        if( SegIsExecutable( ii, p->pub16.f.segment ) == DS_OK ) {
            si->kind = SK_CODE;
        } else {
            si->kind = SK_DATA;
        }
        si->global = 1;
        break;
    case S_PUB32:
        if( SegIsExecutable( ii, p->pub32.f.segment ) == DS_OK ) {
            si->kind = SK_CODE;
        } else {
            si->kind = SK_DATA;
        }
        si->global = 1;
        break;
    case S_GDATA16:
    case S_GDATA32:
    case S_GTHREAD32:
        si->global = 1;
        /* fall through */
    case S_REGISTER:
    case S_MANYREG:
    case S_BPREL16:
    case S_LDATA16:
    case S_REGREL16:
    case S_LDATA32:
    case S_BPREL32:
    case S_REGREL32:
    case S_LTHREAD32:
        si->kind = SK_DATA;
        break;
    case S_CONSTANT:
        si->kind = SK_CONST;
        break;
    case S_UDT:
    case S_COBOLUDT:
        si->kind = SK_TYPE;
        break;
    case S_GPROC16:
        si->global = 1;
        /* fall through */
    case S_LPROC16:
        si->kind = SK_PROCEDURE;
        si->rtn_far = p->lproc16.f.flags.f.far_ret;
        si->ret_addr_offset = sizeof( unsigned_16 );
        si->prolog_size = p->lproc16.f.debug_start;
        si->epilog_size = p->lproc16.f.proc_length - p->lproc16.f.debug_end;
        si->rtn_size = p->lproc16.f.proc_length;
        //NYI: fill in si->rtn_calloc
        //NYI: fill in si->rtn_modifier
        //NYI: fill in si->ret_size
        //NYI: fill in si->num_parms
        break;
    case S_GPROC32:
        si->global = 1;
        /* fall through */
    case S_LPROC32:
        si->kind = SK_PROCEDURE;
        si->rtn_far = p->lproc32.f.flags.f.far_ret;
        if( ii->mad == MAD_AXP ) {
            si->ret_addr_offset = 0;
        } else {
            si->ret_addr_offset = sizeof( unsigned_32 );
        }
        si->prolog_size = p->lproc32.f.debug_start;
        si->epilog_size = p->lproc32.f.proc_length - p->lproc32.f.debug_end;
        si->rtn_size = p->lproc32.f.proc_length;
        //NYI: fill in si->rtn_calloc
        //NYI: fill in si->rtn_modifier
        //NYI: fill in si->ret_size
        //NYI: fill in si->num_parms
        break;
    case S_LABEL16:
    case S_LABEL32:
        si->kind = SK_CODE;
        break;
    default:
        Confused();
        return( DS_FAIL );
    }
    return( DS_OK );
}

static const unsigned_8 DXAXList[]      = { CV_X86_DX, CV_X86_AX };
static const unsigned_8 DXEAXList[]     = { CV_X86_DX, CV_X86_EAX };
static const unsigned_8 ST1ST0List[]    = { CV_X86_ST1, CV_X86_ST0 };

dip_status      DIPENTRY DIPImpSymParmLocation( imp_image_handle *ii,
                    imp_sym_handle *is, location_context *lc,
                    location_list *ll, unsigned n )
{
    s_all               *p;
    unsigned            type;
    int                 is32;
    unsigned            parm_count;
    cv_calls            call;
    dip_status          ds;
    unsigned_8          *reg_list;
    imp_type_handle     it;
    type_info           ti;

    p = VMBlock( ii, is->handle, is->len );
    switch( p->common.code ) {
    case S_LPROC16:
    case S_GPROC16:
        is32 = 0;
        type = p->lproc16.f.proctype;
        break;
    case S_LPROC32:
    case S_GPROC32:
        is32 = 1;
        type = p->lproc32.f.proctype;
        break;
    default:
        return( DS_ERR|DS_FAIL );
    }
    ds = TypeCallInfo( ii, type, &call, &parm_count );
    if( ds != DS_OK ) return( ds );
    if( n > parm_count ) return( DS_NO_PARM );
    if( n == 0 ) {
        /* return value */
        p = VMRecord( ii, is->handle + is->len );
        if( p == NULL ) return( DS_ERR|DS_FAIL );
        /* WARNING: assuming that S_RETURN directly follows func defn */
        if( p->common.code == S_RETURN ) {
            switch( p->return_.f.style ) {
            case CVRET_VOID:
                return( DS_NO_PARM );
            case CVRET_DIRECT:
                reg_list = (unsigned_8 *)(&p->return_ + 1);
                return( LocationManyReg( ii, reg_list[0], &reg_list[1], lc, ll ) );
            case CVRET_CALLOC_NEAR:
            case CVRET_CALLOC_FAR:
            case CVRET_RALLOC_NEAR:
            case CVRET_RALLOC_FAR:
                //NYI: have to handle these suckers
                NYI();
                break;
            }
            return( DS_ERR|DS_BAD_LOCATION );
        }
        /* find out about return type */
        ds = TypeIndexFillIn( ii, type, &it );
        if( ds != DS_OK ) return( ds );
        ds = ImpTypeBase( ii, &it, &it );
        if( ds != DS_OK ) return( ds );
        ds = ImpTypeInfo( ii, &it, lc, &ti );
        if( ds != DS_OK ) return( ds );
        switch( ti.kind ) {
        case TK_VOID:
            return( DS_BAD_LOCATION );
        case TK_BOOL:
        case TK_ENUM:
        case TK_CHAR:
        case TK_INTEGER:
        case TK_POINTER:
            switch( ii->mad ) {
            case MAD_X86:
                switch( ti.size ) {
                case 1:
                    return( LocationOneReg( ii, CV_X86_AL, lc, ll ) );
                case 2:
                    return( LocationOneReg( ii, CV_X86_AX, lc, ll ) );
                case 4:
                    if( is32 ) {
                        return( LocationOneReg( ii, CV_X86_EAX, lc, ll ) );
                    } else {
                        return( LocationManyReg( ii, sizeof( DXAXList ), DXAXList, lc, ll ) );
                    }
                case 6:
                    return( LocationManyReg( ii, sizeof( DXEAXList ), DXEAXList, lc, ll ) );
                }
                break;
            case MAD_AXP:
                 return( LocationOneReg( ii, CV_AXP_r0, lc, ll ) );
            }
            return( DS_ERR|DS_FAIL );
        case TK_REAL:
            switch( ii->mad ) {
            case MAD_X86:
                return( LocationOneReg( ii, CV_X86_ST0, lc, ll ) );
            case MAD_AXP:
                return( LocationOneReg( ii, CV_AXP_f0, lc, ll ) );
            }
            return( DS_ERR|DS_FAIL );
        case TK_COMPLEX:
            switch( ii->mad ) {
            case MAD_X86:
                return( LocationManyReg( ii, sizeof( ST1ST0List ), ST1ST0List, lc, ll ) );
            }
            return( DS_ERR|DS_FAIL );
        case TK_STRUCT:
        case TK_ARRAY:
            //NYI: have to handle these suckers
            NYI();
            break;
        }
        return( DS_ERR|DS_FAIL );
    }
    switch( call ) {
    case CV_NEARC:
    case CV_FARC:
        /* all on stack */
        return( DS_NO_PARM );
    case CV_NEARPASCAL:
    case CV_FARPASCAL:
    case CV_NEARFASTCALL:
    case CV_FARFASTCALL:
    case CV_NEARSTDCALL:
    case CV_FARSTDCALL:
    case CV_NEARSYSCALL:
    case CV_FARSYSCALL:
    case CV_THISCALL:
    case CV_MIPS:
    case CV_AXP:
    case CV_GENERIC:
        //NYI: have to handle all of these suckers
        NYI();
        break;
    }
    return( DS_ERR|DS_NO_PARM );
}

dip_status      DIPENTRY DIPImpSymObjType( imp_image_handle *ii,
                    imp_sym_handle *is, imp_type_handle *it, type_info *ti )
{
    dip_status          ds;
    imp_type_handle     func_it;
    imp_type_handle     this_it;

    ds = ImpSymType( ii, is, &func_it );
    if( ds != DS_OK ) return( ds );
    ds = TypeMemberFuncInfo( ii, &func_it, it, &this_it, NULL );
    if( ds != DS_OK ) return( ds );
    if( ti != NULL ) {
        ds = ImpTypeInfo( ii, &this_it, NULL, ti );
        if( ds != DS_OK ) return( ds );
    }
    return( DS_OK );
}

dip_status      DIPENTRY DIPImpSymObjLocation( imp_image_handle *ii,
                                imp_sym_handle *is, location_context *lc,
                                 location_list *ll )
{
    char                *name;
    unsigned            len;
    dip_status          ds;
    virt_mem            check;
    virt_mem            next;
    s_all               *p;
    imp_sym_handle      parm;
    imp_type_handle     it;
    type_info           ti;

⌨️ 快捷键说明

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