jvmsym.c

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

C
996
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <string.h>
#include <ctype.h>
#include "jvmdip.h"
#include "java_lang_String.h"

#define OBJECT_SCOPE    (~0L)

typedef walk_result WALK_GLUE( imp_image_handle *, sym_walk_info, imp_sym_handle *, void * );

static walk_result WalkObject( imp_image_handle *ii, bool statics_only,
                ji_ptr clazz, WALK_GLUE *wk, imp_sym_handle *is, void *d )
{
    ji_ptr      super;
    ji_ptr      super_name;
    ji_ptr      block;
    unsigned    num;
    unsigned    i;
    walk_result wr;
    unsigned    acc;

    super = GetPointer( clazz + offsetof( ClassClass, superclass ) );
    if( super != 0 ) {
        super = GetPointer( super + offsetof( JHandle, obj ) );
        is->kind = JS_TYPE;
        is->u.cn = super;
        if( ii->object_class == 0 ) {
            super_name = GetPointer( super + offsetof( ClassClass, name ) );
            GetString( super_name, NameBuff, sizeof( NameBuff ) );
            if( strcmp( NameBuff, JAVA_OBJECT_NAME ) == 0 ) {
                ii->object_class = super;
            }
        }
        /* Don't bother walking java.lang.Object fields - nothing interesting */
        if( super != ii->object_class ) {
            wr = wk( ii, SWI_INHERIT_START, is, d );
            if( wr == WR_CONTINUE ) {
                wr = WalkObject( ii, statics_only, super, wk, is, d );
                if( wr != WR_CONTINUE ) return( wr );
                wk( ii, SWI_INHERIT_END, NULL, d );
            }
        }
    }
    /* walk the fields */
    block = GetPointer( clazz + offsetof( ClassClass, fields ) );
    num = GetU16( clazz + offsetof( ClassClass, fields_count ) );
    is->kind = JS_FIELD;
    for( i = 0; i < num; ++i, block += sizeof( struct fieldblock ) ) {
        if( statics_only ) {
            acc = GetU16( block + offsetof( struct fieldblock, access ) );
            if( !(acc & ACC_STATIC) ) continue;
        }
        is->u.fb = block;
        wr = wk( ii, SWI_SYMBOL, is, d );
        if( wr != WR_CONTINUE ) return( wr );
    }
    /* walk the methods */
    block = GetPointer( clazz + offsetof( ClassClass, methods ) );
    num = GetU16( clazz + offsetof( ClassClass, methods_count ) );
    is->kind = JS_METHOD;
    for( i = 0; i < num; ++i ) {
        acc = GetU16( block + offsetof( struct methodblock, fb.access ) );
        if( !(acc & ACC_NATIVE) ) {
            /* Don't bother telling debugger about native methods */
            is->u.mb = block;
            wr = wk( ii, SWI_SYMBOL, is, d );
            if( wr != WR_CONTINUE ) return( wr );
        }
        block += sizeof( struct methodblock );
    }
    return( WR_CONTINUE );
}

static walk_result WalkAScope( imp_image_handle *ii, unsigned mb_idx,
            scope_block *scope, WALK_GLUE *wk, imp_sym_handle *is, void *d )
{
    ji_ptr              lv_tbl;
    unsigned            lv_num;
    unsigned            idx;
    struct localvar     var;
    ji_ptr              code_start;
    walk_result         wr;

    is->kind = JS_LOCAL;
    code_start = (ji_ptr)ii->methods[mb_idx].code;
    lv_tbl = (ji_ptr)ii->methods[mb_idx].localvar_table;
    lv_num = ii->methods[mb_idx].localvar_table_length;
    for( idx = scope->unique; idx < lv_num; ++idx ) {
        is->u.lv = lv_tbl + idx * sizeof( var );
        if( GetData( is->u.lv, &var, sizeof( var ) ) != DS_OK ) {
            return( WR_FAIL );
        }
        if( var.length != scope->len || (code_start+var.pc0) != scope->start.mach.offset ) {
            return( WR_CONTINUE );
        }
        wr = wk( ii, SWI_SYMBOL, is, d );
        if( wr != WR_CONTINUE ) return( wr );
    }
    return( WR_CONTINUE );
}

static walk_result WalkAllScopes( imp_image_handle *ii, unsigned mb_idx,
            addr_off off, WALK_GLUE *wk, imp_sym_handle *is, void *d )
{
    ji_ptr              lv_tbl;
    unsigned            lv_num;
    unsigned            idx;
    struct localvar     var;
    walk_result         wr;

    is->kind = JS_LOCAL;
    off -= (ji_ptr)ii->methods[mb_idx].code;
    lv_tbl = (ji_ptr)ii->methods[mb_idx].localvar_table;
    lv_num = ii->methods[mb_idx].localvar_table_length;
    for( idx = 0; idx < lv_num; ++idx ) {
        is->u.lv = lv_tbl + idx * sizeof( var );
        if( GetData( is->u.lv, &var, sizeof( var ) ) != DS_OK ) {
            return( WR_FAIL );
        }
        if( (off >= var.pc0) && (off < (var.pc0+var.length)) ) {
            wr = wk( ii, SWI_SYMBOL, is, d );
            if( wr != WR_CONTINUE ) return( wr );
        }
    }
    return( WalkObject( ii, FALSE, ii->cc, wk, is, d ) );
}

