source: trunk/src/gcc/libjava/include/i386-signal.h@ 64

Last change on this file since 64 was 2, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 4.9 KB
Line 
1// i386-signal.h - Catch runtime signals and turn them into exceptions
2// on an i386 based Linux system.
3
4/* Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation
5
6 This file is part of libgcj.
7
8This software is copyrighted work licensed under the terms of the
9Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
10details. */
11
12
13#ifndef JAVA_SIGNAL_H
14#define JAVA_SIGNAL_H 1
15
16#include <signal.h>
17#include <sys/syscall.h>
18
19#define HANDLE_SEGV 1
20#define HANDLE_FPE 1
21
22#define SIGNAL_HANDLER(_name) \
23static void _name (int _dummy)
24
25#define MAKE_THROW_FRAME(_exception) \
26do \
27{ \
28 void **_p = (void **)&_dummy; \
29 struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p; \
30 \
31 /* Advance the program counter so that it is after the start of the \
32 instruction: the x86 exception handler expects \
33 the PC to point to the instruction after a call. */ \
34 _regs->eip += 2; \
35 \
36} \
37while (0)
38
39#define HANDLE_DIVIDE_OVERFLOW \
40do \
41{ \
42 void **_p = (void **)&_dummy; \
43 struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p; \
44 \
45 register unsigned char *_eip = (unsigned char *)_regs->eip; \
46 \
47 /* According to the JVM spec, "if the dividend is the negative \
48 * integer of the smallest magnitude and the divisor is -1, then \
49 * overflow occurs and the result is equal to the dividend. Despite \
50 * the overflow, no exception occurs". \
51 \
52 * We handle this by inspecting the instruction which generated the \
53 * signal and advancing eip to point to the following instruction. \
54 * As the instructions are variable length it is necessary to do a \
55 * little calculation to figure out where the following instruction \
56 * actually is. \
57 \
58 */ \
59 \
60 if (_eip[0] == 0xf7) \
61 { \
62 unsigned char _modrm = _eip[1]; \
63 \
64 if (_regs->eax == 0x80000000 \
65 && ((_modrm >> 3) & 7) == 7) /* Signed divide */ \
66 { \
67 _regs->edx = 0; /* the remainder is zero */ \
68 switch (_modrm >> 6) \
69 { \
70 case 0: \
71 if ((_modrm & 7) == 5) \
72 _eip += 4; \
73 break; \
74 case 1: \
75 _eip += 1; \
76 break; \
77 case 2: \
78 _eip += 4; \
79 break; \
80 case 3: \
81 break; \
82 } \
83 _eip += 2; \
84 _regs->eip = (unsigned long)_eip; \
85 return; \
86 } \
87 else \
88 { \
89 /* Advance the program counter so that it is after the start \