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"
26 #include "pseudo-atomic.h"
33 os_vm_address_t
arch_get_bad_addr(int sig
, siginfo_t
*code
, os_context_t
*context
)
35 return (os_vm_address_t
)code
->si_addr
;
38 void arch_skip_instruction(os_context_t
*context
)
40 /* KLUDGE: Other platforms check for trap codes and skip inlined
41 * trap/error parameters. We should too. */
43 /* Note that we're doing integer arithmetic here, not pointer. So
44 * the value that the return value of os_context_pc_addr() points
45 * to will be incremented by 4, not 32.
47 *os_context_pc_addr(context
) += 4;
50 unsigned char *arch_internal_error_arguments(os_context_t
*context
)
52 return (unsigned char *)*os_context_pc_addr(context
);
55 boolean
arch_pseudo_atomic_atomic(os_context_t
*context
)
57 /* FIXME: this foreign_function_call_active test is dubious at
58 * best. If a foreign call is made in a pseudo atomic section
59 * (?) or more likely a pseudo atomic section is in a foreign
60 * call then an interrupt is executed immediately. Maybe it
61 * has to do with C code not maintaining pseudo atomic
62 * properly. MG - 2005-08-10
64 * The foreign_function_call_active used to live at each call-site
65 * to arch_pseudo_atomic_atomic, but this seems clearer.
67 #ifdef LISP_FEATURE_GENCGC
68 return get_pseudo_atomic_atomic(arch_os_get_current_thread());
70 return (!foreign_function_call_active
)
71 && (NIL
!= SymbolValue(PSEUDO_ATOMIC_ATOMIC
,0));
75 void arch_set_pseudo_atomic_interrupted(os_context_t
*context
)
77 set_pseudo_atomic_interrupted(arch_os_get_current_thread());
80 void arch_clear_pseudo_atomic_interrupted(os_context_t
*context
)
82 clear_pseudo_atomic_interrupted(arch_os_get_current_thread());
85 unsigned int arch_install_breakpoint(void *pc
)
87 /* FIXME: Implement. */
92 void arch_remove_breakpoint(void *pc
, unsigned int orig_inst
)
94 /* FIXME: Implement. */
97 void arch_do_displaced_inst(os_context_t
*context
, unsigned int orig_inst
)
99 /* FIXME: Implement. */
103 arch_handle_breakpoint(os_context_t
*context
)
105 handle_breakpoint(context
);
109 arch_handle_fun_end_breakpoint(os_context_t
*context
)
111 *os_context_pc_addr(context
) = (int) handle_fun_end_breakpoint(context
);
115 arch_handle_single_step_trap(os_context_t
*context
, int trap
)
117 handle_single_step_trap(context
, trap
, reg_LEXENV
);
118 arch_skip_instruction(context
);
122 sigtrap_handler(int signal
, siginfo_t
*siginfo
, os_context_t
*context
)
124 u32 trap_instruction
= *((u32
*)*os_context_pc_addr(context
));
125 unsigned code
= trap_instruction
>> 5 & 0xFF;
126 if ((trap_instruction
>> 21) != 0x6A1) {
127 lose("Unrecognized trap instruction %08lx in sigtrap_handler() (PC: %p)",
128 trap_instruction
, *os_context_pc_addr(context
));
131 handle_trap(context
, code
);
134 void arch_install_interrupt_handlers()
136 undoably_install_low_level_interrupt_handler(SIGTRAP
, sigtrap_handler
);
140 #ifdef LISP_FEATURE_LINKAGE_TABLE
144 * Linkage entry size is 16, because we need 2 instructions and an 8 byte address.
147 #define LINKAGE_TEMP_REG reg_NFP
149 void arch_write_linkage_table_jmp(char *reloc_addr
, void *target_addr
)
159 inst_ptr
= (int*) reloc_addr
;
162 inst
= 0x58000000 | 2 << 5 | LINKAGE_TEMP_REG
;
166 inst
= 0xD61F0000 | LINKAGE_TEMP_REG
<< 5;
170 *(unsigned long *)inst_ptr
++ = target_addr
;
172 os_flush_icache((os_vm_address_t
) reloc_addr
, (char*) inst_ptr
- reloc_addr
);
176 arch_write_linkage_table_ref(void * reloc_addr
, void *target_addr
)
178 *(unsigned long *)reloc_addr
= (unsigned long)target_addr
;