harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gshiman...@apache.org
Subject svn commit: r584206 - in /harmony/enhanced/drlvm/trunk/vm/vmcore/src: jvmti/jvmti_break_intf.cpp util/linux/signals_em64t.cpp
Date Fri, 12 Oct 2007 17:20:15 GMT
Author: gshimansky
Date: Fri Oct 12 10:20:14 2007
New Revision: 584206

URL: http://svn.apache.org/viewvc?rev=584206&view=rev
Log:
All registers should be copied to/from system ucontext struct.
JVMTI breakpoints implemented for x86_64 Linux platform.


Modified:
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp?rev=584206&r1=584205&r2=584206&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp Fri Oct 12 10:20:14
2007
@@ -542,6 +542,35 @@
     assert(false);
 }
 
+static char *gen_push(char *code_addr, POINTER_SIZE_INT value)
+{
+#ifdef _IA32_
+    return push(code_addr, Imm_Opnd(size_32, value));
+#elif defined _EM64T_
+    int32 high = (int32)((uint32)(value >> 32));
+    int32 low = (int32)((uint32)value);
+    code_addr = alu(code_addr, sub_opc, rsp_opnd, Imm_Opnd(size_8, 8));
+    code_addr = mov(code_addr, M_Base_Opnd(rsp_reg, 4), Imm_Opnd(size_32, high), size_32);
+    return mov(code_addr, M_Base_Opnd(rsp_reg, 0), Imm_Opnd(size_32, low), size_32);
+#else
+    assert(0);
+    return NULL;
+#endif
+}
+
+static char *gen_jump(char *code_addr, char *target_addr)
+{
+#ifdef _IA32_
+    return jump(code_addr, target_addr);
+#elif defined _EM64T_
+    code_addr = gen_push(code_addr, (POINTER_SIZE_INT)target_addr);
+    return ret(code_addr);
+#else
+    assert(0);
+    return NULL;
+#endif
+}
+
 void
 VMBreakPoints::process_native_breakpoint()
 {
@@ -697,18 +726,17 @@
             instruction_length - 1);
 
         // Create JMP $next_instruction instruction in the execution buffer
-        jump((char *)instruction_buffer + instruction_length,
+        gen_jump((char *)instruction_buffer + instruction_length,
             next_instruction);
         break;
     }
     case InstructionDisassembler::RELATIVE_JUMP:
     {
-        jint instruction_length = idisasm.get_length_with_prefix();
         char *jump_target = (char *)idisasm.get_jump_target_address();
 
         // Create JMP to the absolute address which conditional jump
         // had in the execution buffer
-        jump((char *)instruction_buffer, jump_target);
+        gen_jump((char *)instruction_buffer, jump_target);
         break;
     }
     case InstructionDisassembler::RELATIVE_COND_JUMP:
@@ -726,11 +754,11 @@
         code = branch8(code, get_condition_code(jump_type), Imm_Opnd(size_8, 0));
         char *branch_address = code - 1;
 
-        code = jump(code, next_instruction);
+        code = gen_jump(code, next_instruction);
         jint offset = (jint)(code - branch_address - 1);
         *branch_address = offset;
 
-        jump(code, jump_target);
+        gen_jump(code, jump_target);
         break;
     }
     case InstructionDisassembler::RELATIVE_CALL:
@@ -740,20 +768,19 @@
         char *code = (char *)instruction_buffer;
 
         // Push "return address" to the $next_instruction
-        code = push(code, Imm_Opnd(size_platf, (POINTER_SIZE_INT)next_instruction));
+        code = gen_push(code, (POINTER_SIZE_INT)next_instruction);
 
         // Jump to the target address of the call instruction
-        jump(code, jump_target);
+        gen_jump(code, jump_target);
         break;
     }
     case InstructionDisassembler::INDIRECT_JUMP:
     {
-        jint instruction_length = idisasm.get_length_with_prefix();
         char *jump_target = (char *)idisasm.get_target_address_from_context(&regs);
 
         // Create JMP to the absolute address which conditional jump
         // had in the execution buffer
-        jump((char *)instruction_buffer, jump_target);
+        gen_jump((char *)instruction_buffer, jump_target);
         break;
     }
     case InstructionDisassembler::INDIRECT_CALL:
@@ -763,10 +790,10 @@
         char *code = (char *)instruction_buffer;
 
         // Push "return address" to the $next_instruction
-        code = push(code, Imm_Opnd(size_platf, (POINTER_SIZE_INT)next_instruction));
+        code = gen_push(code, (POINTER_SIZE_INT)next_instruction);
 
         // Jump to the target address of the call instruction
-        jump(code, jump_target);
+        gen_jump(code, jump_target);
         break;
     }
     }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp?rev=584206&r1=584205&r2=584206&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp Fri Oct 12 10:20:14
2007
@@ -81,6 +81,15 @@
     regs->rbp = uc->uc_mcontext.gregs[REG_RBP];
     regs->rip = uc->uc_mcontext.gregs[REG_RIP];
     regs->rsp = uc->uc_mcontext.gregs[REG_RSP];
