projects
/
sbcl.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Use safepoints for INTERRUPT-THREAD
[sbcl.git]
/
src
/
runtime
/
x86-64-arch.c
diff --git
a/src/runtime/x86-64-arch.c
b/src/runtime/x86-64-arch.c
index
a88435c
..
62333e2
100644
(file)
--- a/
src/runtime/x86-64-arch.c
+++ b/
src/runtime/x86-64-arch.c
@@
-31,6
+31,13
@@
#include "genesis/symbol.h"
#define BREAKPOINT_INST 0xcc /* INT3 */
#include "genesis/symbol.h"
#define BREAKPOINT_INST 0xcc /* INT3 */
+#define UD2_INST 0x0b0f /* UD2 */
+
+#ifndef LISP_FEATURE_UD2_BREAKPOINTS
+#define BREAKPOINT_WIDTH 1
+#else
+#define BREAKPOINT_WIDTH 2
+#endif
unsigned long fast_random_state = 1;
unsigned long fast_random_state = 1;
@@
-67,6
+74,8
@@
context_eflags_addr(os_context_t *context)
return CONTEXT_ADDR_FROM_STEM(rflags);
#elif defined __OpenBSD__
return &context->sc_rflags;
return CONTEXT_ADDR_FROM_STEM(rflags);
#elif defined __OpenBSD__
return &context->sc_rflags;
+#elif defined __NetBSD__
+ return CONTEXT_ADDR_FROM_STEM(RFLAGS);
#else
#error unsupported OS
#endif
#else
#error unsupported OS
#endif
@@
-101,6
+110,10
@@
void arch_skip_instruction(os_context_t *context)
case trap_FunEndBreakpoint: /* not tested */
break;
case trap_FunEndBreakpoint: /* not tested */
break;
+#ifdef LISP_FEATURE_SB_SAFEPOINT
+ case trap_GlobalSafepoint:
+ case trap_CspSafepoint:
+#endif
case trap_PendingInterrupt:
case trap_Halt:
case trap_SingleStepAround:
case trap_PendingInterrupt:
case trap_Halt:
case trap_SingleStepAround:
@@
-153,8
+166,14
@@
arch_install_breakpoint(void *pc)
{
unsigned int result = *(unsigned int*)pc;
{
unsigned int result = *(unsigned int*)pc;
+#ifndef LISP_FEATURE_UD2_BREAKPOINTS
*(char*)pc = BREAKPOINT_INST; /* x86 INT3 */
*((char*)pc+1) = trap_Breakpoint; /* Lisp trap code */
*(char*)pc = BREAKPOINT_INST; /* x86 INT3 */
*((char*)pc+1) = trap_Breakpoint; /* Lisp trap code */
+#else
+ *(char*)pc = UD2_INST & 0xff;
+ *((char*)pc+1) = UD2_INST >> 8;
+ *((char*)pc+2) = trap_Breakpoint;
+#endif
return result;
}
return result;
}
@@
-164,6
+183,9
@@
arch_remove_breakpoint(void *pc, unsigned int orig_inst)
{
*((char *)pc) = orig_inst & 0xff;
*((char *)pc + 1) = (orig_inst & 0xff00) >> 8;
{
*((char *)pc) = orig_inst & 0xff;
*((char *)pc + 1) = (orig_inst & 0xff00) >> 8;
+#if BREAKPOINT_WIDTH > 1
+ *((char *)pc + 2) = (orig_inst & 0xff0000) >> 16;
+#endif
}
\f
/* When single stepping, single_stepping holds the original instruction
}
\f
/* When single stepping, single_stepping holds the original instruction
@@
-181,8
+203,7
@@
arch_do_displaced_inst(os_context_t *context, unsigned int orig_inst)
unsigned int *pc = (unsigned int*)(*os_context_pc_addr(context));
/* Put the original instruction back. */
unsigned int *pc = (unsigned int*)(*os_context_pc_addr(context));
/* Put the original instruction back. */
- *((char *)pc) = orig_inst & 0xff;
- *((char *)pc + 1) = (orig_inst & 0xff00) >> 8;
+ arch_remove_breakpoint(pc, orig_inst);
#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
/* Install helper instructions for the single step:
#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
/* Install helper instructions for the single step:
@@
-207,14
+228,14
@@
arch_do_displaced_inst(os_context_t *context, unsigned int orig_inst)
void
arch_handle_breakpoint(os_context_t *context)
{
void
arch_handle_breakpoint(os_context_t *context)
{
- --*os_context_pc_addr(context);
+ *os_context_pc_addr(context) -= BREAKPOINT_WIDTH;
handle_breakpoint(context);
}
void
arch_handle_fun_end_breakpoint(os_context_t *context)
{
handle_breakpoint(context);
}
void
arch_handle_fun_end_breakpoint(os_context_t *context)
{
- --*os_context_pc_addr(context);
+ *os_context_pc_addr(context) -= BREAKPOINT_WIDTH;
*os_context_pc_addr(context) =
(unsigned long)handle_fun_end_breakpoint(context);
}
*os_context_pc_addr(context) =
(unsigned long)handle_fun_end_breakpoint(context);
}
@@
-234,8
+255,7
@@
sigtrap_handler(int signal, siginfo_t *info, os_context_t *context)
{
unsigned int trap;
{
unsigned int trap;
- if (single_stepping && (signal==SIGTRAP))
- {
+ if (single_stepping) {
#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
/* Un-install single step helper instructions. */
*(single_stepping-3) = single_step_save1;
#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
/* Un-install single step helper instructions. */
*(single_stepping-3) = single_step_save1;
@@
-245,12
+265,13
@@
sigtrap_handler(int signal, siginfo_t *info, os_context_t *context)
*context_eflags_addr(context) ^= 0x100;
#endif
/* Re-install the breakpoint if possible. */
*context_eflags_addr(context) ^= 0x100;
#endif
/* Re-install the breakpoint if possible. */
- if ((char *)*os_context_pc_addr(context) ==
- (char *)single_stepping + 1) {
+ if (((char *)*os_context_pc_addr(context) >
+ (char *)single_stepping) &&
+ ((char *)*os_context_pc_addr(context) <=
+ (char *)single_stepping + BREAKPOINT_WIDTH)) {
fprintf(stderr, "warning: couldn't reinstall breakpoint\n");
} else {
fprintf(stderr, "warning: couldn't reinstall breakpoint\n");
} else {
- *((char *)single_stepping) = BREAKPOINT_INST; /* x86 INT3 */
- *((char *)single_stepping+1) = trap_Breakpoint;
+ arch_install_breakpoint(single_stepping);
}
single_stepping = NULL;
}
single_stepping = NULL;
@@
-259,7
+280,7
@@
sigtrap_handler(int signal, siginfo_t *info, os_context_t *context)
/* This is just for info in case the monitor wants to print an
* approximation. */
/* This is just for info in case the monitor wants to print an
* approximation. */
- current_control_stack_pointer =
+ access_control_stack_pointer(arch_os_get_current_thread()) =
(lispobj *)*os_context_sp_addr(context);
/* On entry %eip points just after the INT3 byte and aims at the
(lispobj *)*os_context_sp_addr(context);
/* On entry %eip points just after the INT3 byte and aims at the
@@
-276,8
+297,8
@@
sigill_handler(int signal, siginfo_t *siginfo, os_context_t *context) {
/* Triggering SIGTRAP using int3 is unreliable on OS X/x86, so
* we need to use illegal instructions for traps.
*/
/* Triggering SIGTRAP using int3 is unreliable on OS X/x86, so
* we need to use illegal instructions for traps.
*/
-#if defined(LISP_FEATURE_DARWIN) && !defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
- if (*((unsigned short *)*os_context_pc_addr(context)) == 0x0b0f) {
+#if defined(LISP_FEATURE_UD2_BREAKPOINTS) && !defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
+ if (*((unsigned short *)*os_context_pc_addr(context)) == UD2_INST) {
*os_context_pc_addr(context) += 2;
return sigtrap_handler(signal, siginfo, context);
}
*os_context_pc_addr(context) += 2;
return sigtrap_handler(signal, siginfo, context);
}