OpenVMS Alpha provides a feature called a user-supplied executive image.This is a mechanism
for providing code and/or data in system space for access by all
processes on the system.Since these memory pages are in system space,
all processes see them at the same address.They may be read from any
mode, but only written from kernel mode.
One use of a user-supplied executive image is for one process to force another process to
execute a particular piece of code.The sample provided here will do
just that.
In this example, a process registers itself by running an image which
executes the user-supplied executive image's routine set_value.Since the registration involves
modifying a datum in the user-supplied executive image (which can only be done from kernel
mode), this call goes through a user-written system service which will
run the user-supplied executive image's routine in kernel mode.
Any process can find the internal PID of the process that is currently
registered by running the get_value routine in the user-supplied executive image.This
involves reading a datum in the user-supplied executive image, which can be done from any
mode.Consequently the use of a user-written system service is not
required to perform this operation.
The final piece of functionality offered by the user-supplied executive image is to cause the
registered process to execute the print_it function.This involves
calling the internal routine SCH$QAST which requires execution from an
elevated mode.
Here is the code for the user-supplied executive image:
MY_EXECLET.MAR
Here is the code for the User-Written System Service:
MY_UWSS.MAR
Here is the code for the executable test harness:
CALL_MY_EXECLET.C
Here are the commands to build and install the pieces:
BUILD_IT.COM
Assuming that is done, here is a stylized log of a session using these routines.
Process A Process B
--------------------------------------------------------------------------------------------------------------------------
$ MCR call_my_execlet s |
|$ MCR call_my_execlet g
|value is 10034
|$ MCR call_my_execlet p
|%SYSTEM-F-NOPRIV, insufficient privilege or object protection violation
|$ SET PROCESS/PRIVILEGES=CMKRNL
|$ MCR call_my_execlet p
Process with PID 00000134 |
Executing routine PRINT_IT with a PD of 817B22F0|
First instruction is at 84B76130|
Other useful information: As provided, this user-supplied executive image is loaded as boot
time via SYSMAN.It could also be loaded on a running system with the
ability to be unloaded and reloaded (the reload feature is not available if
loaded at boot time).
If this were done, users of the user-supplied executive image should also make references to the image
so that the unload code would not unload the user-supplied executive image while it is in use
by another image.Information on calling these undocumented routines is provided later in this FAQ.
The routines to load and unload a user-supplied executive image, LDR$LOAD_IMAGE and LDR$UNLOAD_IMAGE, are documented in the
OpenVMS Programming Concepts Manual.
Following is a description of routines which
retrieve information about user-supplied executive images and which make and
remove references to them.
More information on user-supplied executive images may be found in the
OpenVMS Programming Concepts Manual in the section titled "Accessing Another Process's Context."
As a final note, it may be useful for a user-supplied executive image to know its name.The
initialization routine receives the address of the loaded image data
block (defined by ldrimgdef.sdl) as the first parameter.This structure
contains the name of the user-supplied executive image.
LDR$REF_INFO
;+
; Functional Description:
;
; This routine is called to return reference information for an unloadable
; exec image. The image must be fully loaded with a valid loaded
; image block.
;
; Environment:
;
; mode - kernel, ipl-0
;
; Input Parameters:
;
; - reference information handle (see SYS$MAKE_REF or
; SYS$REMOVE_REF)
; - filename descriptor
;
; Output Parameters:
;
; R0 - 1, if valid, unloadable exec image and reference
;information duly filled in.
; R0 - LBC otherwise.
;-
SYS$MAKE_REF
;+
;
; This system service grants access toan unloadable exec image.
; Unloadable exec images may choose to adopt the system loader's
; mechanism for tracking references.
; An application must call $make_ref for each access of the exec
; image. If the exec image is marked 'unload-pending', access is
; denied (by returning error status in R0).
; Each $make_ref must be followed by $remove_ref to avoid nasty
; consequences.
;
; Inputs:
;
; 4(AP) = Address of reference information handle.
;
; The reference information handle has three longwords.
; It has the following format.
;
; +-------------------------------------------+
; | base address of image |
; +-------------------------------------------+
; | address of loaded image block |
; +-------------------------------------------+
; | sequence number |
; +-------------------------------------------+
;
; The reference information handle is filled by ldr$load_image.
; Alternatively, the contents may be obtained by calling
; ldr$ref_info
;
; Output:
;
; R0 = ss$_normal or
;loader$_unl_pen or
;loader$_not_unl
;
; Side Effects:
;
; If the exec image is not marked for unload, the reference count
; is incremented.
;-
SYS$REMOVE_REF
;+
;
; This system service marks the end of reference for an unloadable exec image.
; Unloadable exec images may choose to adopt the system loader's
; mechanism for tracking references by using sys$make_ref and sys$remove_ref
; before and after each access.
; Each $make_ref must be followed by $remove_ref to avoid nasty
; consequences
; It is the responsibility of the application to ensure that all accesses
; are preceded and succeeded by $make_ref and $remove_ref respectively.
;
;
; Inputs:
;
; 4(AP) = Address of reference information handle.
;
; The reference information handle has three longwords.
; It has the following format.
;
; +-------------------------------------------+
; | base address of image |
; +-------------------------------------------+
; | address of loaded image block |
; +-------------------------------------------+
; | sequence number |
; +-------------------------------------------+
;
; The reference information handle is filled by ldr$load_image.
; Alternatively, the contents may be obtained by calling
; ldr$ref_info
;
; Output:
;
; R0 = ss$_normal or
; ss$_badparam, ss$_accvio, loader$_badrefcnt
;
; Side Effects:
;
; If the exec image is not marked for unload, the reference count is
; decremented.If the image is marked for unload and this reference has
; caused the reference count to go down from 1 to 0, this process traverses
; system space for a while.
;-