+    regs->r8 = uc->uc_mcontext.gregs[REG_R8];
+    regs->r9 = uc->uc_mcontext.gregs[REG_R9];
+    regs->r10 = uc->uc_mcontext.gregs[REG_R10];
+    regs->r11 = uc->uc_mcontext.gregs[REG_R11];
+    regs->r12 = uc->uc_mcontext.gregs[REG_R12];
+    regs->r13 = uc->uc_mcontext.gregs[REG_R13];
+    regs->r14 = uc->uc_mcontext.gregs[REG_R14];
+    regs->r15 = uc->uc_mcontext.gregs[REG_R15];
+    regs->eflags = uc->uc_mcontext.gregs[REG_EFL];
 }
 
 void linux_regs_to_ucontext(ucontext_t *uc, Registers* regs)
@@ -94,6 +103,15 @@
     uc->uc_mcontext.gregs[REG_RBP] = regs->rbp;
     uc->uc_mcontext.gregs[REG_RIP] = regs->rip;
     uc->uc_mcontext.gregs[REG_RSP] = regs->rsp;
+    uc->uc_mcontext.gregs[REG_R8] = regs->r8;
+    uc->uc_mcontext.gregs[REG_R9] = regs->r9;
+    uc->uc_mcontext.gregs[REG_R10] = regs->r10;
+    uc->uc_mcontext.gregs[REG_R11] = regs->r11;
+    uc->uc_mcontext.gregs[REG_R12] = regs->r12;
+    uc->uc_mcontext.gregs[REG_R13] = regs->r13;
+    uc->uc_mcontext.gregs[REG_R14] = regs->r14;
+    uc->uc_mcontext.gregs[REG_R15] = regs->r15;
+    uc->uc_mcontext.gregs[REG_EFL] = regs->eflags;
 }
 
 // exception catch support for stack restore
@@ -536,14 +554,45 @@
     }
 }
 
+void jvmti_jit_breakpoint_handler(int signum, siginfo_t* UNREF info, void* context)
+{
+    ucontext_t *uc = (ucontext_t *)context;
+    Registers regs;
+
+    linux_ucontext_to_regs(&regs, uc);
+    TRACE2("signals", "JVMTI breakpoint detected at " <<
+        (void *)regs.rip);
+    assert(!interpreter_enabled());
+
+    bool handled = jvmti_jit_breakpoint_handler(&regs);
+    if (handled)
+    {
+        linux_regs_to_ucontext(uc, &regs);
+        return;
+    }
+
+    fprintf(stderr, "SIGTRAP in VM code.\n");
+    linux_ucontext_to_regs(&regs, uc);
+
+    // setup default handler
+    signal(signum, SIG_DFL);
+
+    if (!is_gdb_crash_handler_enabled() ||
+        !gdb_crash_handler())
+    {
+        // print stack trace
+        st_print_stack(&regs);
+    }
+}
+
 /**
  * Print out the call stack of the aborted thread.
  * @note call stacks may be used for debugging
  */
-void abort_handler (int signum, siginfo_t* info, void* context) {
+void abort_handler (int signum, siginfo_t* UNREF info, void* context) {
     fprintf(stderr, "SIGABRT in VM code.\n");
-    ucontext_t *uc = (ucontext_t *)context;
     Registers regs;
+    ucontext_t *uc = (ucontext_t *)context;
     linux_ucontext_to_regs(&regs, uc);
 
     // setup default handler
@@ -557,10 +606,51 @@
     }
 }
 
+void general_signal_handler(int signum, siginfo_t* info, void* context)
+{
+    bool replaced = false;
+    ucontext_t* uc = (ucontext_t *)context;
+    POINTER_SIZE_INT saved_ip = (POINTER_SIZE_INT)uc->uc_mcontext.gregs[REG_RIP];
+    POINTER_SIZE_INT new_ip = 0;
+
+    // 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
+    POINTER_SIZE_INT break_buf =
+        (POINTER_SIZE_INT)p_TLS_vmthread->jvmti_thread.jvmti_jit_breakpoints_handling_buffer;
+    if (saved_ip >= break_buf &&
+        saved_ip < break_buf + TM_JVMTI_MAX_BUFFER_SIZE)
+    {
+        // Breakpoints should not occur in breakpoint buffer
+        assert(signum != SIGTRAP);
+
+        replaced = true;
+        new_ip = (POINTER_SIZE_INT)vm_get_ip_from_regs(p_TLS_vmthread);
+        uc->uc_mcontext.gregs[REG_RIP] = (greg_t)new_ip;
+    }
+
+    // FIXME: Should unify all signals here as it is done on ia32
+    jvmti_jit_breakpoint_handler(signum, info, context);
+
+    // If EIP was not changed in specific handler to start another handler,
+    // we should restore original EIP, if it's nesessary
+    if (replaced &&
+        (POINTER_SIZE_INT)uc->uc_mcontext.gregs[REG_RIP] == new_ip)
+    {
+        uc->uc_mcontext.gregs[REG_RIP] = (greg_t)saved_ip;
+    }
+}
+
 void initialize_signals()
 {
     struct sigaction sa;
 
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_SIGINFO;
+    sa.sa_sigaction = &general_signal_handler;
+    sigaction(SIGTRAP, &sa, NULL);
+    
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_SIGINFO | SA_ONSTACK;;
     sa.sa_sigaction = &null_java_reference_handler;



Mime
View raw message