2 * This software is part of the SBCL system. See the README file for
5 * This software is derived from the CMU CL system, which was
6 * written at Carnegie Mellon University and released into the
7 * public domain. The software is in the public domain and is
8 * provided with absolutely no warranty. See the COPYING and CREDITS
9 * files for more information.
22 #include "interrupt.h"
24 #include "breakpoint.h"
32 os_vm_address_t
arch_get_bad_addr(int sig
, siginfo_t
*code
, os_context_t
*context
)
34 return (os_vm_address_t
)code
->si_addr
;
37 void arch_skip_instruction(os_context_t
*context
)
39 /* KLUDGE: Other platforms check for trap codes and skip inlined
40 * trap/error parameters. We should too. */
42 /* Note that we're doing integer arithmetic here, not pointer. So
43 * the value that the return value of os_context_pc_addr() points
44 * to will be incremented by 4, not 16.
46 *os_context_pc_addr(context
) += 4;
49 unsigned char *arch_internal_error_arguments(os_context_t
*context
)
51 return (unsigned char *)(*os_context_pc_addr(context
) + 5);
54 boolean
arch_pseudo_atomic_atomic(os_context_t
*context
)
56 /* FIXME: this foreign_function_call_active test is dubious at
57 * best. If a foreign call is made in a pseudo atomic section
58 * (?) or more likely a pseudo atomic section is in a foreign
59 * call then an interrupt is executed immediately. Maybe it
60 * has to do with C code not maintaining pseudo atomic
61 * properly. MG - 2005-08-10
63 * The foreign_function_call_active used to live at each call-site
64 * to arch_pseudo_atomic_atomic, but this seems clearer.
66 #ifdef LISP_FEATURE_GENCGC
67 return SymbolValue(PSEUDO_ATOMIC_ATOMIC
, 0) != NIL
;
69 return (!foreign_function_call_active
)
70 && (NIL
!= SymbolValue(PSEUDO_ATOMIC_ATOMIC
,0));
74 void arch_set_pseudo_atomic_interrupted(os_context_t
*context
)
76 SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED
, (lispobj
)do_pending_interrupt
, 0);
79 void arch_clear_pseudo_atomic_interrupted(os_context_t
*context
)
81 SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED
, 0, 0);
84 unsigned int arch_install_breakpoint(void *pc
)
86 /* FIXME: Implement. */
91 void arch_remove_breakpoint(void *pc
, unsigned int orig_inst
)
93 /* FIXME: Implement. */
96 void arch_do_displaced_inst(os_context_t
*context
, unsigned int orig_inst
)
98 /* FIXME: Implement. */
102 arch_handle_breakpoint(os_context_t
*context
)
104 handle_breakpoint(context
);
108 arch_handle_fun_end_breakpoint(os_context_t
*context
)
110 *os_context_pc_addr(context
) = (int) handle_fun_end_breakpoint(context
);
114 arch_handle_single_step_trap(os_context_t
*context
, int trap
)
116 unsigned char register_offset
=
117 *((unsigned char *)(*os_context_pc_addr(context
))+5);
118 handle_single_step_trap(context
, trap
, register_offset
);
119 /* KLUDGE: arch_skip_instruction() only skips one instruction, and
120 * there is a following word to deal with as well, so skip
122 arch_skip_instruction(context
);
123 arch_skip_instruction(context
);
128 #ifdef LISP_FEATURE_LINKAGE_TABLE
132 * Linkage entry size is 16, because we need 4 instructions.
135 #define LINKAGE_TEMP_REG reg_NFP
137 void arch_write_linkage_table_jmp(char *reloc_addr
, void *target_addr
)
145 BX is needed for thumb interworking, without it it could take just two words with
152 inst_ptr
= (int*) reloc_addr
;
155 inst
= 0xe59f0000 | LINKAGE_TEMP_REG
<< 12 | 4;
159 inst
= 0xe12fff10 | LINKAGE_TEMP_REG
;
162 // nop aka mov r0, r0
167 *inst_ptr
++ = (int)target_addr
;
169 os_flush_icache((os_vm_address_t
) reloc_addr
, (char*) inst_ptr
- reloc_addr
);
173 arch_write_linkage_table_ref(void * reloc_addr
, void *target_addr
)
175 *(unsigned long *)reloc_addr
= (unsigned long)target_addr
;