jvmsym.c

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

C
996
字号
            *add = *len;
            first = 0;
        }
        Insert( name, add, len, ")" );
        *add = 0;
        Insert( name, add, len, " " );
        sig = DoDemangle( name, add, len, sig+1 );
        *add = *len;
        break;
    case SIGNATURE_BYTE:
        *add += Insert( name, add, len, "byte" );
        break;
    case SIGNATURE_CHAR:
        *add += Insert( name, add, len, "char" );
        break;
    case SIGNATURE_FLOAT:
        *add += Insert( name, add, len, "float" );
        break;
    case SIGNATURE_DOUBLE:
        *add += Insert( name, add, len, "double" );
        break;
    case SIGNATURE_INT:
        *add += Insert( name, add, len, "int" );
        break;
    case SIGNATURE_LONG:
        *add += Insert( name, add, len, "long" );
        break;
    case SIGNATURE_SHORT:
        *add += Insert( name, add, len, "short" );
        break;
    case SIGNATURE_VOID:
        *add += Insert( name, add, len, "void" );
        break;
    case SIGNATURE_BOOLEAN:
        *add += Insert( name, add, len, "boolean" );
        break;
    }
    return( sig );
}

static unsigned Demangle( char *name, unsigned len, ji_ptr sig_ptr )
{
    char        sig[MAX_NAME];
    unsigned    add;

    GetString( sig_ptr, sig, sizeof( sig ) );
    add = len;
    DoDemangle( name, &add, &len, sig );
    return( len );
}

unsigned        DIPENTRY DIPImpSymName( imp_image_handle *ii,
                        imp_sym_handle *is, location_context *lc,
                        symbol_name sn, char *buff, unsigned max )
{
    unsigned    len;
    ji_ptr      sig;

    len = GetName( ii, is );
    switch( is->kind ) {
    case JS_METHOD:
        if( sn == SN_DEMANGLED ) {
            sig = GetSignature( ii, is );
            if( sig != 0 ) {
                len = Demangle( NameBuff, len, sig );
            }
        }
        break;
    case JS_TYPE:
    case JS_PACKAGE:
        NormalizeClassName( NameBuff, len );
        break;
    }
    return( NameCopy( buff, NameBuff, max, len ) );
}

dip_status      DIPENTRY DIPImpSymType( imp_image_handle *ii,
                imp_sym_handle *is, imp_type_handle *it )
{
    it->sig = GetSignature( ii, is );
    switch( is->kind ) {
    case JS_TYPE:
    case JS_PACKAGE:
        it->kind = JT_RAWNAME;
        return( DS_OK );
    }
    switch( GetU8( it->sig ) ) {
    case SIGNATURE_ARRAY:
    case SIGNATURE_CLASS:
        it->u.is = *is;
        it->kind = JT_WANTOBJECT;
        break;
    default:
        it->kind = JT_SIGNATURE;
        break;
    }

    return( DS_OK );
}

dip_status FollowObject( ji_ptr sig, location_list *ll, ji_ptr *handle )
{
    location_list               var;
    unsigned_32                 off;
    dip_status                  ds;
    unsigned                    len;
    Classjava_lang_String       str;

    /* follow the object pointer(s) */

    if( sig == 0 ) return( DS_OK );
    len = GetString( sig, NameBuff, sizeof( NameBuff ) );
    if( len == 0 ) return( DS_ERR | DS_FAIL );
    switch( NameBuff[0] ) {
    case SIGNATURE_CLASS:
    case SIGNATURE_ARRAY:
        LocationCreate( &var, LT_INTERNAL, &off );
        ds = DCAssignLocation( &var, ll, sizeof( off ) );
        if( ds != DS_OK ) return( ds );
        ll->e[0].u.addr.mach.offset = GetPointer( off + offsetof( JHandle, obj ) );
        *handle = off;
        break;
    default:
        *handle = 0;
        break;
    }
    if( NameBuff[0] == SIGNATURE_CLASS
     && memcmp( &NameBuff[1], JAVA_STRING_NAME, sizeof( JAVA_STRING_NAME ) - 1 ) == 0 ) {
        /* Got a string, get pointer to actual character storage */
        *handle = ll->e[0].u.addr.mach.offset;
        ds = GetData( ll->e[0].u.addr.mach.offset, &str, sizeof( str ) );
        if( ds != DS_OK ) return( ds );
        ll->e[0].u.addr.mach.offset = GetPointer( (ji_ptr)str.value + offsetof( JHandle, obj ) )
                                        + str.offset * sizeof( unicode );
    }
    return( DS_OK );
}

