1 /* src/vm/jit/arm/linux/md-os.c - machine dependent arm linux functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: md.c 166 2006-01-22 23:38:44Z twisti $
37 #include "vm/jit/arm/md-abi.h"
39 #define ucontext broken_glibc_ucontext
40 #define ucontext_t broken_glibc_ucontext_t
45 typedef struct ucontext {
46 unsigned long uc_flags;
47 struct ucontext *uc_link;
49 struct sigcontext uc_mcontext;
53 #define scontext_t struct sigcontext
55 #if defined(ENABLE_THREADS)
56 # include "threads/native/threads.h"
59 #include "vm/exceptions.h"
60 #include "vm/signallocal.h"
61 #include "vm/stringlocal.h"
63 #include "vm/jit/asmpart.h"
64 #include "vm/jit/stacktrace.h"
67 /* md_signal_handler_sigsegv ***************************************************
69 Signal handler for hardware exceptions.
71 *******************************************************************************/
73 void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
88 _uc = (ucontext_t*) _p;
89 _sc = &_uc->uc_mcontext;
91 /* ATTENTION: glibc included messed up kernel headers we needed a
92 workaround for the ucontext structure. */
94 pv = (u1 *) _sc->arm_ip;
95 sp = (u1 *) _sc->arm_sp;
96 ra = (u1 *) _sc->arm_lr; /* this is correct for leafs */
97 xpc = (u1 *) _sc->arm_pc;
99 /* get exception-throwing instruction */
102 vm_abort("md_signal_handler_sigsegv: the program counter is NULL");
104 mcode = *((s4 *) xpc);
106 /* this is a NullPointerException */
108 addr = *((s4 *) _sc + OFFSET(scontext_t, arm_r0)/4 + ((mcode >> 16) & 0x0f));
109 type = EXCEPTION_HARDWARE_NULLPOINTER;
113 vm_abort("md_signal_handler_sigsegv: faulting address is not NULL: addr=%p", addr);
115 /* create stackframeinfo */
117 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
119 /* Handle the type. */
121 p = signal_handle(xpc, type, val);
123 /* remove stackframeinfo */
125 stacktrace_remove_stackframeinfo(&sfi);
129 _sc->arm_r10 = (intptr_t) p;
130 _sc->arm_fp = (intptr_t) xpc;
131 _sc->arm_pc = (intptr_t) asm_handle_exception;
135 /* md_signal_handler_sigill ****************************************************
137 Illegal Instruction signal handler for hardware exception checks.
139 *******************************************************************************/
141 void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
155 _uc = (ucontext_t*) _p;
156 _sc = &_uc->uc_mcontext;
158 /* ATTENTION: glibc included messed up kernel headers we needed a
159 workaround for the ucontext structure. */
161 pv = (u1 *) _sc->arm_ip;
162 sp = (u1 *) _sc->arm_sp;
163 ra = (u1 *) _sc->arm_lr; /* this is correct for leafs */
164 xpc = (u1 *) _sc->arm_pc;
166 /* get exception-throwing instruction */
168 mcode = *((u4 *) xpc);
170 /* check for undefined instruction we use */
172 if ((mcode & 0x0ff000f0) != 0x07f000f0)
173 vm_abort("md_signal_handler_sigill: unknown illegal instruction");
175 type = (mcode >> 8) & 0x0fff;
176 val = *((s4 *) _sc + OFFSET(scontext_t, arm_r0)/4 + (mcode & 0x0f));
178 /* create stackframeinfo */
180 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
182 /* Handle the type. */
184 p = signal_handle(xpc, type, val);
186 /* remove stackframeinfo */
188 stacktrace_remove_stackframeinfo(&sfi);
190 /* set registers if we have an exception, return continue execution
191 otherwise (this is needed for patchers to work) */
194 _sc->arm_r10 = (intptr_t) p;
195 _sc->arm_fp = (intptr_t) xpc;
196 _sc->arm_pc = (intptr_t) asm_handle_exception;
201 /* md_signal_handler_sigusr2 ***************************************************
203 Signal handler for profiling sampling.
205 *******************************************************************************/
207 #if defined(ENABLE_THREADS)
208 void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
210 threadobject *thread;
215 thread = THREADOBJECT;
217 _uc = (ucontext_t*) _p;
218 _sc = &_uc->uc_mcontext;
220 pc = (u1 *) _sc->arm_pc;
227 /* md_critical_section_restart *************************************************
229 Search the critical sections tree for a matching section and set
230 the PC to the restart point, if necessary.
232 *******************************************************************************/
234 #if defined(ENABLE_THREADS)
235 void md_critical_section_restart(ucontext_t *_uc)
241 _sc = &_uc->uc_mcontext;
243 pc = (u1 *) _sc->arm_pc;
245 npc = critical_find_restart_point(pc);
248 _sc->arm_pc = (ptrint) npc;
254 * These are local overrides for various environment variables in Emacs.
255 * Please do not remove this and leave it at the end of the file, where
256 * Emacs will automagically detect them.
257 * ---------------------------------------------------------------------
260 * indent-tabs-mode: t