.OPT
file,
tells the linker what code is to be included in the shareable image
.VEC
file,
tells the linker what subset of the code inside this shareable image
can be called from outside this shareable image
A useful metaphor is to think of each shareable image as an integrated circuit. (I apologize to those who are already very familiar with either shareables or integrated circuits - I know this metaphor has many failings, but it is the best I've been able to come up with). The overall program consists of a group of interlinked shareable images just as some electronic device consists of a group of interlinked intergrated circuits.
For a single one of these integrated circuits:
.OPT
file tells what components should be built into
the integrated circuit
.VEC
file tells what points in the integrated circuit
should have pins attached that make them accessible from the outside world
.OPT
and .VEC
files.
.VEC
and .OPT
files,
study how the shareable is made that contains the SLD Swimmer.
The swimmer is the code that calculates the trajectories of particles
through the complex electromagnetic environment of the SLD detector;
it is used heavily both by the simulation part of the Monte Carlo and by
the track reconstruction code.
If you look at
the SLD Shareables Constellation,
you will see SWIMSHR near the middle of the diagram.
It calls code from SLDSHR on down (the underlying utilities used by all
SLD offline software) and it is called by code from DSPSHR on up (DSPSHR
contains the Event Display system).
The .OPT File
Now look at the .OPT
file that determines how SWIMSHR is built.
It is in DUCS as PRODSWIM:SWIMSHR.OPT
.
Type it out or bring it up in an editor.
As was mentioned above, the .OPT
file determines what code
is to be included in the shareable (what components should be built into
the integrated circuit).
After the standard DUCS header, the first line is
ducsswim:swim/libThis tells the linker to include the entire library called
ducsswim:swim.olb
into this shareable.
The next few lines, all of which end in /share
,
determine what other shareables this SWIMSHR will be able to make calls to
(sorry, the integrated circuit metaphor doesn't have anything to match this).
For example, the line
sldshr/sharemeans that SWIMSHR can call routines from SLDSHR.
Notice that there is no line
ugsrtl/shareThis means that SWIMSHR can not call any routines from the shareable UGSRTL.
We will not discuss the meaning of the lines starting with
Declare the standard clusters
.
You will probably not need to make any changes there.
But if you ever need to make a whole new shareable,
you should copy this code and substitute in your new shareable name
whereever you see SWIM
.
The .VEC File
Now look at the .VEC
file that determines how SWIMSHR is built.
It is in DUCS as PRODSWIM:SWIMSHR.VEC
.
Type it out or bring it up in an editor.
As was mentioned above, the .VEC
file determines what subset of
the code inside this shareable can be called from outside this shareable
(what points in the integrated circuit should have pins attached).
We will not discuss the meaning of the lines above the DUCS header.
.Library /ducsutil:shrlib/ Transfer_Header SWIMShrXfr .Ident "SWIM-P03.000_1" SWIM$_MajorId == 03 SWIM$_MinorId == 000 SWIM$_Version == 1 SWIM$_Branch == ^A/P/All you need to know about these is that if you ever need to make a whole new shareable, you should copy this code and substitute in your new shareable name whereever you see
SWIM
.
Next comes a standard DUCS header. Then come the lines you need to understand, such as
Transfer SWERRM;
You saw from PRODSWIM:SWIMSHR.OPT
that the SWIM shareable
will be built from all of the code found in the SWIM library.
Take a look at how many routines are in this library by issuing the command
lib/list ducsswim:swim.olb
All of those routines will be in SWIMSHR (all of those components will be inside of our integrated circuit), but only a few of those routines will be able to be called from other shareables (only a few of those components of the integrated circuit will connect to external pins).
The Transfer
lines in the .VEC
file determine
which routines have that special characteristic.
The last routine shown by lib/list ducsswim:swim.olb
was SWZERO
.
This routine does not have a Transfer
in SWIMSHR.VEC
.
That means that this routine can not be called by any routine in any other
shareable. It can only be called by routines in SWIMSHR.
The lines at the end of SWIMSHR.VEC
about Data
have to do with how Common blocks can be used from Shareables.
We will not discuss this in any detail.
In general, Common blocks cause trouble in shareables.
Whenever possible, do your work with Jazelle banks instead.
Example Showing What Happens if a Transfer is Missing
Try the following example to see what a Transfer statement does.
Our earlier compile, link and run example used a routine called
WBPREP1.PREPMORT
in the shareable USERSHR
.
If you look at the PRODUSER:USERSHR.OPT
file, you will see
that it contains the line
Swimshr/shareThis means that your routine in
USERSHR
is allowed to call
routines from SWIMSHR
.
Edit your WBPREP1.PREPMORT
example now to add two calls to
routines in USERSHR
.
Just before the END
statement, insert the lines:
$CALL SWEXTR( ) ERROR RETURN; $CALL SWZERO( ) ERROR RETURN;These are not really proper calls (we've left out the arguments), but it is enough to demonstrate our point about shareables.
You will also need to add these routine names to the declaration statement at the head of the routine so that it becomes
INTEGER JZBLOC, SWEXTR, SWZERO;Now compile the new version:
EXPEDITE WBPREP1.PREPMORT
Then try to link the shareable: EXPEDITE USERSHR.VEC
You will get an error message as follows:
Action--> @DUCSUDUC:UBLDSHR USERSHR USER TEST %LINK-W-NUDFSYMS, 1 undefined symbol: %LINK-I-UDFSYM, SWZERO %LINK-W-USEUNDEF, undefined symbol SWZERO referenced in psect $CODE offset %X000000AF in module WBPREP1 file DISK$SLD_USR0:[PERL.TEST]USER.OLB;1The routine
SWZERO
could not be found by the linker.
It was in the SWIM
object library, but because it did not
have a Transfer
statement in SWIMSHR.VEC
,
it was not available to routines outside of the SWIM
shareable.
The other routine we called, SWEXTR
, was correctly linked.
It had a Transfer
statement in SWIMSHR.VEC
.
A More Complicated .VEC File
There are several other kinds of statements that you should know about
that can appear in a .VEC
file.
To see some of these, take a look at the .VEC
file that
determines how the B Physics shareable is built.
It is in DUCS as PRODHEAVY:HEAVYSHR.VEC
.
Type it out or bring it up in an editor.
The part above the DUCS header is the same weird stuff you saw and ignored
in SWIMSHR
.
Also, ignore the lines that start with a semicolon, they are just comments
are are even somewhat misleading.
Below the DUCS header you see some different kinds of lines. These lines can start with
Transfer
makes the routine available for calls from
other shareables (you have already seen this)
External
is like Transfer, but it also means that the
routine can be called directly from IDA (using an IDA EXTERNAL statement)
Processor
is like External, but it also means that the
routine is an IDA Processor
CmdProc
is like External, but it also means that the
routine is an IDA Command Processor
.VEC
file
EXTERNAL
statement and a PROCESSOR
or
CMDPROC
statement.
The three different forms are only there to remind users which routines
are to be called from IDA with which kind of statement.
Most of the time, you will just be concerned with External
and Transfer
statements.
Remember that both mean that a routine can be called from routines in
other shareables, but of the two, only External
can be called
directly from IDA.
Notice the following two lines near the end of the file:
External BBEXTRK Transfer BBFITANow start up IDA and try the commands
EXTERNAL BBEXTRK
and EXTERNAL BBFITA
.
Only the first of these works.
BBFITA
has only been listed as a Transfer
and therefore cannot be called directly from IDA.
You could fix this situation by changing the Transfer
to an External
and relinking HEAVYSHR
.
We try not to have routines set as External
unless someone
needs it. Their presence consumes a small amount of the system's
logical name space (a system resource that has limits).
Don't Change the Order in a VEC File
Under many circumstances, changing the order of the statements in a
VEC files can cause serious problems.
In general, when you first write a new .VEC
file, the order
does not matter, but once you have linked the shareable and then have
linked other shareables to this shareable, you should not change the order.
When one shareable is linked against another, it does not store
the names of the routines it is calling, it stores the positions of
the links.
Lets say I create a shareable called ONESHR
with the following
lines in its ONESHR.VEC
file:
Transfer A Transfer B Transfer C Transfer DI link my
ONESHR
with no problem.
Now say I have some other shareable called TWOSHR
that contains
calls to B and C.
I write my TWOSHR.OPT
to include the line
oneshr/sharemeaning that routines in
TWOSHR
are allowed to call routines in
ONESHR
.
I go ahead and link TWOSHR
.
Everything works fine.
I run my job that includes both shareables. It all works.
Now lets say I want to add some more stuff to ONESHR
.
I might change the ONESHR.VEC
to say:
Transfer A Transfer X Transfer B Transfer C Transfer DAgain I link my
ONESHR
with no problem.
If I then run my job that includes both shareables, it falls apart.
When my code from TWOSHR
tries to call B,
it actually calls X.
When my code from TWOSHR
tries to call C,
it actually calls B.
My code is TWOSHR
is still calling the second and third
Transfers
listed in ONESHR
, but these
Transfers
no longer lead to the expected routines.
TWOSHR
will have the wrong connections unless I either
go back to my old version of ONESHR
or I relink
TWOSHR
. When I relink TWOSHR
,
it will decide that B and C are now the third and fourth Transfer
,
not the second and third.
If the changes you make are to simple small shareables,
it is easy to relink everything.
But imagine what would happen if you made a change to the order
of the transfers in one of the very low level SLD shareables
such as SLDSHR
.
Usually, you can find a way to add a new routine to an existing
.VEC
file without changing the overall order.
Any line that has the form dTransfer dummy
is just
a space holder. You can replace it with a new line.
Most of the .VEC
files in DUCS have many of these
dummy lines at their ends for just this purpose.
You can also replace any line that you know is no longer used.
Failing that, it is usually also safe to add your new line at the
end of the .VEC
file.
One other thing you may notice about .VEC
files is that
the references are usually grouped into sets of four.
This is just a convention, it has no actual effect on the shareable.
Problems During Link: Undefined Symbols
The most common problem users have linking their shareables is
that the linker complains about "undefined symbols."
For example, earlier we had an example in which the linker complained:
Action--> @DUCSUDUC:UBLDSHR USERSHR USER TEST %LINK-W-NUDFSYMS, 1 undefined symbol: %LINK-I-UDFSYM, SWZERO %LINK-W-USEUNDEF, undefined symbol SWZERO referenced in psect $CODE offset %X000000AF in module WBPREP1 file DISK$SLD_USR0:[PERL.TEST]USER.OLB;1Assume you didn't know what was causing this problem. You could resolve it as follows:
Note that the undefined symbol was routine SWZERO
.
If you really want your routine to be able to call this,
your first job would be to find out what shareable this routine lives in.
Use a DIR command to locate the file DUCSALL:SWZERO.PREPMORT
.
You will find that it lives in the DUCS section SWIM.
That in turn means that it is a member of the object library,
SWIM.OLB
.
Next, you need to find out what shareable that object library belongs to.
You can generally just look at all of the VEC
files in the
given DUCS section. In this case there is only SWIMSHR.VEC
.
You can look in the corresponding SWIMSHR.OPT
to confirm that
indeed SWIM.OLB
is included in the SWIM shareable.
Now study SWIMSHR.VEC
to see if the routine we want,
SWZERO
is mentioned there.
If it isn't, you would need to make our own copy of SWIMSHR.VEC
that contains such a Transfer
.
You would add the Transfer
(taking care not to change the
order of the existing code means you would have to add this
Transfer
to the end of the VEC
file).
You would then relink SWIMSHR.VEC
.
Finally, you would check that your own shareable includes
swimshr/sharein its
.OPT
file.
Your shareable should then link correctly.
Your shareable's OPT
file indicates that your shareable
is allowed to call code from SWIMSHR
,
and SWIMSHR's VEC
file contains a Transfer
for
SWZERO
.
Problems During Run: Routine Not Found
The most common problem users have running shareables is
that when they issue an EXTERNAL
, PROCESSOR
or CMDPROC
statement,
they get an error message "Routine cannot be found in current image."
This message can mean one of several things.
SETUP_COM
file
External
, PROCESSOR
or CMDPROC
statement in the relevant .VEC
file
SETUP_COM
fileSETUP_COM
file that was created when you linked the shareable.
This was discussed earlier in
Compile, Link and Run.
For complicated projects, where you have modifications to several shareables
and there are many SETUP_COM
files involved,
the PROJECT command can help keep things straight.
It is discussed in another section of this Workbook.
The routine does not have an
Issue the DCL command:
External
, PROCESSOR
or CMDPROC
statement in the relevant .VEC
file
show logical shr_routine_nameIf the routine does have an
External
, Processor
or Cmdproc
statement in the relevant shareable's
.VEC
file, there will exist an appropriate logical name.
For example, we saw earlier that HEAVYSHR.VEC
contains the lines:
External BBEXTRK Transfer BBFITA
If you issue the command show logical shr_bbextrk
you will see
"SHR_BBEXTRK" = "BBEXTRK/IMAGE=HEAVYSHR" (LNM$DUCS40)This confirms that
BBEXTRK
can be called from IDA.
In fact, when you first try to call BBEXTRK
from IDA,
IDA uses this logical name to figure out that it needs to load
HEAVYSHR
.
If you issue the command show logical shr_bbfita
you will see
%SHOW-S-NOTRAN, no translation for logical name SHR_BBFITAThis confirms that
BBFITA
can not be called from IDA.
If you really needed to call it from IDA, you would need to make
your own copy of HEAVYSHR.VEC
that changes
Transfer BBFITA
to External BBFITA
.
You would then relink HEAVYSHR.VEC
.
.EXE
being produced,
the other half of the cases may fool you because they will produce
an .EXE
file but it is really no good.
You can test a single shareable by just running its .EXE
as a standalone file. For example:
RUN USERSHR.EXEIf the shareable is working correctly, the RUN command should reply
%DCL-E-NOTRF, no transfer address.Any other message means the shareable has a problem.
If the message includes the following line, your problem invovles incorrect use of common blocks.
-SYSTEM-F-NOTINSTALL, writable shareable images must be installedIn that case, see the following section on the use of common blocks in shareables.
Look at the first image's .OPT
file to see what other shareable
images this image is linked to.
Test each of them with the RUN
test described above.
Be particularly suspicious of images that are in DUCS DEV or TEST mode.
Use of Common Blocks in Shareables
The use of common blocks can cause problems for shareables.
If at all possible, use Jazelle banks instead.
If you use a common block in a shareable but do not take any other special action, when you go to run the shareable you will get the following message:
-SYSTEM-F-NOTINSTALL, writable shareable images must be installed
.OPT
file:
Psect_attributes = common_block_name, NoShrPut the line at the end of the
.OPT
file,
then relink the shareable.
In every shareable that is to use the common block,
the .OPT
file needs to have a set of lines as follows
just after the line Collect = shareable_nameXfr
:
Cluster = shareable_nameNoShrGbl Collect = shareable_nameShrGbl, common_block_name Psect_attributes = common_block_name, NoShr, GblFor example, the common block
JAZELLE
is included in
JAZELLESHR.OPT
as follows:
Cluster = JazelleNoShrGbl Collect = JazelleNoShrGbl, Jazell Psect_Attributes = Jazell, NoShr, GblIf there is more than one common block, list them all in the same
Collect
statement and then provide one
Psect_Attributes
statement for each common block.
For example:
Cluster = JazelleNoShrGbl Collect = JazelleNoShrGbl, Jazell, Other_Common Psect_Attributes = Jazell, NoShr, Gbl Psect_Attributes = Other_Common, NoShr, GblThese lines in the
.OPT
file are there to satisfy the VAX linker.
Add a line as follows to the .VEC
file of the most fundamental
shareable that is to use the common block:
Data common_block_nameFor example, the common block
JAZELLE
is included in
JAZELLESHR.VEC
as follows:
Data JAZELLThe line in the
.VEC
file is there to satisfy the Alpha linker.
Any shareables for which you have changed the .OPT
or
.VEC
files will need to be relinked.
Remember to relink in the correct order starting with the most
fundamental shareable.