You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2007/10/12 19:20:15 UTC
svn commit: r584206 - in /harmony/enhanced/drlvm/trunk/vm/vmcore/src:
jvmti/jvmti_break_intf.cpp util/linux/signals_em64t.cpp
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(®s);
// 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(®s, uc);
+ TRACE2("signals", "JVMTI breakpoint detected at " <<
+ (void *)regs.rip);
+ assert(!interpreter_enabled());
+
+ bool handled = jvmti_jit_breakpoint_handler(®s);
+ if (handled)
+ {
+ linux_regs_to_ucontext(uc, ®s);
+ return;
+ }
+
+ fprintf(stderr, "SIGTRAP in VM code.\n");
+ linux_ucontext_to_regs(®s, uc);
+
+ // setup default handler
+ signal(signum, SIG_DFL);
+
+ if (!is_gdb_crash_handler_enabled() ||
+ !gdb_crash_handler())
+ {
+ // print stack trace
+ st_print_stack(®s);
+ }
+}
+
/**
* 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(®s, 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;