Contributed by Kalevi Suominen <kalevi.suominen@helsinki.fi>.
[libsigsegv/ericb.git] / src / fault-netbsd-alpha.c
blob6ca67bc13791227f46a5b2049a30be42221e5f89
1 /* Fault handler information subroutine. NetBSD/Alpha version.
2 * Taken from gcc-3.3/boehm-gc/os_dep.c.
4 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
5 * Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved.
6 * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved.
7 * Copyright (c) 1999 by Hewlett-Packard Company. All rights reserved.
9 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
10 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
12 * Permission is hereby granted to use or copy this program
13 * for any purpose, provided the above notices are retained on all copies.
14 * Permission to modify the code and to distribute modified code is granted,
15 * provided the above notices are retained, and a notice that the code was
16 * modified is included with the above copyright notice.
19 /* Decodes the machine instruction which was responsible for the sending of the
20 SIGBUS signal. Luckily this is much easier than, say, on the PowerPC. */
22 static void *
23 get_fault_addr (struct sigcontext *scp)
25 unsigned int instr = *((unsigned int *)(scp->sc_pc));
26 unsigned long faultaddr;
28 /* Instructions which access memory have operands of the form ARG_MEM or
29 ARG_FMEM, consisting of
30 - a base register specification (PRB) in bits 20..16,
31 - a memory displacement (MDISP) in bits 15..0,
32 - an general register specification (RA) or a floating-point register
33 specification (FA) in bits 25..21.
34 See binutils-2.13.90.0.16/opcodes/alpha-opc.c. */
36 faultaddr = scp->sc_regs[(instr >> 16) & 0x1f];
37 faultaddr += (unsigned long) (long) (((int)instr << 16) >> 16);
38 return (void *) faultaddr;