projects
/
sbcl.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Document extensible sequence protocol
[sbcl.git]
/
src
/
runtime
/
x86-arch.c
diff --git
a/src/runtime/x86-arch.c
b/src/runtime/x86-arch.c
index
6babc96
..
d00f26b
100644
(file)
--- a/
src/runtime/x86-arch.c
+++ b/
src/runtime/x86-arch.c
@@
-18,7
+18,6
@@
#include "os.h"
#include "arch.h"
#include "lispregs.h"
#include "os.h"
#include "arch.h"
#include "lispregs.h"
-#include "signal.h"
#include "alloc.h"
#include "interrupt.h"
#include "interr.h"
#include "alloc.h"
#include "interrupt.h"
#include "interr.h"
@@
-30,8
+29,13
@@
#include "genesis/symbol.h"
#define BREAKPOINT_INST 0xcc /* INT3 */
#include "genesis/symbol.h"
#define BREAKPOINT_INST 0xcc /* INT3 */
+#define UD2_INST 0x0b0f /* UD2 */
-unsigned long fast_random_state = 1;
+#ifndef LISP_FEATURE_UD2_BREAKPOINTS
+#define BREAKPOINT_WIDTH 1
+#else
+#define BREAKPOINT_WIDTH 2
+#endif
void arch_init(void)
{}
void arch_init(void)
{}
@@
-71,7
+75,7
@@
context_eflags_addr(os_context_t *context)
#elif defined __NetBSD__
return &(context->uc_mcontext.__gregs[_REG_EFL]);
#elif defined LISP_FEATURE_WIN32
#elif defined __NetBSD__
return &(context->uc_mcontext.__gregs[_REG_EFL]);
#elif defined LISP_FEATURE_WIN32
- return (int *)&context->EFlags;
+ return (int *)&context->win32_context->EFlags;
#else
#error unsupported OS
#endif
#else
#error unsupported OS
#endif
@@
-106,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:
@@
-158,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;
}
@@
-169,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
@@
-186,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:
@@
-222,11
+238,13
@@
restore_breakpoint_from_single_step(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 (*os_context_pc_addr(context) == (int)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;
@@
-236,14
+254,14
@@
restore_breakpoint_from_single_step(os_context_t * context)
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) =
(int)handle_fun_end_breakpoint(context);
}
*os_context_pc_addr(context) =
(int)handle_fun_end_breakpoint(context);
}
@@
-259,19
+277,18
@@
arch_handle_single_step_trap(os_context_t *context, int trap)
#ifndef LISP_FEATURE_WIN32
void
#ifndef LISP_FEATURE_WIN32
void
-sigtrap_handler(int signal, siginfo_t *info, void *void_context)
+sigtrap_handler(int signal, siginfo_t *info, os_context_t *context)
{
{
- os_context_t *context = (os_context_t*)void_context;
unsigned int trap;
unsigned int trap;
- if (single_stepping && (signal==SIGTRAP)) {
+ if (single_stepping) {
restore_breakpoint_from_single_step(context);
return;
}
/* This is just for info in case the monitor wants to print an
* approximation. */
restore_breakpoint_from_single_step(context);
return;
}
/* 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);
#ifdef LISP_FEATURE_SUNOS
(lispobj *)*os_context_sp_addr(context);
#ifdef LISP_FEATURE_SUNOS
@@
-294,16
+311,14
@@
sigtrap_handler(int signal, siginfo_t *info, void *void_context)
}
void
}
void
-sigill_handler(int signal, siginfo_t *siginfo, void *void_context) {
- os_context_t *context = (os_context_t*)void_context;
-
+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;
*os_context_pc_addr(context) += 2;
- return sigtrap_handler(signal, siginfo, void_context);
+ return sigtrap_handler(signal, siginfo, context);
}
#endif
fake_foreign_function_call(context);
}
#endif
fake_foreign_function_call(context);