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 + -
显示快捷键?