harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gshiman...@apache.org
Subject svn commit: r597138 [15/15] - in /harmony/enhanced/drlvm/trunk: build/make/ build/make/components/vm/ vm/include/ vm/include/open/ vm/jitrino/src/codegenerator/ia32/ vm/port/src/encoder/ia32_em64t/ vm/port/src/lil/ia32/pim/ vm/tests/ncai/ vm/tests/ncai...
Date Wed, 21 Nov 2007 16:29:54 GMT
Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ia32.cpp?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ia32.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ia32.cpp Wed Nov 21 08:29:40 2007
@@ -0,0 +1,424 @@
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+
+#define LOG_DOMAIN "ncai.step"
+#include "cxxlog.h"
+#include "jvmti_break_intf.h"
+
+#include "ncai_utils.h"
+#include "ncai_direct.h"
+#include "ncai_internal.h"
+
+// Instrument predicted exit points for STEP_OUT mode
+static bool ncai_instrument_exits(void* addr, NCAISingleStepState* sss);
+
+
+void ncai_setup_single_step(GlobalNCAI* ncai,
+            const VMBreakPoint* bp, jvmti_thread_t jvmti_thread)
+{
+    VMBreakPoints* vm_brpt = VM_Global_State::loader_env->TI->vm_brpt;
+    LMAutoUnlock lock(vm_brpt->get_lock());
+    NCAISingleStepState* sss = jvmti_thread->ncai_ss;
+
+    TRACE2("ncai.step", "Setup predicted single step breakpoints for address "
+        << ((bp) ? bp->addr : NULL));
+
+    if (!ncai->step_enabled) // SS is now disabled
+    {
+        if (sss)
+            ncai_stop_thread_single_step(jvmti_thread);
+        return;
+    }
+
+    assert(sss && sss->breakpoints);
+    sss->breakpoints->remove_all_reference();
+
+    VMBreakInterface* intf = sss->breakpoints;
+    ncaiStepMode step_mode = ncai_get_thread_ss_mode(jvmti_thread);
+
+    // Set breakpoints to possible next instructions
+    // If step mode is STEP_OFF, set it like for STEP_INTO
+    if (step_mode == NCAI_STEP_OFF)
+        step_mode = NCAI_STEP_INTO;
+
+    InstructionDisassembler* dasm = bp->disasm;
+    InstructionDisassembler::Type type = dasm->get_type();
+    assert(type != InstructionDisassembler::OPCODEERROR);
+    char* address = (char*)bp->addr;
+    jint length = dasm->get_length_with_prefix();
+
+    if (step_mode == NCAI_STEP_OUT)
+    {
+        if (type == InstructionDisassembler::RET)
+        {
+            sss->flag_out = true;
+            step_mode = NCAI_STEP_INTO;
+        }
+        else
+        {
+            sss->flag_out = false;
+            bool UNREF res = ncai_instrument_exits(bp->addr, sss);
+            assert(res);
+            return;
+        }
+    }
+
+    // Set breakpoint to instruction which follows the current one in memory
+    if (type == InstructionDisassembler::OTHER ||
+        type == InstructionDisassembler::RELATIVE_COND_JUMP ||
+        ((type == InstructionDisassembler::RELATIVE_CALL ||
+          type == InstructionDisassembler::INDIRECT_CALL) &&
+            step_mode == NCAI_STEP_OVER))
+    {
+        char* next_addr = address + length;
+
+        TRACE2("ncai.step", "Setting up SS breakpoint to instruction "
+            << "following linear instruction: " << (void*)next_addr);
+
+        VMBreakPointRef* ref =
+            intf->add_reference((NativeCodePtr)next_addr, 0);
+        assert(ref);
+    }
+
+    // Set breakpoint to result of direct/conditional transfers
+    if (type == InstructionDisassembler::RELATIVE_JUMP ||
+        type == InstructionDisassembler::RELATIVE_COND_JUMP)
+    {
+        char* target = (char*)dasm->get_jump_target_address();
+
+        TRACE2("ncai.step", "Setting up SS breakpoint to relative JUMP target: "
+            << (void*)target);
+
+        VMBreakPointRef* ref =
+            intf->add_reference((NativeCodePtr)target, 0);
+        assert(ref);
+    }
+
+    // Set breakpoint to result of context-dependent transfers
+    if (type == InstructionDisassembler::INDIRECT_JUMP ||
+        type == InstructionDisassembler::RET)
+    {
+        char* target = (char*)dasm->get_target_address_from_context(&bp->regs);
+
+        TRACE2("ncai.step", "Setting up SS breakpoint to "
+            << "INDIRECT_JUMP or RET target: " << (void*)target);
+
+        VMBreakPointRef* ref =
+            intf->add_reference((NativeCodePtr)target, 0);
+        assert(ref);
+    }
+
+    // Check if step mode is STEP_INTO and target address is in VM code
+    // If so, we should step over this call to avoid deadlocks and recursion
+    if (step_mode == NCAI_STEP_INTO &&
+        (   type == InstructionDisassembler::RELATIVE_CALL ||
+            type == InstructionDisassembler::INDIRECT_CALL))
+    {
+        char* target;
+
+        if (type == InstructionDisassembler::RELATIVE_CALL)
+            target = (char*)dasm->get_jump_target_address();
+        else
+            target = (char*)dasm->get_target_address_from_context(&bp->regs);
+
+        ncaiModuleKind mod_type =
+            ncai_get_target_address_type(target);
+
+        VMBreakPointRef* ref;
+        char* next_addr = address + length;
+
+//        if (mod_type == NCAI_MODULE_VM_INTERNAL)
+        if (mod_type != NCAI_MODULE_JNI_LIBRARY)
+        {
+            TRACE2("ncai.step", "Setting up SS breakpoint to "
+                << "instruction following CALL: " << (void*)next_addr);
+
+            ref = intf->add_reference((NativeCodePtr)next_addr, 0);
+        }
+        else
+        {
+            TRACE2("ncai.step", "Setting up SS breakpoint to "
+                << "CALL target: " << (void*)target);
+
+            ref = intf->add_reference((NativeCodePtr)target, 0);
+        }
+
+        assert(ref);
+    }
+}
+
+void ncai_setup_signal_step(jvmti_thread_t jvmti_thread, NativeCodePtr addr)
+{
+    GlobalNCAI* ncai = VM_Global_State::loader_env->NCAI;
+    if (!ncai->isEnabled() || !ncai->step_enabled)
+        return;
+
+    TRACE2("ncai.step",
+        "Setting breakpoint to HWE handler address: " << addr);
+
+    NCAISingleStepState* sss = jvmti_thread->ncai_ss;
+    assert(sss);
+
+    VMBreakPoints *vm_brpt = VM_Global_State::loader_env->TI->vm_brpt;
+    LMAutoUnlock lock(vm_brpt->get_lock());
+
+    if (sss && sss->breakpoints)
+        sss->breakpoints->remove_all_reference();
+
+    VMBreakInterface* intf = sss->breakpoints;
+    ncaiStepMode step_mode = ncai_get_thread_ss_mode(jvmti_thread);
+
+    if (step_mode == NCAI_STEP_OUT)
+        sss->flag_out = true; // To report next step
+
+    // Check if target address is in VM code
+    ncaiModuleKind mod_type =
+        ncai_get_target_address_type(addr);
+
+// Trying to set breakpoint to any type of code
+//    if (mod_type != NCAI_MODULE_VM_INTERNAL)
+//    if (mod_type == NCAI_MODULE_JNI_LIBRARY)
+    {
+        VMBreakPointRef* UNREF ref = intf->add_reference(addr, 0);
+        assert(ref);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//  Utility functions for STEP_OUT processing
+
+struct stAddrListItem
+{
+    void*           addr;
+    stAddrListItem* next;
+};
+
+struct stMovItem
+{
+    InstructionDisassembler*    dasm;
+    stMovItem*                  next;
+};
+
+
+static void add_mov_list(stMovItem** plist, InstructionDisassembler* dasm)
+{
+    bool has_reg = false;
+    bool has_imm = false;
+    bool has_mem = false;
+
+    for (unsigned i = 0; i < dasm->get_operands_count(); i++)
+    {
+        const InstructionDisassembler::Opnd& op = dasm->get_opnd(i);
+        if (op.kind == InstructionDisassembler::Kind_Reg)
+            has_reg = true;
+        else if (op.kind == InstructionDisassembler::Kind_Mem)
+            has_mem = true;
+        else if (op.kind == InstructionDisassembler::Kind_Imm)
+            has_imm = true;
+
+        if (has_reg && (has_mem || has_imm))
+        {
+            stMovItem* mov = (stMovItem*)STD_MALLOC(sizeof(stMovItem));
+            assert(mov);
+            mov->dasm = dasm;
+            mov->next = *plist;
+            *plist = mov;
+            return;
+        }
+    }
+
+    delete dasm;
+}
+
+static void free_mov_list(stMovItem** plist)
+{
+    while (*plist)
+    {
+        stMovItem* next = (*plist)->next;
+        InstructionDisassembler* dasm = (*plist)->dasm;
+        delete dasm;
+        STD_FREE(*plist);
+        *plist = next;
+    }
+}
+
+static bool add_addr(stAddrListItem** plist, void* addr)
+{
+    for (stAddrListItem* ptr = *plist; ptr; ptr = ptr->next)
+    {
+        if (ptr->addr == addr)
+            return false;
+    }
+
+    stAddrListItem* item = (stAddrListItem*)STD_MALLOC(sizeof(stAddrListItem));
+    assert(item);
+    item->next = *plist;
+    item->addr = addr;
+    *plist = item;
+
+    return true;
+}
+
+static void free_addr_list(stAddrListItem** plist)
+{
+    while (*plist)
+    {
+        stAddrListItem* next = (*plist)->next;
+        STD_FREE(*plist);
+        *plist = next;
+    }
+}
+
+static inline void add_branch(stAddrListItem** plist, void* addr)
+{
+    for (stAddrListItem* ptr = *plist; ptr; ptr = ptr->next)
+    {
+        if (ptr->addr == addr)
+            return;
+    }
+
+    stAddrListItem* item = (stAddrListItem*)STD_MALLOC(sizeof(stAddrListItem));
+    assert(item);
+
+    item->next = *plist;
+    item->addr = addr;
+    *plist = item;
+}
+
+static bool ncai_fill_jump_targets(void* cur, InstructionDisassembler* pdasm,
+    stAddrListItem** pbranches, stMovItem* movs)
+{
+    assert(pdasm->get_type() == InstructionDisassembler::INDIRECT_JUMP);
+#define MAX_FUN_SIZE    1024
+    // Indirect jump can represent table switch instruction
+    // Not implemented yet
+    assert(0);
+    return true;
+}
+
+static InstructionDisassembler* get_local_disasm(void* addr)
+{
+    VMBreakPoints* vm_brpt = VM_Global_State::loader_env->TI->vm_brpt;
+    uint8* bptr = (uint8*)addr;
+    InstructionDisassembler* pdasm;
+
+    if (*bptr == INSTRUMENTATION_BYTE)
+    { // Address was instrumented by another thread or by breakpoint
+        VMBreakPoint* bp = vm_brpt->find_breakpoint(addr);
+        assert(bp && bp->disasm);
+        pdasm = new InstructionDisassembler(*bp->disasm);
+    }
+    else
+        pdasm = new InstructionDisassembler(addr);
+
+    assert(pdasm);
+    return pdasm;
+}
+
+static bool ncai_instrument_exits(void* addr, NCAISingleStepState* sss)
+{
+    assert(addr && sss);
+    stAddrListItem* branch_list = NULL;
+    stMovItem* mov_list = NULL;
+    stAddrListItem* addr_list = NULL;
+    void* cur = addr;
+
+    while (cur || branch_list)
+    {
+        if (!cur || !add_addr(&addr_list, cur))
+        {
+            free_mov_list(&mov_list);
+            cur = NULL;
+
+            if (branch_list)
+            {
+                stAddrListItem* br = branch_list;
+                cur = br->addr;
+                branch_list = br->next;
+                STD_FREE(br);
+            }
+
+            continue;
+        }
+
+        InstructionDisassembler* pdasm = get_local_disasm(cur);
+        InstructionDisassembler::Type type = pdasm->get_type();
+        size_t len = (size_t)pdasm->get_length_with_prefix();
+
+        if (type == InstructionDisassembler::INDIRECT_JUMP)
+        {
+            bool UNREF res =
+                ncai_fill_jump_targets(cur, pdasm, &branch_list, mov_list);
+            assert(res);
+
+            free_mov_list(&mov_list);
+            delete pdasm;
+            cur = NULL;
+            continue;
+        }
+
+        if (type == InstructionDisassembler::RET)
+        {
+            VMBreakInterface* intf = sss->breakpoints;
+            assert(intf);
+
+            VMBreakPointRef* ref =
+                intf->add_reference((NativeCodePtr)cur, 0);
+            assert(ref);
+
+            free_mov_list(&mov_list);
+            delete pdasm;
+            cur = NULL;
+            continue;
+        }
+
+        if (type == InstructionDisassembler::RELATIVE_JUMP)
+        {
+            void* target = pdasm->get_jump_target_address();
+
+            if (target >= cur)
+                cur = target;
+
+            free_mov_list(&mov_list);
+            delete pdasm;
+            continue;
+        }
+
+        if (type == InstructionDisassembler::OTHER)
+        {
+            add_mov_list(&mov_list, pdasm);
+            cur = (void*)((char*)cur + len);
+            continue;
+        }
+
+        if (type == InstructionDisassembler::RELATIVE_CALL ||
+            type == InstructionDisassembler::INDIRECT_CALL)
+        {
+            free_mov_list(&mov_list);
+            delete pdasm;
+            cur = (void*)((char*)cur + len);
+            continue;
+        }
+
+        if (type == InstructionDisassembler::RELATIVE_COND_JUMP)
+        {
+            void* target = pdasm->get_jump_target_address();
+            assert(target);
+
+            if (target >= cur)
+                add_branch(&branch_list, target);
+
+            delete pdasm;
+            cur = (void*)((char*)cur + len);
+            continue;
+        }
+
+        assert(0);
+    }
+
+    free_mov_list(&mov_list);
+    free_addr_list(&addr_list);
+    return true;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ia32.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ipf.cpp?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ipf.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ipf.cpp Wed Nov 21 08:29:40 2007
@@ -0,0 +1,26 @@
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+
+#define LOG_DOMAIN "ncai.step"
+#include "cxxlog.h"
+#include "jvmti_break_intf.h"
+
+#include "ncai_utils.h"
+#include "ncai_direct.h"
+#include "ncai_internal.h"
+
+
+void ncai_setup_single_step(GlobalNCAI* ncai,
+            const VMBreakPoint* bp, jvmti_thread_t jvmti_thread)
+{
+    TRACE2("ncai.step", "Setup predicted single step breakpoints: "
+        << "not implemented for em64t");
+}
+
+void ncai_setup_signal_step(jvmti_thread_t jvmti_thread, NativeCodePtr addr)
+{
+    TRACE2("ncai.step", "Setting up single step in exception handler: "
+        << "not implemented for IPF");
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ipf.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_em64t.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_em64t.cpp?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_em64t.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_em64t.cpp Wed Nov 21 08:29:40 2007
@@ -0,0 +1,235 @@
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+
+#include "open/types.h"
+#include <open/ncai_thread.h>
+
+#include "ncai_internal.h"
+
+
+struct NcaiRegisters
+{
+    uint64  rax;
+    uint64  rbx;
+    uint64  rcx;
+    uint64  rdx;
+    uint64  rsp;
+    uint64  rbp;
+    uint64  rsi;
+    uint64  rdi;
+    uint64  r8;
+    uint64  r9;
+    uint64  r10;
+    uint64  r11;
+    uint64  r12;
+    uint64  r13;
+    uint64  r14;
+    uint64  r15;
+    uint16  ds;
+    uint16  es;
+    uint16  fs;
+    uint16  gs;
+    uint16  ss;
+    uint16  cs;
+    uint64  rip;
+    uint32  eflags;
+};
+
+#define REGSIZE(_field_) ((jint)sizeof(((NcaiRegisters*)0)->_field_))
+#define REGOFF(_field_) ((POINTER_SIZE_INT)&(((NcaiRegisters*)0)->_field_))
+
+NcaiRegisterTableItem g_ncai_reg_table[] = {
+    {"rax",     REGSIZE(rax),   REGOFF(rax)   },
+    {"rbx",     REGSIZE(rbx),   REGOFF(rbx)   },
+    {"rcx",     REGSIZE(rcx),   REGOFF(rcx)   },
+    {"rdx",     REGSIZE(rdx),   REGOFF(rdx)   },
+    {"rsp",     REGSIZE(rsp),   REGOFF(rsp)   },
+    {"rbp",     REGSIZE(rbp),   REGOFF(rbp)   },
+    {"rsi",     REGSIZE(rsi),   REGOFF(rsi)   },
+    {"rdi",     REGSIZE(rdi),   REGOFF(rdi)   },
+    {"ds",      REGSIZE(ds),    REGOFF(ds)    },
+    {"es",      REGSIZE(es),    REGOFF(es)    },
+    {"fs",      REGSIZE(fs),    REGOFF(fs)    },
+    {"gs",      REGSIZE(gs),    REGOFF(gs)    },
+    {"ss",      REGSIZE(ss),    REGOFF(ss)    },
+    {"cs",      REGSIZE(cs),    REGOFF(cs)    },
+    {"rip",     REGSIZE(rip),   REGOFF(rip)   },
+    {"eflags",  REGSIZE(eflags),REGOFF(eflags)},
+};
+
+size_t ncai_get_reg_table_size()
+{
+    return sizeof(g_ncai_reg_table)/sizeof(g_ncai_reg_table[0]);
+}
+
+#ifdef PLATFORM_POSIX
+
+static void ncai_context_to_registers(ucontext_t* pcontext, NcaiRegisters* pregs)
+{
+    pregs->rax  = pcontext->uc_mcontext.gregs[REG_RAX];
+    pregs->rbx  = pcontext->uc_mcontext.gregs[REG_RBX];
+    pregs->rcx  = pcontext->uc_mcontext.gregs[REG_RCX];
+    pregs->rdx  = pcontext->uc_mcontext.gregs[REG_RDX];
+    pregs->rsp  = pcontext->uc_mcontext.gregs[REG_RSP];
+    pregs->rbp  = pcontext->uc_mcontext.gregs[REG_RBP];
+    pregs->rsi  = pcontext->uc_mcontext.gregs[REG_RSI];
+    pregs->rdi  = pcontext->uc_mcontext.gregs[REG_RDI];
+    pregs->r8   = pcontext->uc_mcontext.gregs[REG_R8];
+    pregs->r9   = pcontext->uc_mcontext.gregs[REG_R9];
+    pregs->r10  = pcontext->uc_mcontext.gregs[REG_R10];
+    pregs->r11  = pcontext->uc_mcontext.gregs[REG_R11];
+    pregs->r12  = pcontext->uc_mcontext.gregs[REG_R12];
+    pregs->r13  = pcontext->uc_mcontext.gregs[REG_R13];
+    pregs->r14  = pcontext->uc_mcontext.gregs[REG_R14];
+    pregs->r15  = pcontext->uc_mcontext.gregs[REG_R15];
+    pregs->fs = ((uint16*)&pcontext->uc_mcontext.gregs[REG_CSGSFS])[2];
+    pregs->gs = ((uint16*)&pcontext->uc_mcontext.gregs[REG_CSGSFS])[1];
+    pregs->ss   = 0;
+    pregs->cs = ((uint16*)&pcontext->uc_mcontext.gregs[REG_CSGSFS])[0];
+    pregs->rip    = pcontext->uc_mcontext.gregs[REG_RIP];
+    pregs->eflags = pcontext->uc_mcontext.gregs[REG_EFL];
+}
+
+static void ncai_registers_to_context(NcaiRegisters* pregs, ucontext_t* pcontext)
+{
+    pcontext->uc_mcontext.gregs[REG_RAX]  = pregs->rax;
+    pcontext->uc_mcontext.gregs[REG_RBX]  = pregs->rbx;
+    pcontext->uc_mcontext.gregs[REG_RCX]  = pregs->rcx;
+    pcontext->uc_mcontext.gregs[REG_RDX]  = pregs->rdx;
+    pcontext->uc_mcontext.gregs[REG_RSP]  = pregs->rsp;
+    pcontext->uc_mcontext.gregs[REG_RBP]  = pregs->rbp;
+    pcontext->uc_mcontext.gregs[REG_RSI]  = pregs->rsi;
+    pcontext->uc_mcontext.gregs[REG_RDI]  = pregs->rdi;
+    pcontext->uc_mcontext.gregs[REG_R8]   = pregs->r8;
+    pcontext->uc_mcontext.gregs[REG_R9]   = pregs->r9;
+    pcontext->uc_mcontext.gregs[REG_R10]  = pregs->r10;
+    pcontext->uc_mcontext.gregs[REG_R11]  = pregs->r11;
+    pcontext->uc_mcontext.gregs[REG_R12]  = pregs->r12;
+    pcontext->uc_mcontext.gregs[REG_R13]  = pregs->r13;
+    pcontext->uc_mcontext.gregs[REG_R14]  = pregs->r14;
+    pcontext->uc_mcontext.gregs[REG_R15]  = pregs->r15;
+    ((uint16*)&pcontext->uc_mcontext.gregs[REG_CSGSFS])[2] = pregs->fs;
+    ((uint16*)&pcontext->uc_mcontext.gregs[REG_CSGSFS])[1]  = pregs->gs;
+    // ss register is not restored, because there is no storage for it
+    ((uint16*)&pcontext->uc_mcontext.gregs[REG_CSGSFS])[0]  = pregs->cs;
+    pcontext->uc_mcontext.gregs[REG_RIP]  = pregs->rip;
+    pcontext->uc_mcontext.gregs[REG_EFL]  = pregs->eflags;
+}
+
+#else // #ifdef PLATFORM_POSIX
+
+static void ncai_context_to_registers(CONTEXT* pcontext, NcaiRegisters* pregs)
+{
+    pregs->rax    = pcontext->Rax;
+    pregs->rbx    = pcontext->Rbx;
+    pregs->rcx    = pcontext->Rcx;
+    pregs->rdx    = pcontext->Rdx;
+    pregs->rsp    = pcontext->Rsp;
+    pregs->rbp    = pcontext->Rbp;
+    pregs->rsi    = pcontext->Rsi;
+    pregs->rdi    = pcontext->Rdi;
+    pregs->r8     = pcontext->R8;
+    pregs->r9     = pcontext->R9;
+    pregs->r10    = pcontext->R10;
+    pregs->r11    = pcontext->R11;
+    pregs->r12    = pcontext->R12;
+    pregs->r13    = pcontext->R13;
+    pregs->r14    = pcontext->R14;
+    pregs->r15    = pcontext->R15;
+    pregs->ds     = pcontext->SegDs;
+    pregs->es     = pcontext->SegEs;
+    pregs->fs     = pcontext->SegFs;
+    pregs->gs     = pcontext->SegGs;
+    pregs->ss     = pcontext->SegSs;
+    pregs->cs     = pcontext->SegCs;
+    pregs->rip    = pcontext->Rip;
+    pregs->eflags = pcontext->EFlags;
+}
+
+static void ncai_registers_to_context(NcaiRegisters* pregs, CONTEXT* pcontext)
+{
+    pcontext->Rax     = pregs->rax;
+    pcontext->Rbx     = pregs->rbx;
+    pcontext->Rcx     = pregs->rcx;
+    pcontext->Rdx     = pregs->rdx;
+    pcontext->Rsp     = pregs->rsp;
+    pcontext->Rbp     = pregs->rbp;
+    pcontext->Rsi     = pregs->rsi;
+    pcontext->Rdi     = pregs->rdi;
+    pcontext->R8      = pregs->r8;
+    pcontext->R9      = pregs->r9;
+    pcontext->R10     = pregs->r10;
+    pcontext->R11     = pregs->r11;
+    pcontext->R12     = pregs->r12;
+    pcontext->R13     = pregs->r13;
+    pcontext->R14     = pregs->r14;
+    pcontext->R15     = pregs->r15;
+    pcontext->SegDs   = pregs->ds;
+    pcontext->SegEs   = pregs->es;
+    pcontext->SegFs   = pregs->fs;
+    pcontext->SegGs   = pregs->gs;
+    pcontext->SegSs   = pregs->ss;
+    pcontext->SegCs   = pregs->cs;
+    pcontext->Rip     = pregs->rip;
+    pcontext->EFlags  = pregs->eflags;
+}
+
+#endif // #ifdef PLATFORM_POSIX
+
+bool ncai_get_register_value(hythread_t thread, jint reg_number, void* buf_ptr)
+{
+    os_thread_context_t context;
+    IDATA status = hythread_get_thread_context(thread, &context);
+
+    if (status != TM_ERROR_NONE)
+        return false;
+
+    NcaiRegisters regs;
+    ncai_context_to_registers(&context, &regs);
+
+    memcpy(
+        buf_ptr,
+        ((uint8*)&regs) + g_ncai_reg_table[reg_number].offset,
+        g_ncai_reg_table[reg_number].size);
+
+    return true;
+}
+
+bool ncai_set_register_value(hythread_t thread, jint reg_number, void* buf_ptr)
+{
+    os_thread_context_t context;
+    IDATA status = hythread_get_thread_context(thread, &context);
+
+    if (status != TM_ERROR_NONE)
+        return false;
+
+    NcaiRegisters regs;
+    ncai_context_to_registers(&context, &regs);
+
+    memcpy(
+        ((uint8*)&regs) + g_ncai_reg_table[reg_number].offset,
+        buf_ptr,
+        g_ncai_reg_table[reg_number].size);
+
+    ncai_registers_to_context(&regs, &context);
+
+    status = hythread_set_thread_context(thread, &context);
+
+    return (status == TM_ERROR_NONE);
+}
+
+void* ncai_get_instruction_pointer(hythread_t thread)
+{
+    os_thread_context_t context;
+    IDATA status = hythread_get_thread_context(thread, &context);
+
+    if (status != TM_ERROR_NONE)
+        return NULL;
+
+    NcaiRegisters regs;
+    ncai_context_to_registers(&context, &regs);
+
+    return (void*)regs.rip;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_em64t.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ia32.cpp?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ia32.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ia32.cpp Wed Nov 21 08:29:40 2007
@@ -0,0 +1,208 @@
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+
+#include <open/types.h>
+//#include "m2n.h"
+//#include "m2n_ia32_internal.h"
+#include <open/ncai_thread.h>
+#include "jit_export_rt.h"
+#include "method_lookup.h"
+
+#include "ncai_internal.h"
+
+
+struct NcaiRegisters
+{
+    uint32  eax;
+    uint32  ebx;
+    uint32  ecx;
+    uint32  edx;
+    uint32  esp;
+    uint32  ebp;
+    uint32  esi;
+    uint32  edi;
+    uint16  ds;
+    uint16  es;
+    uint16  fs;
+    uint16  gs;
+    uint16  ss;
+    uint16  cs;
+    uint32  eip;
+    uint32  eflags;
+};
+
+#define REGSIZE(_field_) ((jint)sizeof(((NcaiRegisters*)0)->_field_))
+#define REGOFF(_field_) ((POINTER_SIZE_INT)&(((NcaiRegisters*)0)->_field_))
+
+NcaiRegisterTableItem g_ncai_reg_table[] = {
+    {"eax",     REGSIZE(eax),   REGOFF(eax)   },
+    {"ebx",     REGSIZE(ebx),   REGOFF(ebx)   },
+    {"ecx",     REGSIZE(ecx),   REGOFF(ecx)   },
+    {"edx",     REGSIZE(edx),   REGOFF(edx)   },
+    {"esp",     REGSIZE(esp),   REGOFF(esp)   },
+    {"ebp",     REGSIZE(ebp),   REGOFF(ebp)   },
+    {"esi",     REGSIZE(esi),   REGOFF(esi)   },
+    {"edi",     REGSIZE(edi),   REGOFF(edi)   },
+    {"ds",      REGSIZE(ds),    REGOFF(ds)    },
+    {"es",      REGSIZE(es),    REGOFF(es)    },
+    {"fs",      REGSIZE(fs),    REGOFF(fs)    },
+    {"gs",      REGSIZE(gs),    REGOFF(gs)    },
+    {"ss",      REGSIZE(ss),    REGOFF(ss)    },
+    {"cs",      REGSIZE(cs),    REGOFF(cs)    },
+    {"eip",     REGSIZE(eip),   REGOFF(eip)   },
+    {"eflags",  REGSIZE(eflags),REGOFF(eflags)},
+};
+
+size_t ncai_get_reg_table_size()
+{
+    return sizeof(g_ncai_reg_table)/sizeof(g_ncai_reg_table[0]);
+}
+
+#ifdef PLATFORM_POSIX
+
+static void ncai_context_to_registers(ucontext_t* pcontext, NcaiRegisters* pregs)
+{
+    pregs->eax  = pcontext->uc_mcontext.gregs[REG_EAX];
+    pregs->ebx  = pcontext->uc_mcontext.gregs[REG_EBX];
+    pregs->ecx  = pcontext->uc_mcontext.gregs[REG_ECX];
+    pregs->edx  = pcontext->uc_mcontext.gregs[REG_EDX];
+    pregs->esp  = pcontext->uc_mcontext.gregs[REG_ESP];
+    pregs->ebp  = pcontext->uc_mcontext.gregs[REG_EBP];
+    pregs->esi  = pcontext->uc_mcontext.gregs[REG_ESI];
+    pregs->edi  = pcontext->uc_mcontext.gregs[REG_EDI];
+    pregs->ds = pcontext->uc_mcontext.gregs[REG_DS];
+    pregs->es = pcontext->uc_mcontext.gregs[REG_ES];
+    pregs->fs = pcontext->uc_mcontext.gregs[REG_FS];
+    pregs->gs = pcontext->uc_mcontext.gregs[REG_GS];
+    pregs->ss = pcontext->uc_mcontext.gregs[REG_SS];
+    pregs->cs = pcontext->uc_mcontext.gregs[REG_CS];
+    pregs->eip    = pcontext->uc_mcontext.gregs[REG_EIP];
+    pregs->eflags = pcontext->uc_mcontext.gregs[REG_EFL];
+}
+
+static void ncai_registers_to_context(NcaiRegisters* pregs, ucontext_t* pcontext)
+{
+    pcontext->uc_mcontext.gregs[REG_EAX]  = pregs->eax;
+    pcontext->uc_mcontext.gregs[REG_EBX]  = pregs->ebx;
+    pcontext->uc_mcontext.gregs[REG_ECX]  = pregs->ecx;
+    pcontext->uc_mcontext.gregs[REG_EDX]  = pregs->edx;
+    pcontext->uc_mcontext.gregs[REG_ESP]  = pregs->esp;
+    pcontext->uc_mcontext.gregs[REG_EBP]  = pregs->ebp;
+    pcontext->uc_mcontext.gregs[REG_ESI]  = pregs->esi;
+    pcontext->uc_mcontext.gregs[REG_EDI]  = pregs->edi;
+    pcontext->uc_mcontext.gregs[REG_DS] = pregs->ds;
+    pcontext->uc_mcontext.gregs[REG_ES] = pregs->es;
+    pcontext->uc_mcontext.gregs[REG_FS] = pregs->fs;
+    pcontext->uc_mcontext.gregs[REG_GS] = pregs->gs;
+    pcontext->uc_mcontext.gregs[REG_SS] = pregs->ss;
+    pcontext->uc_mcontext.gregs[REG_CS] = pregs->cs;
+    pcontext->uc_mcontext.gregs[REG_EIP]  = pregs->eip;
+    pcontext->uc_mcontext.gregs[REG_EFL]  = pregs->eflags;
+}
+
+#else // #ifdef PLATFORM_POSIX
+
+#ifndef __INTEL_COMPILER
+//4244 - conversion from 'int' to 'unsigned short', possible loss of data
+    #pragma warning (disable:4244)
+#endif
+
+static void ncai_context_to_registers(CONTEXT* pcontext, NcaiRegisters* pregs)
+{
+    pregs->eax    = pcontext->Eax;
+    pregs->ebx    = pcontext->Ebx;
+    pregs->ecx    = pcontext->Ecx;
+    pregs->edx    = pcontext->Edx;
+    pregs->esp    = pcontext->Esp;
+    pregs->ebp    = pcontext->Ebp;
+    pregs->esi    = pcontext->Esi;
+    pregs->edi    = pcontext->Edi;
+    pregs->ds     = pcontext->SegDs;
+    pregs->es     = pcontext->SegEs;
+    pregs->fs     = pcontext->SegFs;
+    pregs->gs     = pcontext->SegGs;
+    pregs->ss     = pcontext->SegSs;
+    pregs->cs     = pcontext->SegCs;
+    pregs->eip    = pcontext->Eip;
+    pregs->eflags = pcontext->EFlags;
+}
+
+static void ncai_registers_to_context(NcaiRegisters* pregs, CONTEXT* pcontext)
+{
+    pcontext->Eax     = pregs->eax;
+    pcontext->Ebx     = pregs->ebx;
+    pcontext->Ecx     = pregs->ecx;
+    pcontext->Edx     = pregs->edx;
+    pcontext->Esp     = pregs->esp;
+    pcontext->Ebp     = pregs->ebp;
+    pcontext->Esi     = pregs->esi;
+    pcontext->Edi     = pregs->edi;
+    pcontext->SegDs   = pregs->ds;
+    pcontext->SegEs   = pregs->es;
+    pcontext->SegFs   = pregs->fs;
+    pcontext->SegGs   = pregs->gs;
+    pcontext->SegSs   = pregs->ss;
+    pcontext->SegCs   = pregs->cs;
+    pcontext->Eip     = pregs->eip;
+    pcontext->EFlags  = pregs->eflags;
+}
+
+#endif // #ifdef PLATFORM_POSIX
+
+bool ncai_get_register_value(hythread_t thread, jint reg_number, void* buf_ptr)
+{
+    os_thread_context_t context;
+    IDATA status = hythread_get_thread_context(thread, &context);
+
+    if (status != TM_ERROR_NONE)
+        return false;
+
+    NcaiRegisters regs;
+    ncai_context_to_registers(&context, &regs);
+
+    memcpy(
+        buf_ptr,
+        ((uint8*)&regs) + g_ncai_reg_table[reg_number].offset,
+        g_ncai_reg_table[reg_number].size);
+
+    return true;
+}
+
+bool ncai_set_register_value(hythread_t thread, jint reg_number, void* buf_ptr)
+{
+    os_thread_context_t context;
+    IDATA status = hythread_get_thread_context(thread, &context);
+
+    if (status != TM_ERROR_NONE)
+        return false;
+
+    NcaiRegisters regs;
+    ncai_context_to_registers(&context, &regs);
+
+    memcpy(
+        ((uint8*)&regs) + g_ncai_reg_table[reg_number].offset,
+        buf_ptr,
+        g_ncai_reg_table[reg_number].size);
+
+    ncai_registers_to_context(&regs, &context);
+
+    status = hythread_set_thread_context(thread, &context);
+
+    return (status == TM_ERROR_NONE);
+}
+
+void* ncai_get_instruction_pointer(hythread_t thread)
+{
+    os_thread_context_t context;
+    IDATA status = hythread_get_thread_context(thread, &context);
+
+    if (status != TM_ERROR_NONE)
+        return NULL;
+
+    NcaiRegisters regs;
+    ncai_context_to_registers(&context, &regs);
+
+    return (void*)regs.eip;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ia32.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ipf.cpp?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ipf.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ipf.cpp Wed Nov 21 08:29:40 2007
@@ -0,0 +1,258 @@
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+
+#include "open/types.h"
+#include <open/ncai_thread.h>
+
+#include "ncai_internal.h"
+
+
+struct NcaiRegisters
+{
+    // General registers
+    union
+    {
+        uint64  gr[32];
+        struct
+        {
+            uint64  gr0;
+            uint64  gr1;
+            uint64  gr2;
+            uint64  gr3;
+            uint64  gr4;
+            uint64  gr5;
+            uint64  gr6;
+            uint64  gr7;
+            uint64  gr8;
+            uint64  gr9;
+            uint64  gr10;
+            uint64  gr11;
+            uint64  gr12;
+            uint64  gr13;
+            uint64  gr14;
+            uint64  gr15;
+            uint64  gr16;
+            uint64  gr17;
+            uint64  gr18;
+            uint64  gr19;
+            uint64  gr20;
+            uint64  gr21;
+            uint64  gr22;
+            uint64  gr23;
+            uint64  gr24;
+            uint64  gr25;
+            uint64  gr26;
+            uint64  gr27;
+            uint64  gr28;
+            uint64  gr29;
+            uint64  gr30;
+            uint64  gr31;
+        };
+    };
+    // Branch registers
+    union
+    {
+        uint64  br[8];
+        struct
+        {
+            uint64  br0;
+            uint64  br1;
+            uint64  br2;
+            uint64  br3;
+            uint64  br4;
+            uint64  br5;
+            uint64  br6;
+            uint64  br7;
+        };
+    };
+    // Application registers
+    uint64  RSC;        // ar16
+    uint64  BSP;        // ar17
+//    uint64  BSPSTORE;   // ar18
+    uint64  RNAT;       // ar19
+//    uint64  FCR;        // ar21
+//    uint64  EFLAGS;     // ar24
+//    uint64  CSD;        // ar25
+//    uint64  SSD;        // ar26
+//    uint64  CFLG;       // ar27
+//    uint64  FSR;        // ar28
+//    uint64  FIR;        // ar29
+//    uint64  FDR;        // ar30
+    uint64  CCV;        // ar32
+    uint64  UNAT;       // ar36
+    uint64  FPSR;       // ar40
+//    uint64  ITC;        // ar44
+    uint64  PFS;        // ar64
+    uint64  LC;         // ar65
+//    uint64  EC;         // ar66
+
+    uint64  IP;         // Instruction pointer
+    uint64  CFM;        // Current frame marker (38 bits)
+};
+
+#define REGSIZE(_field_) ((jint)sizeof(((NcaiRegisters*)0)->_field_))
+#define REGOFF(_field_) ((POINTER_SIZE_INT)&(((NcaiRegisters*)0)->_field_))
+
+NcaiRegisterTableItem g_ncai_reg_table[] = {
+    {"gr0",     REGSIZE(gr0),   REGOFF(gr0)   },
+    {"gr1",     REGSIZE(gr1),   REGOFF(gr1)   },
+    {"gr2",     REGSIZE(gr2),   REGOFF(gr2)   },
+    {"gr3",     REGSIZE(gr3),   REGOFF(gr3)   },
+    {"gr4",     REGSIZE(gr4),   REGOFF(gr4)   },
+    {"gr5",     REGSIZE(gr5),   REGOFF(gr5)   },
+    {"gr6",     REGSIZE(gr6),   REGOFF(gr6)   },
+    {"gr7",     REGSIZE(gr7),   REGOFF(gr7)   },
+    {"gr8",     REGSIZE(gr8),   REGOFF(gr8)   },
+    {"gr9",     REGSIZE(gr9),   REGOFF(gr9)   },
+    {"gr10",    REGSIZE(gr10),  REGOFF(gr10)  },
+    {"gr11",    REGSIZE(gr11),  REGOFF(gr11)  },
+    {"gr12",    REGSIZE(gr12),  REGOFF(gr12)  },
+    {"gr13",    REGSIZE(gr13),  REGOFF(gr13)  },
+    {"gr14",    REGSIZE(gr14),  REGOFF(gr14)  },
+    {"gr15",    REGSIZE(gr15),  REGOFF(gr15)  },
+    {"gr16",    REGSIZE(gr16),  REGOFF(gr16)  },
+    {"gr17",    REGSIZE(gr17),  REGOFF(gr17)  },
+    {"gr18",    REGSIZE(gr18),  REGOFF(gr18)  },
+    {"gr19",    REGSIZE(gr19),  REGOFF(gr19)  },
+    {"gr20",    REGSIZE(gr20),  REGOFF(gr20)  },
+    {"gr21",    REGSIZE(gr21),  REGOFF(gr21)  },
+    {"gr22",    REGSIZE(gr22),  REGOFF(gr22)  },
+    {"gr23",    REGSIZE(gr23),  REGOFF(gr23)  },
+    {"gr24",    REGSIZE(gr24),  REGOFF(gr24)  },
+    {"gr25",    REGSIZE(gr25),  REGOFF(gr25)  },
+    {"gr26",    REGSIZE(gr26),  REGOFF(gr26)  },
+    {"gr27",    REGSIZE(gr27),  REGOFF(gr27)  },
+    {"gr28",    REGSIZE(gr28),  REGOFF(gr28)  },
+    {"gr29",    REGSIZE(gr29),  REGOFF(gr29)  },
+    {"gr30",    REGSIZE(gr30),  REGOFF(gr30)  },
+    {"gr31",    REGSIZE(gr31),  REGOFF(gr31)  },
+    {"br0",     REGSIZE(br0),   REGOFF(br0)   },
+    {"br1",     REGSIZE(br1),   REGOFF(br1)   },
+    {"br2",     REGSIZE(br2),   REGOFF(br2)   },
+    {"br3",     REGSIZE(br3),   REGOFF(br3)   },
+    {"br4",     REGSIZE(br4),   REGOFF(br4)   },
+    {"br5",     REGSIZE(br5),   REGOFF(br5)   },
+    {"br6",     REGSIZE(br6),   REGOFF(br6)   },
+    {"br7",     REGSIZE(br7),   REGOFF(br7)   },
+
+    {"RSC",     REGSIZE(RSC),     REGOFF(RSC)     },
+    {"BSP",     REGSIZE(BSP),     REGOFF(BSP)     },
+//    {"BSPSTORE",REGSIZE(BSPSTORE),REGOFF(BSPSTORE)},
+    {"RNAT",    REGSIZE(RNAT),    REGOFF(RNAT)    },
+//    {"FCR",     REGSIZE(FCR),     REGOFF(FCR)     },
+//    {"EFLAGS",  REGSIZE(EFLAGS),  REGOFF(EFLAGS)  },
+//    {"CSD",     REGSIZE(CSD),     REGOFF(CSD)     },
+//    {"SSD",     REGSIZE(SSD),     REGOFF(SSD)     },
+//    {"CFLG",    REGSIZE(CFLG),    REGOFF(CFLG)    },
+//    {"FSR",     REGSIZE(FSR),     REGOFF(FSR)     },
+//    {"FIR",     REGSIZE(FIR),     REGOFF(FIR)     },
+//    {"FDR",     REGSIZE(FDR),     REGOFF(FDR)     },
+    {"CCV",     REGSIZE(CCV),     REGOFF(CCV)     },
+    {"UNAT",    REGSIZE(UNAT),    REGOFF(UNAT)    },
+    {"FPSR",    REGSIZE(FPSR),    REGOFF(FPSR)    },
+//    {"ITC",     REGSIZE(ITC),     REGOFF(ITC)     },
+    {"PFS",     REGSIZE(PFS),     REGOFF(PFS)     },
+    {"LC",      REGSIZE(LC),      REGOFF(LC)      },
+//    {"EC",      REGSIZE(EC),      REGOFF(EC)      },
+
+    {"IP",      REGSIZE(IP),      REGOFF(IP)      },
+    {"CFM",     REGSIZE(CFM),     REGOFF(CFM)     }
+};
+
+size_t ncai_get_reg_table_size()
+{
+    return sizeof(g_ncai_reg_table)/sizeof(g_ncai_reg_table[0]);
+}
+
+
+static void ncai_context_to_registers(ucontext_t* pcontext, NcaiRegisters* pregs)
+{
+    memcpy(&pregs->gr, &pcontext->uc_mcontext.sc_gr, sizeof(pregs->gr));
+    memcpy(&pregs->br, &pcontext->uc_mcontext.sc_br, sizeof(pregs->br));
+
+    pregs->RSC  = pcontext->uc_mcontext.sc_ar_rsc;
+    pregs->BSP  = pcontext->uc_mcontext.sc_ar_bsp;
+    pregs->RNAT = pcontext->uc_mcontext.sc_ar_rnat;
+    pregs->CCV  = pcontext->uc_mcontext.sc_ar_ccv;
+    pregs->UNAT = pcontext->uc_mcontext.sc_ar_unat;
+    pregs->FPSR = pcontext->uc_mcontext.sc_ar_fpsr;
+    pregs->PFS  = pcontext->uc_mcontext.sc_ar_pfs;
+    pregs->LC   = pcontext->uc_mcontext.sc_ar_lc;
+    pregs->IP   = pcontext->uc_mcontext.sc_ip;
+    pregs->CFM  = pcontext->uc_mcontext.sc_cfm;
+}
+
+static void ncai_registers_to_context(NcaiRegisters* pregs, ucontext_t* pcontext)
+{
+    memcpy(&pcontext->uc_mcontext.sc_gr, &pregs->gr, sizeof(pcontext->uc_mcontext.sc_gr));
+    memcpy(&pcontext->uc_mcontext.sc_br, &pregs->br, sizeof(pcontext->uc_mcontext.sc_br));
+
+    pcontext->uc_mcontext.sc_ar_rsc  = pregs->RSC;
+    pcontext->uc_mcontext.sc_ar_bsp  = pregs->BSP;
+    pcontext->uc_mcontext.sc_ar_rnat = pregs->RNAT;
+    pcontext->uc_mcontext.sc_ar_ccv  = pregs->CCV;
+    pcontext->uc_mcontext.sc_ar_unat = pregs->UNAT;
+    pcontext->uc_mcontext.sc_ar_fpsr = pregs->FPSR;
+    pcontext->uc_mcontext.sc_ar_pfs  = pregs->PFS;
+    pcontext->uc_mcontext.sc_ar_lc   = pregs->LC;
+    pcontext->uc_mcontext.sc_ip      = pregs->IP;
+    pcontext->uc_mcontext.sc_cfm     = pregs->CFM;
+}
+
+bool ncai_get_register_value(hythread_t thread, jint reg_number, void* buf_ptr)
+{
+    os_thread_context_t context;
+    IDATA status = hythread_get_thread_context(thread, &context);
+
+    if (status != TM_ERROR_NONE)
+        return false;
+
+    NcaiRegisters regs;
+    ncai_context_to_registers(&context, &regs);
+
+    memcpy(
+        buf_ptr,
+        ((uint8*)&regs) + g_ncai_reg_table[reg_number].offset,
+        g_ncai_reg_table[reg_number].size);
+
+    return true;
+}
+
+bool ncai_set_register_value(hythread_t thread, jint reg_number, void* buf_ptr)
+{
+    os_thread_context_t context;
+    IDATA status = hythread_get_thread_context(thread, &context);
+
+    if (status != TM_ERROR_NONE)
+        return false;
+
+    NcaiRegisters regs;
+    ncai_context_to_registers(&context, &regs);
+
+    memcpy(
+        ((uint8*)&regs) + g_ncai_reg_table[reg_number].offset,
+        buf_ptr,
+        g_ncai_reg_table[reg_number].size);
+
+    ncai_registers_to_context(&regs, &context);
+
+    status = hythread_set_thread_context(thread, &context);
+
+    return (status == TM_ERROR_NONE);
+}
+
+void* ncai_get_instruction_pointer(hythread_t thread)
+{
+    os_thread_context_t context;
+    IDATA status = hythread_get_thread_context(thread, &context);
+
+    if (status != TM_ERROR_NONE)
+        return NULL;
+
+    NcaiRegisters regs;
+    ncai_context_to_registers(&context, &regs);
+
+    return (void*)regs.IP;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ipf.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_linux.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_linux.cpp?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_linux.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_linux.cpp Wed Nov 21 08:29:40 2007
@@ -0,0 +1,25 @@
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+
+#include "open/ncai_thread.h"
+#include "ncai_internal.h"
+
+void linux_ucontext_to_regs(Registers* regs, ucontext_t *uc);
+void linux_regs_to_ucontext(ucontext_t *uc, Registers* regs);
+
+bool ncai_get_generic_registers(hythread_t thread, Registers* regs)
+{
+    if (regs == NULL)
+        return false;
+
+    ucontext_t uc;
+    IDATA status = hythread_get_thread_context(thread, &uc);
+
+    if (status != TM_ERROR_NONE)
+        return false;
+
+    linux_ucontext_to_regs(regs, &uc);
+    return true;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_linux.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_win.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_win.cpp?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_win.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_win.cpp Wed Nov 21 08:29:40 2007
@@ -0,0 +1,26 @@
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+
+#include "open/ncai_thread.h"
+#include "ncai_internal.h"
+
+void nt_to_vm_context(PCONTEXT pcontext, Registers* regs);
+void vm_to_nt_context(Registers* regs, PCONTEXT pcontext);
+
+bool ncai_get_generic_registers(hythread_t thread, Registers* regs)
+{
+    if (regs == NULL)
+        return false;
+
+    CONTEXT context;
+    context.ContextFlags = CONTEXT_FULL; // CONTEXT_ALL
+    IDATA status = hythread_get_thread_context(thread, &context);
+
+    if (status != TM_ERROR_NONE)
+        return false;
+
+    nt_to_vm_context(&context, regs);
+    return true;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_win.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp Wed Nov 21 08:29:40 2007
@@ -577,6 +577,18 @@
 void null_java_reference_handler(int signum, siginfo_t* UNREF info, void* context)
 { 
     ucontext_t *uc = (ucontext_t *)context;
+    VM_thread *vm_thread = p_TLS_vmthread;
+    Registers regs;
+    UCONTEXT_TO_REGS(&regs, uc);
+
+    if (vm_thread && vm_thread->jvmti_thread.violation_flag)
+    {
+        vm_thread->jvmti_thread.violation_flag = 0;
+        regs.set_ip(vm_thread->jvmti_thread.violation_restart_address);
+        linux_regs_to_ucontext(uc, &regs);
+        return;
+    }
+
     Global_Env *env = VM_Global_State::loader_env;
 
     TRACE2("signals", "NPE or SOE detected at " << (void*)REGISTER_EIP);
@@ -593,8 +605,6 @@
         }
     }
     fprintf(stderr, "SIGSEGV in VM code.\n");
-    Registers regs;
-    UCONTEXT_TO_REGS(&regs, uc);
 
     // setup default handler
     signal(signum, SIG_DFL);
@@ -646,7 +656,6 @@
     UCONTEXT_TO_REGS(&regs, uc);
     TRACE2("signals", "JVMTI breakpoint detected at " <<
         (void *)regs.eip);
-    assert(!interpreter_enabled());
 
     bool handled = jvmti_jit_breakpoint_handler(&regs);
     if (handled)
@@ -695,14 +704,17 @@
     bool replaced = false;
     ucontext_t* uc = (ucontext_t *)context;
     uint32 saved_eip = (uint32)REGISTER_EIP;
-    uint32 new_eip = 0;
+    uint32 new_eip = saved_eip;
+    VM_thread* vm_thread = p_TLS_vmthread;
+    bool violation =
+        (signum == SIGSEGV) && vm_thread && vm_thread->jvmti_thread.violation_flag;
 
     // If exception is occured in processor instruction previously
     // instrumented by breakpoint, the actual exception address will reside
     // in jvmti_jit_breakpoints_handling_buffer
     // We should replace exception address with saved address of instruction
     uint32 break_buf =
-        (uint32)p_TLS_vmthread->jvmti_thread.jvmti_jit_breakpoints_handling_buffer;
+        (uint32)vm_thread->jvmti_thread.jvmti_jit_breakpoints_handling_buffer;
     if (saved_eip >= break_buf &&
         saved_eip < break_buf + TM_JVMTI_MAX_BUFFER_SIZE)
     {
@@ -710,10 +722,18 @@
         assert(signum != SIGTRAP);
 
         replaced = true;
-        new_eip = (uint32)vm_get_ip_from_regs(p_TLS_vmthread);
+        new_eip = (uint32)vm_get_ip_from_regs(vm_thread);
         REGISTER_EIP = new_eip;
     }
 
+    // Pass exception to NCAI exception handler
+    bool is_handled = 0;
+    bool is_internal = (signum == SIGTRAP) || violation;
+    ncai_process_signal_event((NativeCodePtr)uc->uc_mcontext.gregs[REG_EIP],
+        (jint)signum, is_internal, &is_handled);
+    if (is_handled)
+        return;
+
     switch (signum)
     {
     case SIGTRAP:
@@ -728,6 +748,12 @@
     case SIGABRT:
         abort_handler(signum, info, context);
         break;
+    case SIGINT:
+        vm_interrupt_handler(signum);
+        break;
+    case SIGQUIT:
+        vm_dump_handler(signum);
+        break;
     default:
         // Unknown signal
         assert(0);
@@ -762,8 +788,15 @@
     sa.sa_sigaction = &general_signal_handler;
     sigaction(SIGFPE, &sa, NULL);
 
-    signal(SIGINT, (void (*)(int)) vm_interrupt_handler);
-    signal(SIGQUIT, (void (*)(int)) vm_dump_handler);
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_SIGINFO;
+    sa.sa_sigaction = &general_signal_handler;
+    sigaction(SIGINT, &sa, NULL);
+
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_SIGINFO;
+    sa.sa_sigaction = &general_signal_handler;
+    sigaction(SIGQUIT, &sa, NULL);
 
     /* install abort_handler to print out call stack on assertion failures */
     sigemptyset(&sa.sa_mask);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp Wed Nov 21 08:29:40 2007
@@ -147,9 +147,15 @@
     if (code_type == VM_TYPE_JAVA)
     { // We must add dummy M2N frame to start SI iteration
         assert(pthread);
-        m2n_push_suspended_frame(pthread, pregs);
-        flag_dummy_frame = true;
         is_java = true;
+
+        M2nFrame* lm2n = m2n_get_last_frame(pthread);
+
+        if (!m2n_is_suspended_frame(lm2n) || m2n_get_ip(lm2n) != ip)
+        { // We should not push frame if it was pushed by breakpoint handler
+            m2n_push_suspended_frame(pthread, pregs);
+            flag_dummy_frame = true;
+        }
     }
 
     si = si_create_from_native(pthread);
@@ -358,6 +364,9 @@
         // Simply bp-based frame, let's unwind it
         if (native_is_frame_valid(modules, bp, sp))
         {
+            // Here must be special processing for breakpoint handler frames
+            // But it requires VM_thread structure attached to thread
+            // TODO: Investigate possibility
             native_unwind_bp_based_frame(bp, &ip, &bp, &sp);
         }
         else
@@ -423,7 +432,24 @@
 
         if (native_is_frame_valid(modules, bp, sp))
         { // Simply bp-based frame, let's unwind it
-            native_unwind_bp_based_frame(bp, &ip, &bp, &sp);
+            void *tmp_ip, *tmp_bp, *tmp_sp;
+            native_unwind_bp_based_frame(bp, &tmp_ip, &tmp_bp, &tmp_sp);
+
+            VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
+            vm_breaks->lock();
+
+            if (native_is_ip_in_breakpoint_handler(tmp_ip))
+            {
+                native_unwind_interrupted_frame(&pthread->jvmti_thread, &ip, &bp, &sp);
+            }
+            else
+            {
+                ip = tmp_ip;
+                bp = tmp_bp;
+                sp = tmp_sp;
+            }
+
+            vm_breaks->unlock();
         }
         else
         { // Is not bp-based frame

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/natives_support.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/natives_support.cpp?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/natives_support.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/natives_support.cpp Wed Nov 21 08:29:40 2007
@@ -34,6 +34,7 @@
 #include "lock_manager.h"
 #include "jni_direct.h" // FIXME ???? Can we use it here ????
 #include "open/vm_util.h"
+#include "port_filepath.h"
 
 #include "jni_types.h"
 #include "jni_utils.h"
@@ -195,6 +196,9 @@
     return newCopy;
 }
 
+void ncai_library_load_callback(const char* name);
+void ncai_library_unload_callback(const char* name);
+
 // Function loads native library with a given name.
 NativeLibraryHandle
 natives_load_library(const char* library_name, bool* just_loaded,
@@ -282,6 +286,8 @@
     pinfo->next = jni_libs.lib_info_list;
     jni_libs.lib_info_list = pinfo;
 
+    ncai_library_load_callback(localLibName);
+
     jni_libs.lock._unlock();
 
     res = find_call_JNI_OnLoad(pinfo->handle); // What to do with result???
@@ -289,7 +295,7 @@
     *pstatus = APR_SUCCESS;
 
     returnCode = pinfo->handle;
-    
+
 NATIVES_LOAD_LIBRARY_EXIT :
 
 #ifdef PLATFORM_NT
@@ -330,6 +336,7 @@
             } else {
                 prev->next = lib->next;
             }
+            ncai_library_unload_callback(lib->name->bytes);
             natives_unload_library_internal(lib);
             jni_libs.lock._unlock();
             return;
@@ -708,3 +715,82 @@
 {
     apr_strerror(error, buf, buflen);
 } // natives_describe_error
+
+
+#ifdef PLATFORM_NT
+// Converts to lower case within given buffer
+void lowercase_buf(char* name)
+{
+    assert(name != NULL);
+
+    for(; *name; name++)
+    {
+        if (isalpha(*name) && !islower(*name)) {
+            *name = tolower(*name);
+        }
+    }
+}
+#endif // #ifdef PLATFORM_NT
+
+// Fills provided buffer with short file name
+// Returns pointer to buffer or NULL if file name is too long
+char* short_name(const char* name, char* buf)
+{
+    assert(name != NULL && buf != NULL);
+
+    const char* filepointer = strrchr(name, '/');
+
+    if (!filepointer)
+        filepointer = strrchr(name, '\\');
+
+    if (filepointer)
+    {
+        if (strlen(filepointer + 1) > _MAX_PATH)
+            return NULL;
+
+        strcpy(buf, filepointer + 1);
+    }
+    else
+    {
+        if (strlen(name) > _MAX_PATH)
+            return NULL;
+
+        strcpy(buf, name);
+    }
+
+#ifdef PLATFORM_NT
+    lowercase_buf(buf);
+#endif
+    return buf;
+}
+
+// Checks if given library was loaded already
+// Method is stupid and slow but it works for full and partial names
+bool natives_is_library_loaded_slow(const char* libname)
+{
+    char src_buf[_MAX_PATH + 1], cmp_buf[_MAX_PATH + 1];
+
+    if (short_name(libname, src_buf) == NULL)
+        return false; // Error case
+
+    bool result = false;
+
+    jni_libs.lock._lock();
+
+    for(NativeLibraryList lib = jni_libs.lib_info_list;
+        lib; lib = lib->next)
+    {
+        if (short_name(lib->name->bytes, cmp_buf) == NULL)
+            break; // Error case
+
+        if (0 == strcmp(src_buf, cmp_buf))
+        {
+            result = true;
+            break;
+        }
+    }
+
+    jni_libs.lock._unlock();
+    return result;
+}
+

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp Wed Nov 21 08:29:40 2007
@@ -316,11 +316,22 @@
     //  - other (internal VM error or debugger breakpoint)
     //    => delegate to default handler
 
+    // Pass exception to NCAI exception handler
+    bool is_continuable =
+        (nt_exception->ExceptionRecord->ExceptionFlags != EXCEPTION_NONCONTINUABLE);
+    bool is_handled = !is_continuable;
+    bool is_internal = (code == JVMTI_EXCEPTION_STATUS);
+    ncai_process_signal_event((NativeCodePtr)regs.get_ip(),
+        (jint)code, is_internal, &is_handled);
+    if (is_continuable && is_handled)
+        return EXCEPTION_CONTINUE_EXECUTION;
+
     // delegate "other" cases to crash handler
     // Crash handler shouls be invoked when VM_thread is not attached to VM
     // or exception has occured in native code and it's not STACK_OVERFLOW
-    if (!vmthread ||
-        (!in_java && code != STATUS_STACK_OVERFLOW))
+    if ((!vmthread ||
+        (!in_java && code != STATUS_STACK_OVERFLOW)) &&
+        code != JVMTI_EXCEPTION_STATUS)
     {
         LONG result = process_crash(nt_exception);
         regs.set_ip((void*)saved_eip);
@@ -332,7 +343,8 @@
         nt_exception->ExceptionRecord->ExceptionCode, regs.get_ip(), regs_get_sp(&regs)));
 
     // if HWE occured in java code, suspension should also have been disabled
-    assert(!in_java || !hythread_is_suspend_enabled());
+    bool ncai_enabled = GlobalNCAI::isEnabled();
+    assert(!in_java || !hythread_is_suspend_enabled() || ncai_enabled);
 
     Global_Env *env = VM_Global_State::loader_env;
     // the actual exception object will be created lazily,



Mime
View raw message