📄 jvmacc.c
字号:
/****************************************************************************
*
* 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 <windows.h>
#include "trpimp.h"
#include "javadbg.h"
#include <malloc.h>
#include <string.h>
#define MD_jvm
#include "madregs.h"
#include "javaname.h"
#include "jvmerr.h"
ClassClass *cbCallJava;
HANDLE EventSem;
HANDLE EventDoneSem;
int LastClassGiven; // 1 based index of last class returned
int AppsLoaded;
int Event;
typedef struct brk {
struct brk *next;
char saved;
unsigned pc;
} brk;
brk *BPList = NULL;
brk *StartBPList = NULL;
#define MAX_THREADS 256
Hjava_lang_Thread *Threads[MAX_THREADS];
sys_thread_t *SysThreads[MAX_THREADS];
Hjava_lang_ThreadGroup *ThreadGroup;
static Hsun_tools_debug_BreakpointQueue *TheBkptQ = 0;
int CurrThreadIdx;
int NumThreads;
#define CurrThread ( ( CurrThreadIdx == -1 ) \
? ( NULL ) \
: ((Classjava_lang_Thread*)unhand(Threads[CurrThreadIdx])) )
#define OP_BREAK "\xCA"
#define EventDone() ReleaseSemaphore( EventDoneSem, 1, NULL )
#define Event( i ) Event = i; ReleaseSemaphore( EventSem, 1, NULL )
#define WaitForEvent() WaitForSingleObject( EventSem, INFINITE )
#define WaitEventDone() WaitForSingleObject( EventDoneSem, INFINITE )
#define JS( x ) makeJavaString( x, strlen( x ) )
ClassClass *CbMain;
static void ThreadName( Classjava_lang_Thread* trd, char *buff, int len )
/***********************************************************************/
{
char *p;
unicode *src;
src = unhand(trd->name)->body;
len = obj_length(trd->name);
p = buff;
while( *src ) {
if( --len < 0 ) break;
*p++ = *src++;
}
*p = '\0';
}
static void TheBigSleep()
/***********************/
{
for( ;; ) Sleep( 1000 );
}
unsigned DoRead( int addr, char *buff, unsigned length )
/******************************************************/
{
DWORD bytes;
ReadProcessMemory( GetCurrentProcess(), (LPVOID)addr, buff,
length, (LPDWORD) &bytes );
return( bytes );
}
unsigned DoWrite( int addr, char *buff, unsigned length )
/*******************************************************/
{
DWORD bytes;
WriteProcessMemory( GetCurrentProcess(), (LPVOID)addr, buff,
length, (LPDWORD) &bytes );
return( bytes );
}
void AddStartingBreakpoint( unsigned pc )
/***************************************/
{
brk *new;
new = LocalAlloc( LMEM_FIXED, sizeof( *new ) );
new->next = StartBPList;
StartBPList = new;
new->pc = pc;
DoRead( pc, &new->saved, 1 );
DoWrite( pc, OP_BREAK, 1 );
}
long * getclassvariable(struct ClassClass *cb, char *fname)
/*********************************************************/
{
int n = cb->fields_count;
struct fieldblock *fb;
for (fb = cbFields(cb); --n >= 0; fb++)
if ((fb->access & ACC_STATIC) && strcmp(fname, fieldname(fb)) == 0) {
char *signature = fieldsig(fb);
if (signature[0] == SIGNATURE_LONG ||
signature[0] == SIGNATURE_DOUBLE)
return (long *)twoword_static_address(fb);
else
return (long *)normal_static_address(fb);
}
return (long *)0;
}
void ResumeThreads()
/******************/
{
int i;
for( i = 0; i < NumThreads; ++i ) {
if( SysThreads[i] && SysThreads[i]->handle ) {
ResumeThread( SysThreads[i]->handle );
}
}
}
void SuspendThreads()
/*******************/
{
int i;
for( i = 0; i < NumThreads; ++i ) {
SysThreads[i] = SYSTHREAD(Threads[i]);
if( Threads[i] == unhand(TheBkptQ)->thread ) {
CurrThreadIdx = i;
}
if( SysThreads[i] && SysThreads[i]->handle ) {
SuspendThread( SysThreads[i]->handle );
}
}
}
int HandleBreak()
/****************/
{
int cond;
brk **owner, *bp;
cond = COND_TRACE;
for( owner = &StartBPList; *owner != NULL; owner = &(bp->next) ) {
bp = *owner;
if( bp->pc == unhand(TheBkptQ)->pc ) {
unhand(TheBkptQ)->opcode = bp->saved;
DoWrite( bp->pc, &bp->saved, 1 );
*owner = bp->next;
LocalFree( bp );
break;
}
}
for( bp = BPList; bp != NULL; bp = bp->next ) {
DoWrite( bp->pc, &bp->saved, 1 );
if( bp->pc == unhand(TheBkptQ)->pc ) {
DoWrite( bp->pc, &bp->saved, 1 );
unhand(TheBkptQ)->opcode = bp->saved;
cond = COND_BREAK;
}
}
return( cond );
}
#pragma aux (cdecl) BreakpointLoop "Java_sun_tools_debug_jvmhandler_BreakpointLoop_stub" export
void BreakpointLoop( stack_item *p, ExecEnv *ee )
/******************************************************/
{
Hsun_tools_debug_BreakpointQueue **bkptQ;
ClassClass *jvmhandler_class;
ClassClass *bkpthandler_class;
Classjava_lang_ThreadGroup *tg;
ArrayOfObject *threads;
char buff[256];
int i;
int cond;
int num_threads;
int foundBPThread;
ThreadGroup = (Hjava_lang_ThreadGroup *)p[0].h;
jvmhandler_class = FindClass(ee, "sun/tools/debug/jvmhandler", TRUE);
/* Find the static variable that contains the queue */
bkptQ =(Hsun_tools_debug_BreakpointQueue **) getclassvariable(jvmhandler_class, "bkptQ");
TheBkptQ = *bkptQ;
bkpthandler_class = FindClass(ee, "sun/tools/debug/BreakpointHandler", TRUE);
bkptQ =(Hsun_tools_debug_BreakpointQueue **) getclassvariable(bkpthandler_class, "the_bkptQ");
*bkptQ = TheBkptQ;
monitorEnter(obj_monitor(TheBkptQ));
for( ;; ) {
monitorWait(obj_monitor(TheBkptQ),INFINITE);
if( unhand(TheBkptQ)->exception == NULL ) {
cond = HandleBreak();
} else {
cond = 0;
// nyi - catching exceptions???
}
unhand(TheBkptQ)->updated = TRUE;
tg = unhand(ThreadGroup);
threads = unhand((HArrayOfObject*)tg->threads);
num_threads = obj_length(tg->threads);
// enumerate all threads
NumThreads = 0;
CurrThreadIdx = -1;
foundBPThread = FALSE;
for( i = 0; i < num_threads; ++i ) {
Threads[NumThreads] = (Hjava_lang_Thread*)threads->body[i];
if( Threads[NumThreads] == NULL ) continue;
ThreadName( unhand( Threads[NumThreads] ), buff, sizeof( buff ) );
if( memcmp( buff, "jvmhelp", sizeof( "jvmhelp" )-1 ) == 0 ) continue;
if( Threads[NumThreads] == unhand(TheBkptQ)->thread ) {
foundBPThread = TRUE;
}
++NumThreads;
}
if( !foundBPThread ) {
Threads[NumThreads] = unhand(TheBkptQ)->thread;
ThreadName( unhand( Threads[NumThreads] ), buff, sizeof( buff ) );
++NumThreads;
}
SuspendThreads();
Event( cond );
WaitEventDone();
ResumeThreads();
}
}
#pragma aux (cdecl) HandleExit;
void HandleExit(void)
/*******************/
{
Event( COND_TERMINATE );
TheBigSleep();
}
unsigned ReqGet_sys_config( void )
/********************************/
{
get_sys_config_ret *ret;
ret = GetOutPtr( 0 );
ret->sys.os = OS_NT;
ret->sys.osmajor = 1;
ret->sys.osminor = 0;
ret->sys.huge_shift = 3;
ret->sys.cpu = 0;
ret->sys.fpu = 0;
ret->sys.mad = MAD_JVM;
return( sizeof( *ret ) );
}
unsigned ReqMap_addr()
/********************/
{
map_addr_req *acc;
map_addr_ret *ret;
WORD seg;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
seg = acc->in_addr.segment;
ret->out_addr = acc->in_addr;
switch( seg ) {
case MAP_FLAT_CODE_SELECTOR:
case MAP_FLAT_DATA_SELECTOR:
ret->out_addr.segment = MAD_JVM_USER_MEM_SELECTOR;
break;
default:
ret->out_addr.segment = MAD_JVM_UNKNOWN_SELECTOR;
break;
}
ret->lo_bound = 0;
ret->hi_bound = ~(addr48_off)0;
return( sizeof( *ret ) );
}
unsigned ReqMachine_data()
/************************/
{
machine_data_req *acc;
machine_data_ret *ret;
unsigned_8 *data;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
data = GetOutPtr( sizeof( *ret ) );
return( sizeof( *ret ) );
}
unsigned ReqChecksum_mem()
/************************/
{
DWORD offset;
WORD length,value;
DWORD sum;
checksum_mem_req *acc;
checksum_mem_ret *ret;
acc = GetInPtr(0);
ret = GetOutPtr(0);
length = acc->len;
sum = 0;
offset = acc->in_addr.offset;
while( length != 0 ) {
DoRead( offset, (char*)&value, sizeof( value ) );
sum += value & 0xff;
offset++;
length--;
if( length != 0 ) {
sum += value >> 8;
offset++;
length--;
}
}
ret->result = sum;
return( sizeof( *ret ) );
}
static union {
mad_jvm_findlinecue_acc l;
mad_jvm_findaddrcue_acc a;
} FindLineInfo;
static void LineNumLookup( mad_jvm_findline_ret *info )
/*************************************************************/
{
unsigned mb_idx;
struct methodblock *mb;
unsigned ln_idx;
struct lineno *ln;
unsigned long best_ln;
unsigned long curr_ln;
ClassClass *cb;
int cb_idx;
int nbinclasses = get_nbinclasses();
ClassClass **binclasses = get_binclasses();
best_ln = ~0L;
for( cb_idx = 0; cb_idx < nbinclasses; ++cb_idx ) {
cb = binclasses[cb_idx];
if( cb->source_name == NULL ) continue;
if( stricmp( cb->source_name, ((ClassClass*)(FindLineInfo.l.class_pointer))->source_name ) != 0 ) continue;
mb = cbMethods(cb);
for( mb_idx = 0; mb_idx < cb->methods_count; ++mb_idx, ++mb ) {
ln = mb->line_number_table;
for( ln_idx = 0; ln_idx < mb->line_number_table_length; ++ln_idx, ++ln ) {
curr_ln = ln->line_number;
if( curr_ln == FindLineInfo.l.line_num ) {
info->class_pointer = (unsigned_32)cb;
info->line_index = ln_idx;
info->method_index = mb_idx;
info->ret = SR_EXACT;
return;
}
if( (curr_ln > FindLineInfo.l.line_num ) && (curr_ln < best_ln) ) {
best_ln = curr_ln;
info->class_pointer = (unsigned_32)cb;
info->line_index = ln_idx;
info->method_index = mb_idx;
}
}
}
}
info->ret = best_ln != ~0L ? SR_CLOSEST : SR_NONE;
}
static void LineAddrLookup( mad_jvm_findline_ret *info )
/******************************************************/
{
unsigned i;
long lo;
long hi;
long target;
unsigned long pc;
ClassClass *cc;
struct methodblock *mb;
struct lineno *ln_tbl;
info->ret = SR_NONE;
cc = (ClassClass *)FindLineInfo.a.class_pointer;
mb = cbMethods( cc );
i = 0;
for( ;; ) {
if( i >= cc->methods_count ) return;
if( !(mb->fb.access & ACC_NATIVE) ) {
if( FindLineInfo.a.addr >= (unsigned_32)mb->code
&& FindLineInfo.a.addr < (unsigned_32)mb->code + mb->code_length ) break;
}
++mb;
++i;
}
info->class_pointer = (unsigned_32)cc;
info->method_index = i;
FindLineInfo.a.addr -= (unsigned_32)mb->code;
ln_tbl = mb->line_number_table;
hi = mb->line_number_table_length - 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -