1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2%
3% File:         PXNK:TRAP.SL
4% Description:  Signal handling for Sun Unix 4.2.
5% Author:       Vicki O'Day, HP Labs/CRC
6% Created:      27-Feb-84
7% Modified:     2-Jan-85 13:13:16 (Vicki O'Day)
8% Mode:         Lisp
9% Package:
10% Status:       Open Source: BSD License
11%
12% (c) Copyright 1983, Hewlett-Packard Company, see the file
13%            HP_disclaimer at the root of the PSL file tree
14%
15% (c) Copyright 1982, University of Utah
16%
17% Redistribution and use in source and binary forms, with or without
18% modification, are permitted provided that the following conditions are met:
19%
20%    * Redistributions of source code must retain the relevant copyright
21%      notice, this list of conditions and the following disclaimer.
22%    * Redistributions in binary form must reproduce the above copyright
23%      notice, this list of conditions and the following disclaimer in the
24%      documentation and/or other materials provided with the distribution.
25%
26% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
28% THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR
30% CONTRIBUTORS
31% BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37% POSSIBILITY OF SUCH DAMAGE.
38%
39%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40%
41% Revisions:
42%
43% 17-Feb-89 (Chris Burdorf)
44%  Use sun3_sigset for os/4.
45% 09-Oct-87 (Leigh Stoller)
46%  Do not call build-trap-message anymore. It is too flakey to be relied
47%   on to tell the truth.
48% 31-Apr-87 (Leigh Stoller)
49%  After consult with Julian Padget, altered sigunwind to decrease the
50%   stack frame by 320 bytes instead of 98. The interrupted address is
51%   found 312 bytes into this frame.
52% 18-Aug-86 (Leigh Stoller)
53%  Reworked so that signals can be added more easily. Also added calls to
54%  external functions which set up the trap, and reinit the trap after a
55%  signal is recieved.
56% 2-Jan-85 10:21:47 (Vicki O'Day)
57%  Instead of just calling stderror with a message about the kind of trap,
58%  we now find the name of the routine that caused the trap and report
59%  that as well.  CODE-ADDRESS-TO-SYMBOL is used to figure out the name.
60% 27-Dec-84 10:55:56 (Vicki O'Day)
61%  Added sigunwind, to pop the signal handler's stack frame before calling
62%  stderror.  (Many thanks to Jim Davis for deciphering the contents of this
63%  frame.)
64% 17-Dec-84 10:24:41 (Vicki O'Day)
65%  Added lots more signals to catch, to try to prevent those occasional
66%  dumps out of Nmode.
67%
68%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
69
70(fluid '(errorstack* errornumber* errorcall* errorstring* sigaddr*))
71
72(compiletime
73 (progn
74   (setf *sigcalls* nil)
75   %
76   % Create a list of initialization code needed to set up the traps. The
77   % return value is the entry points for each signal handler.
78   % This is later flaged as a
79   %  cmacro so the returned code can be inserted directly into the lap coded
80   %  procedure 'initializeinterrupts each time it is called. The list
81   %  *sigentries is then inserted to define the entry points.
82   (de *sigsetup (signumber function handler errorstring)
83       (setf *sigcalls* (append
84             % Sigset takes a function pointer.
85             `((*move (wconst ,signumber) (reg 1))
86               (*move ,handler (reg 2))
87               (*link sun3_sigset expr 2))
88             *sigcalls*))
89       % Return the the function definition for the signal handler.
90       `((*entry ,function expr 0)
91
92        % WinNt: handler is called with description in stack
93        % don't need SIGRELSE
94     ,handler
95     (*move (frame 2) (fluid errornumber*))  % number of signal received
96     (push (reg ebp))                        % save a couple of registers
97     (*move (reg st) (reg ebp))
98     (push (reg ebp))
99     (push (reg 2))
100     (*link ieee_flags 0)                    % ieee_flags abused to return
101                                             % a pointer to a
102                                             % EXCEPTION_POINTERS structure
103                                             % which contains
104     (*move (memory (reg 1) 0) (reg 2))      % addr of exception info and
105     (*move (memory (reg 1) 4) (reg 3))      % addr of thread context
106     (*move (memory (reg 2) 0) (reg 4))      % exception code (type)
107     (*move (memory (reg 3) 184) (fluid sigaddr*))
108                                             % instruction pointer at fault
109     (*move (memory (reg 3) 196) (reg 1))    % stack pointer at fault
110     (*move (reg 1) (fluid errorstack*))
111     (*move ($fluid errorcall*) (reg 2))
112     (*move (reg 2) (displacement (reg 3) 184))
113                                             % overwrite address of faulted
114					     % instruction by address of
115 					     % function errortrap
116     (*move (quote ,errorstring) (fluid errorstring*))
117                                             % string for error message
118     (*link initializeinterrupts-1 expr 0)
119     (pop (reg 2)) 		             % restored saved registers
120     (pop (reg ebp))
121     (*move (reg ebp) (reg st))
122     (pop (reg ebp))
123     (ret))
124       )
125
126   % Return the entry point list. Defined as a cmacro.
127   (de *sigcall ()
128       *sigcalls*)
129
130   (defcmacro *sigcall)
131   (defcmacro *sigsetup)
132
133   )
134) % End of compiletime.
135
136
137(lap '(
138       % NO!!! (*sigsetup 1  aborthandler  aborthandlerinstruction  "Abort")
139
140       (*sigsetup 11  SegHandler  SegHandlerInstruction
141                                    "Segmentation Violation")
142
143       (*sigsetup 2  SigHandler  SigHandlerInstruction
144                                    "External Interrupt Signal")
145
146       (*sigsetup 8     FZDHandler  FZDHandlerInstruction
147                         "Float Exception")
148
149       (*sigsetup 4     IllHandler  IllHandlerInstruction
150                         "Illegal Instruction")
151
152       (*sigsetup 15     PRIHandler  PRIHandlerInstruction
153                         "Kill Signal")
154
155
156       (*sigsetup 21    IOVHandler  IOVHandlerInstruction
157                         "Terminal Interrupt")
158
159       (*sigsetup 22     ALGHandler  ALGHandlerInstruction
160                         "Abort")
161
162
163       (*entry initializeinterrupts-1 expr 0)
164       (*sigcall)
165       (*exit 0)))
166
167(de initializeinterrupts ()
168       (ieee_handler (strbase (strinf "set"))
169                  (strbase (strinf "common"))
170                  (symfnc (id2int 'fpehandler)))
171       (initializeinterrupts-1)
172      )
173
174
175(lap
176 '((!*entry sigunwind expr 0)
177     % At this point, an arg is already set up in register 1 with a message
178     % describing the kind of trap.  First, though, we want to find the
179     % name of the routine that caused the trap by using the "interrupted
180     % address" in the signal handler stack frame.  Then we want to
181     % pop this frame off the stack.  On the SUN, this adds up to 320 bytes.
182     % Who know why.
183
184     (*link initializeinterrupts-1 expr 0)
185
186     (*move (fluid errornumber*) (reg 1))
187     (*wplus2 (reg 1)(wconst 10000))
188     (pop (reg 2))
189     (pop (reg ebp))
190     (*move (reg ebp) (reg st))
191     (pop (reg ebp))
192     (ret)  %%% (*jcall error)                     % ready to be passed
193     ))
194
195(de errortrap ()
196  (progn
197    (ieee_handler)   % clear fp status
198    (error (wplus2 errornumber* 10000)
199           (build-trap-message errorstring* sigaddr*))))
200
201(setq errorcall* (wgetv symfnc (id2int 'errortrap)))
202
203(de build-trap-message (trap-type trap-addr)
204    (let (extra-info)
205      (if (funboundp 'code-address-to-symbol)
206        (setf extra-info
207          (bldmsg " at %x%n" (inf trap-addr)))
208    % else, get the name of the offending function
209    (setf extra-info (bldmsg "%w%w"
210                 " in "
211                 (code-address-to-symbol (inf trap-addr))))
212      )
213      (bldmsg "%w%w" trap-type extra-info)))
214
215(fluid '(bruch_bruch))
216
217(de terminal-interrupt()
218    (setq bruch_bruch 0)
219    (error 10002 "Terminal Interrupt"))
220
221% End of file.
222
223