⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jvmacc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*
*                            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 + -