dip_status ImpSymLocation( imp_image_handle *ii, imp_sym_handle *is,
                location_context *lc, location_list *ll, ji_ptr *obj_handle )
{
    address             a;
    dip_status          ds;
    location_list       var;
    unsigned            acc;
    unsigned            cp_idx;
    unsigned_32         off;
    ji_ptr              sig;

    switch( is->kind ) {
    case JS_METHOD:
        sig = 0;
        acc = GetU16( is->u.mb + offsetof( struct methodblock, fb.access ) );
        if( acc & ACC_NATIVE ) return( DS_ERR | DS_BAD_LOCATION );
        a = DefCodeAddr;
        a.mach.offset = GetPointer( is->u.mb + offsetof( struct methodblock, code ) );
        LocationCreate( ll, LT_ADDR, &a );
        break;
    case JS_FIELD:
        sig = GetPointer( is->u.fb + offsetof( struct fieldblock, signature ) );
        acc = GetU16( is->u.fb + offsetof( struct fieldblock, access ) );
        if( acc & ACC_STATIC ) {
            a = DefDataAddr;
            switch( GetU8( sig ) ) {
            case SIGNATURE_LONG:
            case SIGNATURE_DOUBLE:
                a.mach.offset = GetPointer( is->u.fb
                            + offsetof( struct fieldblock, u.static_address ) );
                break;
            default:
                a.mach.offset = is->u.fb
                            + offsetof( struct fieldblock, u.static_value );
                break;
            }
            LocationCreate( ll, LT_ADDR, &a );
        } else {
            ds = DCItemLocation( lc, CI_OBJECT, ll );
            if( ds != DS_OK ) return( ds );
            off = GetU32( is->u.fb + offsetof( struct fieldblock, u.offset ) );
            LocationAdd( ll, off * 8 );
        }
        break;
    case JS_LOCAL:
        ds = DCItemLocation( lc, CI_JVM_vars, &var );
        if( ds != DS_OK ) return( ds );
        a = DefDataAddr;
        LocationCreate( ll, LT_INTERNAL, &a.mach.offset );
        ds = DCAssignLocation( ll, &var, sizeof( a.mach.offset ) );
        if( ds != DS_OK ) return( ds );
        a.mach.offset += GetU32( is->u.lv + offsetof( struct localvar, slot ) )
                                * sizeof( unsigned_32 );
        LocationCreate( ll, LT_ADDR, &a );
        cp_idx = GetU16( is->u.lv + offsetof( struct localvar, sigoff ) );
        sig = GetPointer( ii->cp + cp_idx * sizeof( union cp_item_type ) );
        break;
    case JS_TYPE:
    case JS_PACKAGE:
        return( DS_ERR | DS_BAD_LOCATION );
    }
    *obj_handle = 0;
    return( FollowObject( sig, ll, obj_handle ) );
}

dip_status      DIPENTRY DIPImpSymLocation( imp_image_handle *ii,
                imp_sym_handle *is, location_context *lc, location_list *ll )
{
    ji_ptr      handle;

    return( ImpSymLocation( ii, is, lc, ll, &handle ) );
}

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

