Create a set of transfer vectors for
the symbols (OpenVMS VAX):
The OpenVMS VAX shareable image transfer vectors are located at a
known position within the shareable image -- typically at the
front -- and the various offsets are used to dispatch the run-time
calls into the actual code position(s) within the shareable image.
Use of consistent offsets means callers do not need to relink the
calling image(s) when the shareable image is modified.
An example transfer vector -- XFRVEC.MAR -- looks like this:
.title$$$XFRVEC facnam_SHR Transfer Vectors
.ident/facnam_SHR V1.0-0/
; create a program section to hold just the vectors
; keep all transfer vectors quadword aligned.
.psect$$$XFRVEC,exe,shr,nowrt,rd,pic,quad
; For routines entered via a CALLS or CALLG instruction:
.macroXFRVEC_CALL entry_point,entry_point_int
.alignQUAD
.transfer entry_point
.External entry_point_int
.mask entry_point_int
JMP l^entry_point_int+2
entry_point:: ; allows .transfer to work.
.endm
; define a macro to simplify creating a transfer vector
; to a routine located in the shareable image.
.macroXFRVECentry_point
.alignQUAD
.transfer entry_point
.mask entry_point
JMP l^entry_point+2
.endm
; define a macro that places a longword constant directly
; into the transfer vector array.
.macroXFRCONconstant
.alignQUAD
.long constant
.endm
; and start defining the transfer vectors...
XFRCON42
XFRVECentry_point_name1,entry__point_name1
XFRVECentry_point_name2,entry__point_name2
.End
Use the above template for building a set of transfer vectors.
You will need to substitute the externally visible symbols --
those symbols that you determined
should be visible outside the shareable image
-- in place of the example entry point names (entry_point_name1 or
entry_point_name2) used in the template.
You do not need to change the symbol names of any externally
visible symbols.You can (and probably should) use the same
name in the transfer vectors (the transfer vectors are the
.TRANSFER-created stuff in the MACRO32 file) as you have used
in the code or data in the object file(s).The symbol used in
the transfer vector will be the one visible to the callers of
the shareable image. The linker knows that a TRANSFER may
duplicate another internal symbol.(The linker uses the value
from the transfer directive when it builds the externally-visible
shareable image symbol table -- shareable and executable images
that link against the shareable image never realize there is a
second (internal) symbol of the same name, since it is not
included in the externally-visible shareable image symbol table.)
(Note that this means all calls to an external entry point that
are made from within a shareable image do not use the
shareable image transfer vector, these calls directly call the
internal entry point of the same name.)
Put in as many occurences of XFRVEC as you need.Always add new
transfer vectors to the end of the list.Never reorder the list.
Do not remove any existing vectors.(Jump to a dummy routine
that returns a failure status, if you must.)(Reordering the
list of vectors or removing individual vectors will tend to
break existing applications that are linked against the
shareable image.)
If you really must change the order or remove a vector -- you
have decided you must make an incompatible change -- further
information on the GSMATCH option is
available.
Create a set of SYMBOL_VECTOR
transfer vectors in the LINKER options file for the symbols (OpenVMS Alpha):
SYMBOL_VECTOR = ( entry_point_name1 = PROCEDURE,-
entry_point_name2 = PROCEDURE )
The OpenVMS Alpha LINKER implements the transfer vectors using
the LINKER options file and the image symbol table.(The design
of the Alpha Alpha pipelining and branch prediction makes the
OpenVMS VAX transfer vector scheme rather expensive.)The shareable
image support is otherwise the same.Rephrased: a Macro (the language)
file containing transfer vectors is not required on OpenVMS
Alpha.It's all done in the LINKER options file...
It is possible that a large or complex symbol vector may exceed
the capacity of the LINKER to process a single line in the options
file.If this occurs, multiple SYMBOL_VECTOR declarations can be
used.
Always add new SYMBOL_VECTOR entries to the end of the list.Never
reorder the list.Do not remove any existing vectors.(Jump to a
dummy routine that returns a failure status, if you must.)(Reordering
the list of vectors or removing individual vectors will tend to break
existing applications that are linked against the shareable image.)
For declaring a transfer vector for data, use the following lines
in the OpenVMS Alpha LINKER options file:
SYMBOL_VECTOR = ( variable1 = DATA,-
variable2 = DATA )
Procedure to create common entry points (OpenVMS VAX and Alpha):
It is quite possible to create a small command procedure that
produces either a linker options file or a transfer vector
array, based on the contents of a list of entry points -- this
procedure would allow maintenance of one source file for both
varieties (OpenVMS VAX and Alpha) of transfer vector.
Adapt the following example procedure for your
environment and files (OpenVMS VAX):
The following command procedure assumes that the objects, object
libraries, and/or shareable images specific to the application have
already been created, and that the necessary
Macro32 module containing the transfer vectors
has already been created, and thus that this procedure
need only specify the components and commands specifically necessary for
the shareable image LINK operation.This particular example assumes that
all application object modules are included in the object library named
facnam_SHR.OLB.
$!LINK.COM
$!
$!This is an example of how to convert a user-created,
$!application-specific object library, facnam_SHR.OLB,
$!into an OpenVMS shareable image...
$
$!Assemble the transfer vectors...
$!
$ Macro xfrvec.mar /Object=Sys$Scratch:$$$XFRVEC
$
$!Now create the link options file on the fly...
$
$!Force any existing LNKOUT output file closed...
$!
$ Close/NoLog LNKOPT
$
$!Now open and populate the LNKOPT linker options
$!output file...
$!
$ Open/Write LNKOPT Sys$Scratch:$$$xfrvec.opt
$!The (CLUSTER and COLLECT directives are present
$!to pull the transfer vectors to the very front
$!of the shareable image.)
$ Write LNKOPT"Cluster=$$$XFRVEC"
$ Write LNKOPT"Collect=$$$XFRVEC,$$$XFRVEC"
$ Write LNKOPT"GSMATCH=LEQUAL,19,88"
$ Write LNKOPT"IDENTIFICATION=""facnam V1.0"" "
$ Close LNKOPT
$
$!Pull everything together...
$!
$ Link -
/Shareable=facnam_SHR.EXE -
/Symbol=facnam_SHR.Stb -
/Map=facnam_SHR.Map -
/NODEBUG /NOTRACEBACK -
Sys$Scratch:$$$XFRVEC.Obj, -
Sys$Scratch:$$$XFRVEC.Opt/Option, -
facnam_SHR.OLB/Lib
$
$!And clean up
$!
$ Delete Sys$Scratch:$$$XFRVEC.Obj.*
$ Delete Sys$Scratch:$$$XFRVEC.Opt.*
$
$ Exit
$
OpenVMS Alpha shareable images Macro32 transfer vector modules:
OpenVMS Alpha shareable shareable images do not require a Macro32
transfer vector module, the linker options file replaces this
module.
Evaluate the PSECTs for Shareability:
Look through the image /MAP produced by the image LINK.In
particular, locate ANY variables that have both the PSECT
(program section) attribute of "SHR" (shareable) and "WRT"
(writeable).Make these variables NOSHR (not shareable) or
NOWRT (not writeable) -- how to do this is further discussed
later in this section.
If you fail to make all shareable PSECTS non-writable, you will
have writeable variables shared between processes, and this
typically leads to undesirable consequences.
If both "WRT" and "SHR" are desired, you will have to INSTALL the
shareable with the /WRITEABLE option before anyone can use it.
Using this qualifier also restricts installation to a single
node in a VMScluster.
Also make certain that all code in the shareable is position
independent code (PIC). (All Digital VAX high level languages
typically produce position independent code -- watch out for
code written in MACRO32, however.It is quite possible to write
position dependent code in MACRO32.)
VAX C has several documented "quirks" involving "extern",
"globalref", "globaldef" and "globalvalue" declarations.
Each "extern" creates a seperate PSECT.The "global*"
declarations typically all get placed in the same PSECT.
Also note that C extern variables are visible to callers
of the shareable image -- the LINKER effectively translates
them into UNIVERSAL or TRANSFER type symbols.(As a matter
of preference, some folks tend to avoid using extern and
global* symbols as much as is possible -- for reasons of
personal preference, flexibility and modularity.If one
cannot avoid extern or global* symbols, or that a particular
situation is made easier by using them, consider using
one or two extern structures -- which allows as many
variables as needed, without creating a volume of external
symbols. And as is to be expected, one should ALWAYS use
unique facility prefixes on any extern or global* symbols.
This helps avoid symbol name collisions.)
DEC C supports various external model pragmas, and these
provide better control of the external declarations.
Should you wind up with a PSECT marked SHR and you want it NOSHR,
you can copy the other PSECT attributes and a NOSHR onto a
PSECT_ATTR directive in the LINKER options file. (This is a
`brute force' method -- fixing the problem(s) by adding a
language keyword (eg: "noshare" in VAX C) in the source is a
better long term solution.) The following command procedure
can be used to scan the LINK map looking for the WRT, SHR
attribute combination.
$!PSECT_SCAN.COM - This procedure uses $SEARCH to find any
$!PSECTs marked both SHR and WRT.Any such lines lines
$!lines must be redefined as NOSHR,WRT with a PSECT_ATTR
$!line in the linker or by using a language-specific
$!directive such as the VAX C "noshare" storage modifier.
$!
$!
$
$ search facnam_SHR.map " SHR,"," WRT,"/MATCH=AND -
/output=SYS$SCRATCH:facnam_SHR_SHR-WRT.tmp
$ save_status = $status
$ If save_status .eqs. "%X00000001"
$ Then
$ ! Successful status means a bad PSECT combination was detected.
$ Write Sys$Output "Invalid PSECT attributes have been detected."
$ Write Sys$Output "The PSECT(s) requiring adjustment(s) are:"
$ Type SYS$SCRATCH:facnam_SHR_SHR-WRT.tmp
$ Exit 9
$ Endif
$ If save_status .eqs. "%X08D78053"
$ Then
$ ! Here, "no strings matched" means that you have no problem(s).
$ Write Sys$Output "Successful PSECT_SCAN completion."
$ Write Sys$Output "No invalid PSECT attributes have been detected."
$ Delete SYS$SCRATCH:facnam_SHR_SHR-WRT.tmp;*
$ Exit 1
$ Endif
$ Exit 1
Debugging:
Adapt the LINK.COM command procedure to allow /TRACEBACK and/or
/DEBUG during testing and development.(But by all means, do
not ship the shareable image with those options....)
To facilitate debugging, you will typically need to compile with
qualifiers such as /DEBUG and /NOOPTIMIZE, and LINK with /DEBUG.
The debugger "SET IMAGE" command allows you to access and debug
shareable image.
The INSTALL utility, to prevent security problems, is explicitly
coded to refuse installation of any images linked with /TRACEBACK
or with /DEBUG.See the comments on INSTALL,
below.
Set the Shareable Image Version and Matching:
To update the minor version of the GSMATCH
line (`88' in the above LINK.COM command procedure) whenever making
upward-compatable changes. Update the major version (`19' in the
example) when making incompatable changes.
Updating the minor version means programs linked against a
new shareable will fail when an attempt is made to run the
image against an older shareable.Updating the major version
forces all images linked against the shareable to be relinked.
Programs linked against an older shareable image will work
with a newer shareable image.(Assuming both have the same
major version number.)
A few examples of incompatable changes:
- re-ordered or removed transfer vectors...
- routines of the same name that no longer return the
same status values... (One may see routines return
a NOTIMPL or other status, when the routine is no
longer needed.)
- routines that change the documented behaviour of the
shareable image in undocumented ways.
A few examples of upward compatable changes:
- new entry points are added at the end of the transfer vectors.
- a bug is fixed in a routine
- a new argument is added in an existing routine
and the routine knowns how to deal with calls
with differing numbers of arguments.
- An older routine is no longer needed, and is updated
to call the replacement routine directly, or is updated
to do nothing of consequence other than return a valid
and previously-documented status code.
Update the IDENTIFICATION option:
Update the image IDENTIFICATION string.This string is included in
the LINKER options file.In the above example,
this file is dynamically created by the example command procedure
shown above.This string should be altered whenever making releases,
so that it is obvious what product the shareable is part of.It is
also often useful to encode a version string and a build baselevel
number, to indicate which version and build baselevel the shareable
image represents.
The DIGITAL Software Engineering Standards requires that all
DIGITAL products place their registered product name and version
in this field. (And even if one is not developing a "real"
product, this is still considered polite programming practice.)
Some shareable images deliberately preallocate a series of dummy
transfer vectors within the sharable image transfer vector array,
and the programmers then reassign these vectors as newer routines
are added.This technique avoids having to increment the GSMATCH
version whenever newer routines are implemented or updated, easing
the application compatibility across multiple versions of the
shareable image.This technique can be useful when there are
frequent changes during debugging, and in cases where both
upward and downward compatibility can be maintained.However,
this technique removes any chance of catching cases of newer
applications running against older and potentially incompatible
shareable images, and the shareable image programmers must use
particular care to maintain both upward and downward compatibility
of the interface across the entire series of shareable image
versions sharing the same GSMATCH value.
When a transfer vector does not reference an actual routine,
it must return an application status code that indicates the
routine is not currently implemented in the library.Further,
it is imperative that the shareable image identification be
maintained, so that there is some indication of what is
contained within a particular copy of the shareable image.
When using shareable images that use the same GSMATCH value
and the dummy transfer vector technique, all applications that
reference the shareable image should be coded to expect an
application-defined NOTIMPL status, should the application
be invoked against an older shareable image, a version that
predates the necessary support.(This is one of the cases
that most programmers will depend on GSMATCH to detect and
prevent, and this is one of the reasons why most shareable
images should increment the minor GSMATCH whenever changes
are made to the shareable image.)
Errors and Resolutions:
%LINK-E-OUTSIMG
Sometimes you will see LINK-E-OUTSIMG errors.These
errors are often due to an attempt to write data into
a shareable image you are trying to link against.
(This error can obviously occur during an attempt to
initialize an external symbol.)
This error can also occur as a result of a bug in the
image section processing in the LINKER utility -- if
the address is above 64K pages (hex 02000000), this
error can be generated.(Work with the options file
to reduce the size of the image section below 64K
pages.)This bug is present in the LINKER in OpenVMS
V5.5-2, and possibly in later versions.
%SYSTEM-F-VECFULL
Under OpenVMS, various vectors are used to track special image
components.
There are vectors for up to 42 seperate kernel-mode dispatchers,
for up to 42 executive-mode dispatchers, for up to 42 image run-down
routines, for up to 42 RMS dispatchers, and up to 64 message sections.
For further information, see the Internals and Data Structures
Manual (IDSM).
If the capacity of any of these vectors is exceeded, a run-time
SS$_VECFULL error message will be generated.
Because of these vector limits, one can create an executable
image that incorporates references to at most 42 seperate privileged
shareable images.
On OpenVMS V7.1 and later, duplicate message section entries are
suppressed.
%SYSTEM-F-NOTINSTALL
When an attempt is made to execute an image that contains
one or more writeable shareable program sections (PSECTs),
the image activator will return the SS$_NOTINSTALL error message.
Writeable shareable images must be installed using the /WRITEABLE
qualifier on INSTALL, or by altering the image to mark all writeable
PSECTs to be non-shareable.
In most cases, a single PSECT that is marked with both the WRT
(writeable) and the SHR (shareable) attributes is undesirable, and
should be avoided -- the unintentional and/or uncoordinated sharing
of data among multiple applications can cause various transient
problems at run-time.
Additional information on program sections is
available.