.TITLE EG_RUNDOWN_INTERCEPTOR ; Prototype permanent per-process rundown routine. ;++ ; Module: EG_RUNDOWN_INTERCEPTOR ; ; Facility: EGRNDN ; ; Function: Intercept rundown of images and processes and ; dispatch for additional processing. ; ; Invocation Protocol: Called via JSB by SYS$RUNDWN or SYS$DELPRC ; through P1 dispatch vector entry. ; ; Input Parameters: ; ; R4 - Address of current PCB. ; R7 - Access mode parameter to $RUNDWN maximized with ; previous mode. (This parameter will be USER ; mode for image rundown, and KERNEL mode for ; process rundown. ; AP - Argument pointer existing when the $RUNDWN system ; service was invoked ; ; Environment: ; ; Kernel Mode, IPL = 0 for image rundown ; Activated by SYS$RUNDOWN with R7 = PSL$C_USER ; or R7 = PSL$C_KERNEL ; Kernel Mode AST for process rundown ; Activated by SYS$DELPRC with R7 = PSL$C_KERNEL ; ; Code must reside in a permanent portion of P1 space or ; S0 space (paged or non-paged pool). ; ; Side Effects: ; ; Can cause execution in context of supervisor mode ; AST in the case of process deletion. Execution ; of the AST will result in system logout command file ; execution in normal user context. ; ; Status Returns: ; ; If an initiating AST is dismissed, then ; SS$_NORMAL is returned in R0. ; Else ; There is no status return. ; Endif ; ; Notes: ; ; Revision: 1.0 20-Sep-1985 Larry L. Johnson ; in collaboration with ; Liz Bellamy of DEC, ; Dallas Regional Office. ; ; Language: VAX/VMS Macro-32 Assembler. ; ; Required Macro Libraries: ; STARLET The default VAX System Macro Library. ; (Automatically scanned.) ; LIB The master VAX System Macro Library. ; $CLIDEF ;Definitions for SYS$CLI invocation. $IPLDEF ;Definition of interrupt priority levels. $PHDDEF ;Process header definitions. $PRDEF ;Processor register symbols. $PCBDEF ;Process control block definitions. $IACDEF ;Image activator data areas. $IHDDEF ;Image header structure. $IHADEF ; " $IHIDEF ; " $PSLDEF ;Processor status longword constants. ; External Status References: ; ; Facility Defined Status Values: None ; VAX/VMS Common Run Time Library Status Values: None ; VAX/VMS RMS Status Values: None ; VAX/VMS System Service Status Values: None ; ; External Data References: None ; ; External Routine References: ; ; Facility Defined Routines: None ; VAX/VMS Common Run Time Library Routines: None ; VAX/VMS RMS Routines: None ; ; VAX/VMS System Services: ; ; $ASSIGN ; $CANCEL ; $CLI (Not supported by DEC) ; $CMKRNL ; $DASSGN ; $DCLAST ; $DCLCMH ; $QIOW ; ;-- .PAGE .SUBTITLE Rundown Macros ;....................................................................... ;... Local Macro Definitions ........................................... ;....................................................................... ; These macros are used for output of messages for demonstration ; purposes. .MACRO PUT_TO_SYSOUTPUT MESSAGE_NAME BSBW EGRNDN_OPEN_SYSOUTPUT_CHANNEL $QIOW_S - CHAN = SYSOUTPUT_CHANNEL, - FUNC = #IO$_WRITEVBLK, - P1 = 'MESSAGE_NAME', - P2 = #'MESSAGE_NAME'_SZ, - P4 = #^X00000020 BSBW EGRNDN_CLOSE_SYSOUTPUT_CHANNEL .ENDM PUT_TO_SYSOUTPUT .MACRO DECLARE_MESSAGE MESSAGE_NAME 'MESSAGE_NAME': .ENDM DECLARE_MESSAGE .MACRO END_MESSAGE MESSAGE_NAME MESSAGE_NAME'_SZ = .-'MESSAGE_NAME .ENDM END_MESSAGE .MACRO DEFINE_MESSAGE MESSAGE_NAME, MESSAGE_TEXT DECLARE_MESSAGE MESSAGE_NAME .ASCII "'MESSAGE_TEXT'" END_MESSAGE MESSAGE_NAME .ENDM DEFINE_MESSAGE .PAGE .SUBTITLE Data for Rundown Main Procedure ;....................................................................... ;... Local Read-Only Data Allocations .................................. ;....................................................................... .PSECT _EGRNDN_LOCAL_RO_DATA, - QUAD, CON, NOEXE, LCL, NOPIC, NOSHR, REL, NOWRT, NOVEC ;Messages used for demonstration purposes. DEFINE_MESSAGE RUNDOWN_MARKER_TEXT DEFINE_MESSAGE KERNEL_MARKER_TEXT DEFINE_MESSAGE MARK_FIRST_PASS_TEXT DEFINE_MESSAGE PROCESS_MARKED_FOR_DEL_TEXT DEFINE_MESSAGE IMAGE_EXIT_FORCED_TEXT DEFINE_MESSAGE RETURN_FROM_KERNEL_TEXT DEFINE_MESSAGE AST_TEXT DEFINE_MESSAGE USER_TEXT DEFINE_MESSAGE RESUMPTION_OF_SUPER_MODE ;....................................................................... ;... Local Writeable Data Allocations .................................. ;....................................................................... .PSECT _EGRNDN_LOCAL_RW_DATA, - QUAD, CON, NOEXE, LCL, NOPIC, NOSHR, REL, WRT, NOVEC ; Local Status Variable Allocations: None ; Local Variable Allocations: DECLARE_MESSAGE NONKERNEL_MARKER_TEXT .ASCII "Nonkernel Activation, Mode = " FORMATTED_MODE: .BYTE ^A"?" END_MESSAGE NONKERNEL_MARKER_TEXT ; Process status flags implemented here for now. Eventually ; destined for P1 Pointer Page or an "extended PCB" structure ; in non-paged pool. PROCSTSFLAGS: .LONG 0 EGPRCSTS_V_LOGOUTPND = 0 EGPRCSTS_V_DISMISSAST = 1 .PAGE .SUBTITLE Rundown Dispatcher Main Procedure ;....................................................................... ;... Executable ........................................................ ;....................................................................... .PSECT _EGRNDN_CODE, - QUAD, CON, EXE, LCL, NOPIC, NOSHR, REL, NOWRT, NOVEC RUNDOWN_BEGIN: ;************************************************************ ;******************** ENVIRONMENT ********************* ;* * ;* Kernel Mode * ;* (May or may not be running as kernel mode AST) * ;* * ;************************************************************ ;Output a marker message. PUT_TO_SYSOUTPUT RUNDOWN_MARKER_TEXT ;Determine if rundown requested for user or kernel mode. ;If rundown has been requested for user mode then ; Perform rundown services for user mode. CMPL R7, #PSL$C_USER BNEQ 10$ BSBW EGRNDN_USER_RUNDOWN BRB 30$ 10$: ;Else if rundown has been requested for kernel mode then ; Perform rundown services for kernel mode. CMPL R7, #PSL$C_KERNEL BNEQ 20$ BSBW EGRNDN_KERNEL_RUNDOWN PUT_TO_SYSOUTPUT RETURN_FROM_KERNEL_TEXT BRB 30$ 20$: ;Else ; Do nothing. The meaning of requests to ; rundown for supervisor or executive modes ; is unknown... Allow routine to return to ; caller to let him do as he pleases. ;Endif 30$: ;Return from this routine. ; Check to see if we are to make normal return (RSB) to ; caller, or to issue a RET (normally to dismiss a ; $DELPRC AST). ;If dismiss AST flag has not been set then ; Return to caller in normal fashion. BBSC #EGPRCSTS_V_DISMISSAST, PROCSTSFLAGS, DISMISS_AST RSB ;Else ; Software has detected that it has been invoked ; in AST context and has determined that the ; AST calling rundown is to be dismissed. DISMISS_AST: ;************************************************************ ;******************** ENVIRONMENT ********************* ;* * ;* Kernel Mode AST * ;* * ;************************************************************ MOVL #SS$_NORMAL, R0 RET ;Endif .PAGE .SUBTITLE Rundown for User Mode (Image Termination) ;User Mode Rundown Functions. Assumes the function is ; image rundown. EGRNDN_USER_RUNDOWN: ;************************************************************ ;******************** ENVIRONMENT ********************* ;* * ;* Kernel Mode * ;* * ;************************************************************ ;Calculate ASCII form of access mode for output message, ; and put it to SYS$OUTPUT. ADDB3 #^X30, R7, FORMATTED_MODE PUT_TO_SYSOUTPUT NONKERNEL_MARKER_TEXT BSBW OUTPUT_IMAGE_NAME ;Specify normal return to caller of Rundown Facility ; and leave this routine. BICL2 #<1@EGPRCSTS_V_DISMISSAST>, PROCSTSFLAGS RSB .PAGE .SUBTITLE Kernel Rundown (Logout) EGRNDN_KERNEL_RUNDOWN: ;************************************************************ ;******************** ENVIRONMENT ********************* ;* * ;* Kernel Mode * ;* * ;************************************************************ PUT_TO_SYSOUTPUT KERNEL_MARKER_TEXT ;#++ ;If process deletion is pending, then BBS #PCB$V_DELPEN, PCB$L_STS(R4), 10$ BRW PROCESS_RUNDOWN_END 10$: ;************************************************************ ;******************** ENVIRONMENT ********************* ;* * ;* Kernel Mode AST * ;* * ;************************************************************ ;If logout command procedure has not been run then BBSS #EGPRCSTS_V_LOGOUTPND, PROCSTSFLAGS, - ACTIVATE_LOGOUT_FILE_END ; Recover from process deletion by: ; ...clearing the delete pending bit in ; the PCB at synch IPL, and... SETIPL #IPL$_SYNCH BICL2 #PCB$M_DELPEN, PCB$L_STS(R4) SETIPL #0 ; ...marking the process status flags for dismissal ; of the kernel mode process deletion AST ; (i.e., abort the process deletion). BISL2 #<1@EGPRCSTS_V_DISMISSAST>, PROCSTSFLAGS ; Declare a supervisor mode AST to force the ; activation of the system-wide command file ; on the dismissal of this kernel mode AST. $DCLAST_S - ASTADR = EGRNDN_VECTOR_TO_EGLOGOUT, - ACMODE = #PSL$C_SUPER ;Else ACTIVATE_LOGOUT_FILE_END: ;Do nothing, allowing the process to continue ; to deletion since the command file has ; already been run. ;Endif ;Else PROCESS_RUNDOWN_END: ;************************************************************ ;******************** ENVIRONMENT ********************* ;* * ;* Kernel Mode * ;* (May or may not be in AST context) * ;* * ;************************************************************ ;Do nothing, the context of this call is not understood, if ; it is not a process deletion. ;Endif ;Return to caller RSB .PAGE .SUBTITLE Force Logout Command File Execution ;************************************************************ ; Force logout command file execution. ; ; This is accomplished by calling the CLI callback routine. This ; routine must be executed in User Mode. This code is first entered ; through a supervisor mode AST. Since the CLI needs to be called ; from User mode, the supervisor mode AST builds a new PSL with ; mode = user and REIs to the user mode code. The user mode code ; calls the CLI with a command form of @command_procedure. Return to ; supervisor mode is accomplished by CHMS which is intercepted by ; a Supervisor change mode handler established by the Supervisor ; mode AST. ; ;....................................................................... ;... Local Writeable Data Allocations .................................. ;....................................................................... .PSECT _EGRNDN_LOCAL_RW_DATA, - QUAD, CON, NOEXE, LCL, NOPIC, NOSHR, REL, WRT, NOVEC ;PSL fabricated for switch to user mode. NEW_PSL: .LONG 0 ;CLI Callback Request data block. CLI_REQ_BLOCK: .BLKB CLI$K_SRVDESC ;Location of original supervisor change mode handler. OLD_HANDLER: .LONG 0 ;Original user stack profile. OLD_PR$_USP: .LONG 0 OLD_USER_CTL$AL_STACK: .LONG 0 OLD_USER_CTL$AL_STACKLIM: .LONG 0 ;Local stack for user mode code. USER_STACK_BOTTOM: .BLKB ^X200 USER_STACK: USER_STACK_SIZE = .-USER_STACK_BOTTOM USER_STACK_ADDRESS: .ADDRESS USER_STACK ;....................................................................... ;... Local Read-Only Data Allocations .................................. ;....................................................................... .PSECT _EGRNDN_LOCAL_RO_DATA, - QUAD, CON, NOEXE, LCL, NOPIC, NOSHR, REL, NOWRT, NOVEC ;Command activating system-wide logout command procedure. EG_LOGOUT_COMMAND_STR: .ASCII "@SYSTEM_WIDE_LOGOUT_COMMAND_FILE" EG_LOGOUT_COMMAND_SIZE = .-EG_LOGOUT_COMMAND_STR ;....................................................................... ;... Executable ........................................................ ;....................................................................... .PSECT _EGRNDN_CODE, - QUAD, CON, EXE, LCL, NOPIC, NOSHR, REL, NOWRT, NOVEC ;************************************************************ ;******************** ENVIRONMENT ********************* ;* * ;* Supervisor Mode AST * ;* * ;************************************************************ EGRNDN_VECTOR_TO_EGLOGOUT: .WORD ^M ;Register Usage: ; ; R9 = Address of CLI callback request description block. ; R10 = Address of process permanent data region (PPD). PUT_TO_SYSOUTPUT AST_TEXT ;Cancel outstanding I/O on SYS$INPUT channel. (Can't write to ; SYS$OUTPUT terminal if there is outstanding read with prompt ; on the same device via SYS$INPUT). ;Get address of Process Permanent Data region (PPD). MOVAB @#CTL$AG_CLIDATA, R10 ;Cancel I/O on the input channel recorded there. $CANCEL_S - CHAN = PPD$W_INPCHAN(R10) ; ; Set up user stack. ; (We may or may not have a valid user stack at this point. To ; assure a valid stack we will establish a local one, saving the ; context of any existing user stack to enable it to rundown ; normally). ; $CMKRNL_S - ROUTIN = SETUP_USER_STACK ; ; Declare a supervisor change mode handler so we can get back from user mode ; $DCLCMH_S - ADDRES=SUPER_HANDLER, - PRVHND=OLD_HANDLER ; ; Force mode to USER in order to make call to CLI callback routine. ; ; Get the current PSL and force its modes to user. ; Push the PSL and the PC of continuation on the stack ; and REI to change the mode. MOVPSL NEW_PSL INSV #PSL$C_USER,#PSL$V_CURMOD,#PSL$S_CURMOD,NEW_PSL INSV #PSL$C_USER,#PSL$V_PRVMOD,#PSL$S_PRVMOD,NEW_PSL PUSHL NEW_PSL PUSHAL USER_CODE REI ;************************************************************ ;******************** ENVIRONMENT ********************* ;* * ;* SUPERVISOR mode AST lowered to USER mode. * ;* * ;************************************************************ ; ; User mode code - Call the CLI to execute our command procedure then ; return back to supervisor with a CHMS ; USER_CODE: PUT_TO_SYSOUTPUT USER_TEXT ; ; Setup CLI request block to point to the command we want to execute. ; ; This code is modeled after the LIB$DO_COMMAND procedure which ; could not be used since it issues a call to SYS$EXIT as a last ; act. We may not have an outstanding image to rundown which would ; cause a "trap" for the next image activation, forcing it out ; immediately. When DCL executes the first USER image via the ; command file, it will rundown the image if necessary. ; MOVAL CLI_REQ_BLOCK, R9 MOVB #CLI$K_CLISERV, CLI$B_RQTYPE(R9) MOVW #5, CLI$W_SERVCOD(R9) MOVW #EG_LOGOUT_COMMAND_SIZE, CLI$Q_RQDESC(R9) MOVAL EG_LOGOUT_COMMAND_STR, CLI$Q_RQDESC+4(R9) ;Callback the CLI. PUSHAL CLI_REQ_BLOCK CALLS #1, G^SYS$CLI ; ; Go back to supervisor mode via our change mode handler. ; CHMS #-1 ; ;************************************************************ ;******************** ENVIRONMENT ********************* ;* * ;* SUPERVISOR mode AST * ;* * ;************************************************************ ; ; Supervisor Change Mode Handler ; SUPER_HANDLER: ; ; If change mode code is not ours (i.e., not negative) then ; Transfer operation to the original handler. ; TSTL (SP) BLSS 10$ JMP @OLD_HANDLER 10$: ; ; Else ; ;Output a marker message PUT_TO_SYSOUTPUT RESUMPTION_OF_SUPER_MODE ; Reinstate the original supervisor change mode handler, ; we don't need ours any longer. $DCLCMH_S - ADDRES = @OLD_HANDLER ;Reset the stack to get rid of the stuff put ; there by our change mode instruction. ; (Three longwords: the change mode code, PC and PSL). MOVAL 12(SP),SP ; Restore user stack. (Just in case there was an ; active image which requires rundown and therefore ; should be left with a valid user stack context). $CMKRNL_S - ROUTIN = RESTORE_USER_STACK ; Dismiss supervisor mode AST RET ;************************************************************ .PAGE .SUBTITLE EGRNDN User Stack Utilities. ;************************************************************ ; EGRNDN User Stack Routines. ; ; Kernel Mode routines to: ; ; 1. Setup a user stack, saving the original stack context ; 2. Restore original stack context saved in the setup of ; the new stack area. ; ; The user stack context consists of the following three data: ; ; 1. The user stack processor register (PR$_USP). ; 2. The stack pointer in the P1 pointer page (@#CTL$AL_STACK+12, ; the last element in a four element array.) ; 3. The stack size in the P1 pointer page (@#CTL$AL_STACKLIM+12, ; the last element in a four element array.) ;------------------------------------------------------------ ; Kernel mode routine to save original user stack context and ; establish a new one. SETUP_USER_STACK: .WORD ^M ;Register Usage: ; ; R4 = Usual current PCB address of kernel mode routine. ;Save origninal stack context. MFPR #PR$_USP, OLD_PR$_USP MOVL @#CTL$AL_STACK+12, OLD_USER_CTL$AL_STACK MOVL @#CTL$AL_STACKLIM+12, OLD_USER_CTL$AL_STACKLIM ; Establish new user stack in local storage by appropriately ; setting the same three items. MTPR USER_STACK_ADDRESS, #PR$_USP MOVAL USER_STACK, @#CTL$AL_STACK+12 MOVL #USER_STACK_SIZE, @#CTL$AL_STACKLIM+12 RET ;------------------------------------------------------------ ; Kernel Mode routine to restore saved context of user stack ; RESTORE_USER_STACK: .WORD ^M ;Register Usage: ; ; R4 = Usual current PCB address of kernel mode routine. MTPR OLD_PR$_USP, #PR$_USP MOVL OLD_USER_CTL$AL_STACK, @#CTL$AL_STACK+12 MOVL OLD_USER_CTL$AL_STACKLIM, @#CTL$AL_STACKLIM+12 RET ;************************************************************ .PAGE .SUBTITLE EGRNDN I/O Utilities. ;************************************************************ ; EGRNDN I/O utilities. ;....................................................................... ;... Local Read-Only Data Allocations .................................. ;....................................................................... .PSECT _EGRNDN_LOCAL_RO_DATA, - QUAD, CON, NOEXE, LCL, NOPIC, NOSHR, REL, NOWRT, NOVEC ; Descriptor for notification device. SYSOUTPUT_DEVICE: .ASCID "SYS$OUTPUT" ;....................................................................... ;... Local Writeable Data Allocations .................................. ;....................................................................... .PSECT _EGRNDN_LOCAL_RW_DATA, - QUAD, CON, NOEXE, LCL, NOPIC, NOSHR, REL, WRT, NOVEC ;Channel for terminal communication. (This will not work properly ; for a batch job). SYSOUTPUT_CHANNEL: .WORD 0 ;....................................................................... ;... Executable ........................................................ ;....................................................................... .PSECT _EGRNDN_CODE, - QUAD, CON, EXE, LCL, NOPIC, NOSHR, REL, NOWRT, NOVEC ;------------------------------------------------------------ ; Open a channel for rundown messages for demonstration ; purposes. EGRNDN_OPEN_SYSOUTPUT_CHANNEL: $ASSIGN_S - DEVNAM = SYSOUTPUT_DEVICE,- CHAN = SYSOUTPUT_CHANNEL,- ACMODE = #PSL$C_KERNEL RSB ;------------------------------------------------------------ ; Close the rundown message channel. EGRNDN_CLOSE_SYSOUTPUT_CHANNEL: $DASSGN_S - CHAN = SYSOUTPUT_CHANNEL RSB ;************************************************************ ;....................................................................... ;... Local Read-Only Data Allocations .................................. ;....................................................................... .PSECT _EGRNDN_LOCAL_RO_DATA, - QUAD, CON, NOEXE, LCL, NOPIC, NOSHR, REL, NOWRT, NOVEC IMAGE_NAME_TITLE: .ASCII /Image = / IMAGE_NAME_TITLE_SZ = .-IMAGE_NAME_TITLE ;....................................................................... ;... Executable ........................................................ ;....................................................................... .PSECT _EGRNDN_CODE, - QUAD, CON, EXE, LCL, NOPIC, NOSHR, REL, NOWRT, NOVEC OUTPUT_IMAGE_NAME: OUTPUT_IMAGE_NAME_MASK = ^M PUSHR #OUTPUT_IMAGE_NAME_MASK MOVL @#MMG$IMGHDRBUF, R2 ;Address of image header buffer. MOVZWL IHD$W_IMGIDOFF(R2), R3 ;Offset to image id section ADDL2 R3, R2 ;Address of image id section MOVAL IHI$T_IMGNAM(R2), R2 ;Address of counted string. MOVZBL (R2)+, R3 ;Address of count in R3 leaving ; address of string in R2. BSBW EGRNDN_OPEN_SYSOUTPUT_CHANNEL $QIOW_S - CHAN = SYSOUTPUT_CHANNEL, - FUNC = #IO$_WRITEVBLK, - P1 = IMAGE_NAME_TITLE, - P2 = #IMAGE_NAME_TITLE_SZ, - P4 = #^X00000024 $QIOW_S - CHAN = SYSOUTPUT_CHANNEL, - FUNC = #IO$_WRITEVBLK, - P1 = (R2), - P2 = R3, - P4 = #^X0000002B BSBW EGRNDN_CLOSE_SYSOUTPUT_CHANNEL POPR #OUTPUT_IMAGE_NAME_MASK RSB ;************************************************************ RUNDOWN_END: .END RUNDOWN_BEGIN