struct walk_data {
    IMP_SYM_WKR *wk;
    void        *d;
};

static walk_result WalkSymGlue( imp_image_handle *ii, sym_walk_info swi,
                        imp_sym_handle *is, void *d )
{
    struct walk_data    *wd = d;

    return( wd->wk( ii, swi, is, wd->d ) );
}


walk_result     DIPENTRY DIPImpWalkSymList( imp_image_handle *ii,
                symbol_source ss, void *source, IMP_SYM_WKR *wk,
                imp_sym_handle *is, void *d )
{
    scope_block         *scope;
    address             *a;
    walk_result         wr;
    unsigned            i;
    ji_ptr              clazz;
    imp_type_handle     *it;
    struct walk_data    data;

    data.wk = wk;
    data.d  = d;
    switch( ss ) {
    case SS_BLOCK:
        scope = source;
        switch( FindMBIndex( ii, scope->start.mach.offset, &i ) ) {
        case SR_EXACT:
        case SR_CLOSEST:
            break;
        default:
            return( WR_CONTINUE );
        }
        if( scope->unique == OBJECT_SCOPE ) {
            wr = WalkObject( ii, FALSE, ii->cc, WalkSymGlue, is, &data );
        } else {
            wr = WalkAScope( ii, i, scope, WalkSymGlue, is, &data );
        }
        return( wr );
    case SS_MODULE:
       /* no module scope symbols in Java */
       break;
    case SS_SCOPED:
        a = source;
        switch( FindMBIndex( ii, a->mach.offset, &i ) ) {
        case SR_EXACT:
        case SR_CLOSEST:
            break;
        default:
            return( WR_CONTINUE );
        }
        wr = WalkAllScopes( ii, i, a->mach.offset, WalkSymGlue, is, &data );
        break;
    case SS_TYPE:
        it = source;
        switch( it->kind ) {
        case JT_RAWNAME:
            clazz = GetClass( it->sig );
            break;
        case JT_WANTOBJECT:
        case JT_SIGNATURE:
            if( GetU8( it->sig ) != SIGNATURE_CLASS ) return( WR_CONTINUE );
            clazz = GetClass( it->sig + 1 );
            break;
        default:
            return( WR_CONTINUE );
        }
        if( clazz != 0 ) {
            return( WalkObject( ii, FALSE, clazz, WalkSymGlue, is, &data ) );
        }
        break;
    }
    return( WR_CONTINUE );
}

imp_mod_handle  DIPENTRY DIPImpSymMod( imp_image_handle *ii,
                        imp_sym_handle *is )
{
    return( IMH_JAVA );
}

static unsigned GetName( imp_image_handle *ii, imp_sym_handle *is )
{
    ji_ptr      name;
    unsigned    cp_idx;

    switch( is->kind ) {
    case JS_METHOD:
        name = GetPointer( is->u.mb + offsetof( struct methodblock, fb.name ) );
        break;
    case JS_FIELD:
        name = GetPointer( is->u.fb + offsetof( struct fieldblock, name ) );
        break;
    case JS_LOCAL:
        cp_idx = GetU16( is->u.lv + offsetof( struct localvar, nameoff ) );
        name = GetPointer( ii->cp + cp_idx * sizeof( union cp_item_type ) );
        break;
    case JS_TYPE:
    case JS_PACKAGE:
        name = GetPointer( is->u.cn + offsetof( ClassClass, name ) );
        break;
    }
    return( GetString( name, NameBuff, sizeof( NameBuff ) ) );
}

static ji_ptr GetSignature( imp_image_handle *ii, imp_sym_handle *is )
{
    ji_ptr      sig;
    unsigned    cp_idx;

    sig = 0;
    switch( is->kind ) {
    case JS_METHOD:
        sig = GetPointer( is->u.mb + offsetof( struct methodblock, fb.signature ) );
        break;
    case JS_FIELD:
        sig = GetPointer( is->u.fb + offsetof( struct fieldblock, signature ) );
        break;
    case JS_LOCAL:
        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:
        sig = GetPointer( is->u.cn + offsetof( ClassClass, name ) );
        break;
    }
    return( sig );
}

static unsigned Insert( char *name, unsigned *add, unsigned *len, char *str )
{
    unsigned    str_len;
    unsigned    addv;

    addv = *add;
    str_len = strlen( str );
    memmove( &name[addv+str_len], &name[addv], *len - addv );
    memcpy( &name[addv], str, str_len );
    *len += str_len;
    return( str_len );
}

static char *DoDemangle( char *name, unsigned *add, unsigned *len, char *sig )
{
    char        *p;
    unsigned    first;

    switch( *sig++ ) {
    case SIGNATURE_ARRAY:
        Insert( name, add, len, " []" );
        while( isdigit( *sig ) ) ++sig;
        sig = DoDemangle( name, add, len, sig );
        break;
    case SIGNATURE_CLASS:
        p = strchr( sig, SIGNATURE_ENDCLASS );
        *p = '\0';
        Insert( name, add, len, sig );
        sig = p + 1;
        break;
    case SIGNATURE_FUNC:
        *add += Insert( name, add, len, "(" );
        first = 1;
        for( ;; ) {
            if( *sig == SIGNATURE_ENDFUNC ) break;
            if( !first ) {
                *add += Insert( name, add, len, "," );
            }
            sig = DoDemangle( name, add, len, sig );

⌨️ 快捷键说明

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