📄 vaxexception.s
字号:
# # # push argument list on stack # normal: #normal exit from stack copy pushal (sp) #push address of mechanism arguments pushal 28(sp) #push address of signal arguments pushl $2 #push number of arguments # check if this exception should be modified by an instruction emulator # movl exe$gl_vaxexcvec,r1 #modification routine supplied? # beql exe$srchandler #branch if none/* * No need to check because we only come throught here if we have * an error in the Ultrix emulation code. So jump to the code that * will handle the emulation signals */#if defined (MVAX) || defined(VAX420) || defined (VAX3600) || defined (VAX6200) jsb vax$modify_exception#endif MVAX || VAX420 || VAX3600 || VAX6200 # # check the pc of the exception. if it is in the condition handler call # vector, then an exception has occurred attempting to call a condition # handler (e.g., due to bad address or entry mask). if this is the case, # exit the image to avoid an exception loop. we do the same for calls # to ast routines. while this is not strictly a bad stack, reporting the # exception with the ast context recorded in the stack is such a pain # that it is not worth it. the special case of a t-bit pending exception # is allowed since this case cannot result in a loop. # .globl exe$srchandlerexe$srchandler: #entry point for external use1: movb 36(sp),35(sp) #save signal vector length cmpl 40(sp),$ss$_tbit #check for t-bit pending exception beql 1f #branch if yes - skip checks addl3 $8,36(sp),r1 #compute longword offset to saved pc/* cmpl (sp)[r1],$sys$call_handl #compare to handler call site * beql bad_handler #branch if yes * cmpl (sp)[r1],$exe$astdel #compare to ast call site * beql bad_ast #branch if yes */ # # search for condition handler #1: callg (sp),search #search for condition handler blbc r0,2f #if lbc fatal error bbc $1,32(sp),6f #branch if this is not a stop/* insv $sts$k_severe,$sts$v_severity,$sts$s_severity,40(sp) * #for stop, force severity to fatal */ # # call condition handler # 6: jsb *$sys$call_handl #call handler via system vector blbc r0,1b #if lbc resignal/* bbs $1,32(sp),cont_from_stop #branch if attempting to continue fro stop */ movzbl 35(sp),(sp) #get original signal arg count addl2 $8,(sp) #calculate longword offset to saved pc mull2 $4,(sp) #calculate number of bytes to remove movq 24(sp),r0 #restore r0 and r1 addl2 (sp),sp #remove argument list from stack rei # # # to here on attempt to continue form a call to stop #/* *cont_from_stop: #set final status and message * movl $<lib$_attconsto&^csts$m_severity>!attconsto_idx,r0 * cmpl 20(sp),$-3 #see if just called last chance handler * brb 7f #and flow into exit code * *# *# to here if an exception occurred attempting to call a handler *# *bad_handler: * movl 40(sp),r0 #set condition as final status * #set message string * insv $badhandler_idx,$sts$v_severity,$sts$s_severity,r0 * cmpl 32(sp)[r1],$-3 #see if trying to call last chance handler *7: bneq 2f #if not, go to call it * movl r0,32(sp) #save condition and message * brb 3f #if yes, don't call it again * *# *# to here if an exception occurred attempting to call an ast *# *bad_ast: * movl 40(sp),r0 #set condition as final status * #set message string * insv $badast_idx,$sts$v_severity,$sts$s_severity,r0 * brb 20$ *# *# bad stack when trying to copy exception arguments *# * *badstack: #bad stack exit from stack copy * pushal (sp) #push address of mechanism arguments * pushal 28(sp) #push address of signal arguments * pushl $2 #push number of arguments * #set bad stack status * movzwl $<ss$_badstack&^csts$m_severity>!final_idx,r0 */2: movl r0,32(sp) #save final status and message/* $setsfm_s $0 # clear sys. service failure excep. mode */ movpsl r0 #read current psl extzv $psl$v_curmod,$psl$s_curmod,r0,r0 #extract current mode/* movl *$ctl$al_finalexc[r0],r1 #get address of last chance handler */ movl $default_handler,r1 # store the Ultrix default handler/* beql 3f #if eql none */ mnegl $3,20(sp) #set frame depth to minus three jsb *$sys$call_handl #call last chance condition handler/* brb 8f * * *3: movpsl r0 #read current psl * extzv $psl$v_curmod,$psl$s_curmod,r0,r0 #extract current mode * cmpl $psl$c_exec,r0 #executive or kernel mode? * bgequ 9f #if gequ yes *8: extzv $sts$v_severity,$sts$s_severity,32(sp),r0 #get message index * tstb *$ctl$gb_ssfilter #are system services inhibited? * bneq 4f #yes, don't try to print anything * pushab (sp) #push address of condition argument list * pushl msg_vector[r0] #push address of final exception message * calls $2,exe$excmsg #print final exception message *4: movl 32(sp),r0 #retrieve final status * insv $sts$k_severe,$sts$v_severity,$sts$s_severity,r0 * $exit_s r0 #exit process * *9: bgtru 5f #branch if kernel mode * bug_check fatalexcpt #fatal executive mode exception * brb 4b #go delete the process * *5: bug_check fatalexcpt,fatal #fatal kernel mode exception */ # # copy arguments to previous mode stack and exit to previous mode # copyargs: #copy argument lists to previous mode stack movab 16(sp),r0 #get address of arguments to copy1: movl (r0)+,(r1)+ #copy exception arguments to previous stack sobgtr r3,1b #any more longwords to copy? # bicl2 $psl$m_cm|psl$m_tbit|psl$m_fpd|psl$m_tp,-(r0) bicl2 $0xC8000010,-(r0) #clear compatibility, t-bit, t pending,and #first part done # popl -(r0) #set return address movl (sp)+,-(r0) # popr $^m<r2,r3,r4> #restore registers r2, r3, r4 popr $0x1c movl r0,sp #remove arguments from kernal stack rei # # # subroutine to check accessibility of stack address range # # inputs: # r1 - stack pointer # r3 - partial longword count # # outputs: # r0 - bottom address of range # z condition code - 0 if accessible, else 1 # # r1,r2,r3 are preserved. # check_stack: #check stack address range # pushr $^m<r1,r2,r3> #save registers pushr $0x0e addl3 $3+1+17,r3,r1 #calculate total longwords in range mull2 $4,r1 #calculate number of bytes in range subl3 r1,(sp),r0 #calculate bottom address of range pushl r0 #save this quantity clrl r3 #access mode to maximize with psl<prvmod> # jsb exe$probew #check write access probew r3,r1,(r0) #001 check write access beql 1f #001 br if we can't movl $1,r0 #001 indicate success brb 2f #0011: clrl r0 #001 indicate failure2: bitl $1,r0 #set condition code # popr $^m<r0,r1,r2,r3> #restore registers (note: cond. codes popr $0x0f # preserved rsb #return # # search - search for condition handler # # this is a special internal routine that is called in the initial search # for a condition handler and on resignal from a previously signalled # condition. # # inputs: # # 00(ap) = number of condition arguments. # 04(ap) = address of signal argument list. # 08(ap) = address of mechanism argument list. # 12(ap) = number of mechanism arguments. # 16(ap) = fp of handler establisher frame. # 20(ap) = frame depth. # 24(ap) = saved r0. # 28(ap) = saved r1. # 32(ap) = flags longword # 36(ap) = number of signal arguments. # 40(ap) = exception name (integer value). # 44(ap) = first exception parameter (if any). # 48(ap) = second exception parameter (if any). # . # . # . # 40+n*4(ap) = n'th exception parameter (if any). # 40+n*4+4(ap) = exception pc. # 40+n*4+8(ap) = exception psl. # # outputs: # # r0 low bit clear indicates failure to locate condition handler. # # r0 = ss$_accvio - stack cannot be read from current mode. # # r0 = ss$_nohandler - no condition handler could be found. # # r0 low bit set indicates successful completion. # # r1 = address of condition handler. # search: #search for condition handler .word 0 #entry mask/* movab exe$sigtoret,(fp) #set address of condition handler */1: movl 16(ap),r0 #get previous frame address2: movpsl r1 #read current psl extzv $psl$v_curmod,$psl$s_curmod,r1,r1 #extract current mode incl 20(ap) #increment frame depth beql 5f #if eql first stack frame bgtr 4f #if gtr other stack frame/* movaq *$ctl$aq_excvec[r1],r0 #get address of exception vector quadword * cmpl $-2,20(ap) #examine primary vector? * beql 3f #if eql yes * tstl (r0)+ #adjust to secondary vector *3: movl (r0),r1 #get address of condition handler * bneq 6f #if neq condition handler found * brb 1b # */4: blbs 22(ap),0f #if lbs search count overflowL5: movpsl r1 #read current psl extzv $psl$v_curmod,$psl$s_curmod,r1,r1 #extract current mode #range check fp to make sure we are in #the right stack. this is crucial, since #there is no other mechanism to prevent #following the fp linkage into call #frames belonging to an outer mode./* cmpl r0,*$ctl$al_stack[r1] #frame pointer within stack range? bgtru 0f #if gtru no */ cmpl $psl$c_user,r1 #if in user mode beql L6 #skip top range check/* cmpl r0,*$ctl$al_stacklim[r1]#frame pointer within stack range? blssu 0f #if lssu no */L6: cmpl $sys$call_handl+4,savpc(r0) #call from condition dispatcher? beql 7f #branch if yes - must skip frames movl savfp(r0),r0 #get address of previous frame beql 0f #if eql noneL8: movl r0,16(ap) #save address of establisher frame5: # bsbb check_fp #check if this frame is valid movl (r0),r1 #get address of condition handler beql 1b #if eql none6: bisl2 $1,r0 #indicate successful completion ret #7: extzv $0,$12,savmsk(r0),r1 #get register save mask extzv $14,$2,savmsk(r0),-(sp) #get stack alignment bias addl2 $savrg,r0 #add offset to register save area addl2 (sp)+,r0 #add stack alignment bias8: blbc r1,9f #if lbc corresponding register not saved addl2 $4,r0 #adjust for saved register9: ashl $-1,r1,r1 #any more registers saved? bneq 8b #if neq yes movl chf$l_mcharglst+4(r0),r1 #get address of mechanism arguments movl chf$l_mch_frame(r1),r0 #get address of establisher frame tstl chf$l_mch_depth(r1) #check if this is a vectored handler blss L8 #if so, don't skip "establisher" brb L5 #0: movzwl $ss$_nohandler,r0 #set no handler found ret # # # subroutine to validate the current frame address. this is done with # a range check against the stack limit registers in the p1 vector page. # since fp linkages extend across access modes, there is no other check # possible to prevent chasing an inner mode exception out to an outer # access mode. #/*check_fp: * movpsl r1 #read current psl * extzv $psl$v_curmod,$psl$s_curmod,r1,r1 #extract current mode * cmpl r0,*$ctl$al_stack[r1] #frame pointer within stack range? * bgtru 100$ #if gtru no * cmpl $psl$c_user,r1 #if in user mode * beql 95$ #skip top range check * cmpl r0,*$ctl$al_stacklim[r1]#frame pointer within stack range? * blssu 100$ #if lssu no *95$: rsb #stack frame ok *100$: movzwl $ss$_nohandler,r0 #set no handler found * ret # */ # .text # # d. n. cutler 16-dec-76 # # modified by: # # v02-006 acg0261 andrew c. goldstein, 4-feb-1982 14:11 # fix skipping over vectored handler invocations # in nested exceptions. # # v02-005 acg0252 andrew c. goldstein, 11-jan-1982 17:02 # fix return status when newpc is specified # # v02-004 acg0242 andrew c. goldstein, 16-dec-1981 18:21 # fix unwinding to caller of establisher in nested exceptions, # allow unwinding out of ast's. # # v02-003 dwt0002 david w. thiel 10-nov-1981 11:10 # remove sys_call_handl+5 rsb. # use common condition handler. # # v02-002 acg0183 andrew c. goldstein, 31-dec-1980 11:23 # fix bug in unwinding to establisher frame # #** # # system service unwind procedure call stack # # macro library calls #/* * $chfdef #define condition handling arglist offsets * $ssdef #define system status values */ # # local symbols # # argument list offset definitions # # define depadr 4 #address of number of frames to unwind# define newpc 8 #change of flow final return address #+ # exe$unwind - unwind procedure call stack # # this service provides the capability to unwind the procedure call stack # to a specified depth after a hardware- or software-detected exception # condition has been signalled. optionally a change of flow return address # may also be specified. the actual unwind is not performed immediately by # the service, but rather the return addresses in the call stack are modified # such that when the condition handler returns the unwind occurs. # # inputs: # # depadr(ap) = address of number of frames to unwind. # newpc(ap) = change of flow final return address. # # r4 = current process pcb address. # # outputs: # # r0 low bit clear indicates failure to fully unwind call stack. # # r0 = ss$_accvio - call stack not accessible to calling access # mode. # # r0 = ss$_insframe - insufficient call frames to unwind to # specified depth. # # r0 = ss$_nosignal - no signal is currently active to unwind. # # r0 = ss$_unwinding - unwind already in progress. # # r0 low bit set indicates successful completion. # # r0 = ss$_normal - normal completion. #- .text # .entry exe$unwind,^m<r2,r3,r4,r5> .globl exe$unwindexe$unwind: .word 0x03c/* movab exe$sigtoret,(fp) #establish condition handler */ movl fp,r4 #set address of first frame to examine # # search call stack for a frame that was created by a call from the signal # dispatch vector or by a call from the unwind signal dispatcher. # movzwl $ss$_nosignal,r0 #assume no signal active1: movl savfp(r4),r4 #get address of previous frame beql 2f #if eql end of call stack cmpl $sys$call_handl+4,savpc(r4) #call from condition handler dispatcher? beql 3f #if eql yes cmpl $callunwind+4,savpc(r4) #call from unwind signal dispatcher? bneq 1b #if neq no movzwl $ss$_unwinding,r0 #set already unwinding2: ret # # # set to unwind procedure call stack to specified depth # 3: movl depadr(ap),r3 #get address of number of frames to unwind beql 4f #if eql none specified movl (r3),r3 #get number of frames to unwind brb 5f #4: movl r4,r2 #copy current frame address bsbw oldsp #calculate value of sp before call movl chf$l_mcharglst+4(r2),r2 #get address of mechanism argument list addl3 $1,chf$l_mch_depth(r2),r3 #calculate depth of establisher's caller5: bleq 9f #if leq no frames to remove moval startunwind,r0 #set condition handler unwind address bsbb setpc # # # scan through specified number of frames setting each frame to unwind on return # 6: movl savfp(r4),r4 #get address of previous frame beql 0f #if eql insufficient frames decl r3 #any more frames to consider? bgtr L10 #branch if yes tstl depadr(ap) #are we unwinding to caller of establisher? beql 9f #branch if yes - don't touch handler framesL10: cmpl $sys$call_handl+4,savpc(r4) #call from condition dispatcher? bneq 8f #if neq no
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -