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