//NYI: sym_info fields not set
//    unsigned          global                  : 1;
//    unsigned          compiler                : 1;
//    /* only valid for SK_PROCEDURE */
//    unsigned          rtn_calloc              : 1;
//    unsigned          ret_modifier            : 3;
//    unsigned          ret_size                : 4;
//    unsigned short    num_parms;
//    addr_off          ret_addr_offset;
//    addr_off          prolog_size;
//    addr_off          epilog_size;

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

    memset( si, 0, sizeof( si ) );
    switch( is->kind ) {
    case JS_METHOD:
        si->kind = SK_PROCEDURE;
        si->member = 1;
        si->rtn_size = GetU32( is->u.mb + offsetof( struct methodblock, code_length ) );
        break;
    case JS_FIELD:
        si->kind = SK_DATA;
        si->member = 1;
        break;
    case JS_LOCAL:
        si->kind = SK_DATA;
        return( DS_OK );
    case JS_TYPE:
        si->kind = SK_TYPE;
        return( DS_OK );
    case JS_PACKAGE:
        si->kind = SK_NAMESPACE;
        return( DS_OK );
    }
    acc = GetU16( is->u.fb + offsetof( struct fieldblock, access ) );
    if( acc & ACC_PUBLIC ) si->is_public = 1;
    if( acc & ACC_PRIVATE ) si->is_private = 1;
    if( acc & ACC_PROTECTED ) si->is_protected = 1;
    if( acc & ACC_STATIC ) si->is_static = 1;
    return( DS_OK );
}

dip_status      DIPENTRY DIPImpSymParmLocation( imp_image_handle *ii,
                    imp_sym_handle *is, location_context *lc,
                    location_list *ll, unsigned n )
{
    return( DS_FAIL );
}

dip_status      DIPENTRY DIPImpSymObjType( imp_image_handle *ii,
                    imp_sym_handle *is, imp_type_handle *it, type_info *ti )
{
    struct methodblock  method;
    dip_status          ds;

    if( is->kind != JS_METHOD ) return( DS_FAIL );
    ds = GetData( is->u.mb, &method, sizeof( method ) );
    if( ds != DS_OK ) return( ds );
    if( method.fb.access & ACC_NATIVE ) return( DS_FAIL );
    if( ti != NULL ) {
        if( method.fb.access & ACC_STATIC ) {
            ti->kind = TK_NONE;
        } else {
            ti->kind = TK_POINTER;
            ti->size = sizeof( ji_ptr );
        }
    }
    it->sig = GetPointer( GetPointer( (ji_ptr)method.fb.clazz )
                                + offsetof( ClassClass, name ) );
    it->kind = JT_RAWNAME;
    return( DS_FAIL );
}

dip_status      DIPENTRY DIPImpSymObjLocation( imp_image_handle *ii,
                                imp_sym_handle *is, location_context *lc,
                                 location_list *ll )
{
    struct methodblock  method;
    dip_status          ds;
    unsigned            i;
    imp_sym_handle      is_this;
    ji_ptr              cp;
    ji_ptr              name;
    unsigned            cp_idx;
    ji_ptr              handle;

    if( is->kind != JS_METHOD ) return( DS_FAIL );
    ds = GetData( is->u.mb, &method, sizeof( method ) );
    if( ds != DS_OK ) return( ds );
    if( method.fb.access & (ACC_NATIVE | ACC_STATIC) ) return( DS_FAIL );
    cp = GetPointer( (ji_ptr)method.fb.clazz + offsetof( ClassClass, constantpool ) );
    is_this.kind = JS_LOCAL;
    is_this.u.lv = (ji_ptr)method.localvar_table;
    /* guessing "this" pointer is near start of local var list */
    for( i = 0; i < method.localvar_table_length; ++i ) {
        cp_idx = GetU16( is_this.u.lv + offsetof( struct localvar, nameoff ) );
        name = GetPointer( cp + cp_idx * sizeof( union cp_item_type ) );
        GetString( name, NameBuff, sizeof( NameBuff ) );
        if( strcmp( NameBuff, "this" ) == 0 ) {
            return( ImpSymLocation( ii, &is_this, lc, ll, &handle ) );
        }
        is_this.u.lv += sizeof( struct localvar );
    }
    return( DS_FAIL );
}

search_result   DIPENTRY DIPImpAddrSym( imp_image_handle *ii,
                            imp_mod_handle im, address a, imp_sym_handle *is )
{
    search_result       sr;
    unsigned            i;

⌨️ 快捷键说明

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