# 1. Introduction to shareable images # ===================================   H The programs and command procedures in this library are tools for aidingG in the creation of shareable images from ordinary subroutine libraries. L Before describing these tools, the document attempts to answer the questionsP "What is a shareable image?" and "What advantages does a shareable image have?",( assuming no prior knowlege about either.  K A shareable image is a special sort of .EXE file. It typically contains all I the routines in a particular library, with all internal refernces (CALLs) J between the library routines resolved. What is special about it is that itH also contains a block of information known as the transfer vector, whichA allows (some or all) of the library routines to be CALLed from an I ordinary EXE file, and in fact once it has been created it is used almost G exactly like the library which it replaces. However, it has a number of / advantages over linking with an object library.   E 1. A shareable image is a separate entity and is not copied into your M    program's EXE file when you link it. This makes your EXE file considerably +    smaller, thereby saving much disc space.   J 2. A shareble image has had all CALLs between library routines pre-linked,L    which can make your LINK command considerably faster for a large library.  K 3. A shareable image can 'hide' support routines which should not be called L    except from within the library. This greatly reduces the chance of a nameI    clash between one of the main program's own routines, and something in .    the library of which the user was unaware.   H 4. A shareable image is merged with your program each and every time youE    RUN it. This means that you do not need to re-link your program to F    take advantage of the latest version of the shareable software; you:    will automatically obtain it when you RUN your program.  O This last point is the main difference between a shareable image and a library. J It cannot be over-emphasized that the person(s) creating and maintaining aK shareable image that is used by others must adopt a responsible attitude to I these activities, since the introduction of a bug or incompatibility into F a new version of the image will cause ALL programs using that image toJ manifest the bug the next time they are run. (With a library, the bug will. not affect programs until they are re-linked).  K If this worries you, there are two compensating advantages. Firstly, in the E commoner case where an old bug is fixed you will instantly obtain the M advantages thereof withour re-linking. Secondly, provided old versions of the L shareable image are not immediately deleted, it is always possible to revert3 to using an older version - just as with a library.   I The only real disadvantage of a shareable image (once created) is that it D is harder to DEBUG than an image linked with library code. ThereforeJ it is best not to create a shareable image until the library code is well-O tried and tested. Of course you can always re-link with the object library and  # debug the result if you find a bug.   ! 2. Structure of a shareable image ! =================================   M A shareable image consists of two main parts. The first, the TRANSFER VECTOR, I is unique to shareable images and is the means by which the routines that G it contains can be accessed from the outside. the second part is simply E the code and data defined by the routines which it contains, and this I second part is generated in the usual way by the linker when the transfer % vector is linked against the library.   G In order to further illuminate these concepts, let us consider a simple H llbrary consisting of two routines which can be called by a user, calledI USERA and USERB, plus two support routines SUB1 and SUB2 which are called K by USERA, but which should not be called directly by the user. (The example N is FORTRAN, but the same concepts apply to other VAX languages). The shareableA image corresponding to this library will look like the following:     7                  Contents of file SHAREABLE_USERAB.EXE:   4                       ------------------------------4 Header information -> |  Version = 1.2             |4                       |     and other information  |4                       |                            |4 Transfer vectors -->  |============================|* 		      |  Vector for USERA          |----8                       |----------------------------|   |4 		      |  Vector for USERB          |---|----------B                       |============================|   |         |B Code from library --> |  SUBROUTINE USERA (args)   |<---         |B                       |                            |             |B                       |  code and data including:  |             VB                       |  CALL SUB1 (...)           |-----        |B                       |    and                     |    |        |B                       |  CALL SUB2 (...)           |----|---     |B                       |                            |    |  |     |B                       |  END                       |    V  |     |B                       |----------------------------|    |  |     |B                       |  SUBROUTINE SUB1 (...)     |<----  |     |B                       |    etc.                    |       V     |B                       |  END                       |       |     |B                       |----------------------------|       |     |B                       |  SUBROUTINE SUB2 (...)     |<-------     |B                       |    etc.                    |             |B                       |  END                       |             |B                       |----------------------------|             |B                       |  SUBROUTINE USERB (...)    |<-------------4                       |    etc.                    |4                       |  END                       |4                       ------------------------------    J Nothing except the transfer vectors are visible to the users program whichK uses the shareable image. Since SUB1 and SUB2 do not have transfer vectors, I the user cannot call them directly and could have his own subroutine SUB1 G or SUB2 called by his main program without confusion. The links between N USERA and SUB1, SUB2 were created when the shareable image itself was created,L as were those from the transfer vectors to the routines to which they refer.  > When the user links his program all the linker has to do is toI create links between the users calls to USERA and USERB and the shareable M image's transfer vectors. These links are unusual in that they are to another J file, SHAREABLE_USERAB, rather than within the EXE file being created, andI it is in fact the RUN command which finally connects the two together for 
 its duration.   H This is the  reason for transfer vectors. Without them, if the shareableO image were altered such that the USERA routine became bigger (or smaller), then G USERB would now start at a different place within SHAREABLE_USERAB, but D user programs which used it would not know this. The results are tooM horrible to contemplate. Using transfer vectors, this cannot happen, PROVIDED F THAT TRANSFER VECTORS ARE NEVER ALTERED. This rule is absolute. Once aH shareable image has been created and put into production, nothing may beJ deleted from a transfer vector, not added to it except at the end thereof.G If a routine referred to in the vector becomes obsolete, it cannot just I be deleted. Instead, it must be replaced by a routine which either issues $ an error message or simply RETURNs.   I A shareable image is identified by its file-name and by a VERSION NUMBER. E The version number consists of two parts, the major and minor version K numbers, which are usually written separated by a decimal point. Every time G any changes are made to the image, the minor version is incremented. If K ever any changes are made which mean that the image is no longer compatible H with previous versions, the major version is incremented. When a programI using a shareable image is run, a check is made that the major version is I thae same as that which it was linked against, and that the minor version L is the same or bigger. If either check fails, the program cannot run withoutK relinking (and possibly other changes), and an error number "Version number  mismatch" is generated.   M As noted above, a shareable image can  call private routines contained within K itself. This may include a few routines taken from other libraries on which I the one being made shareable depended. A shareable image can also contain G calls to routines in any other shareable image, which includes all the  H DEC_supplied runtime libraries. However, it cannot make use of a CALL toF a routine which is to be written by the user, because this call is notI defined at the time at which the shareable image is created. Instead, the D routine to be called must be passed as an argument to the routine inI the useable image (say USERB), using (in FORTRAN) the EXTERNAL statement.      		OK				Impossible   	EXTERNAL MYSUB  	    ...' 	CALL USERB( X, MYSUB)			CALL USERB( X)  	    ... 	END  7 	SUBROUTINE MYSUB( X, ...)		SUBROUTINE USERSUB( X, ...)  	   ...					   ... 	END					END  K ---------------------------------------------------------------------------   0 	SUBROUTINE USERB( X, SUB)		SUBROUTINE USERB( X) 	   ...					   ...* 	CALL SUB( X, ...)			CALL USERSUB( X, ...) 	   ...					   ... 	END					END    6 The former is much better programming practice anyway!   3. Using a shareable image ==========================  H This is simplicity itself; one simply includes an options (.OPT) file inK the link command in the same place that one previously included the library I name. (The OPT file will have been written by the person who created the  # shareable image from the library).     		Shareable				Library  O $ LINK PROGRAM,..., [libdir]USERAB/OPT	  $ LINK PROGRAM,..., [libdir]USERAB/LIB   N Should you ever wish to take a program which uses a shareable image to anotherL VAX, it is necessary to take the shareable image(s) which it uses as well asI the program itself. If you are unsure what these are, you can find out by N typing the OPT file which you use to link the shareable image and looking for J lines of the form "shareable-image-name /SHARE". You would also be advisedN to take a copy of this OPT file with you. If you fail to do this, your attemptA to run PROGRAM.EXE will be greeted with a "file not found" error.   J The directory in which a shareable image is assumed to be SYS$SHARE unlessL the filename (SHAREABLE_USERAB in the example) is defined as a logical name,L in which case that file is used. This will normally be taken care of for youG unless you have taked a copy. for example, if you have moved to another D institution and have loaded a copy of SHAREABLE_USERAB.EXE into your8 new directory DISK42:[QQEZ543.SHAREABLES], you will need  J $ ASSIGN DISK42:[QQEZ543.SHAREABLES]SHAREABLE_USERAB.EXE SHAREABLE_USERAB:  & in order to run EXE files that use it.  O NOTE THAT COPYING A SHAREABLE IMAGE MAY BE IN VIOLATION OF COPYRIGHT OR LICENSE ) AGREEMENTS PERTAINING TO IT. Enough said.    4. Creating a shareable image  =============================   M It has to be said that this is a tiresome business (as opposed to a difficult N one). However, it only has to be done once - subsequent updating (to fix bugs,J add new functions, etc.) are relatively straightforward. The procedures inO this directory automate some of he chores involved in the initial conversion of J a library, but it is not possible to render the process totally automatic.  K The working assumption of this utility is that the shareable image is built N from the contents of a single object library. If this is not the case, you canJ choose either to extract the relevant object modules and build a temporaryF object library for use by this procedure, or to write your own command procedure to steer BLDSHR.  G Assuming you have such a library, say MYLIB.OLB, and have defined a DCL  symbol' 	$BLDSHR :== @disc:[wherever]BLDSHR.COM   $ to invoke BLDSHR, the first stage is   	$BLDSHR MYLIB 1  J the number "1" indicates that this is the first pass. BLDSHR will look forK a file MYLIB.VEC as well as MYLIB.OLB, and when it fails to find it it will P ask for confirmation that the shareable image is being built for the very first I time (version 1.0). Assuming you answer positively, it will then scan the I contents of the object library, creating a file called MYLIB.UPD. This is O actually a set of macro-32 macros, but you don't need to understand macro-32 at K all. What it will contain is a header (to be left alone) followed by a list  of lines such as   	VECTOR   <name>  M where <name> is the name of a callable routine or entrypoint in your library. L The list will be alphabetically ordered, EXCEPT that alternative entrypointsG (FORTRAN ENTRY statement) follow the main entrypoint of the module that  declared them.   You now edit this file. Why?  H It is probable that some of these routines should be regarded as libraryM internal routines, and not made available to the user of the shareable image. G for any such routine, change the word VECTOR to the word IGNORE. Should L you wish to rearrange the list, you may do so now, because this is the firstF ever version of the library. The order is then forever fixed. (Its not' of much significance, so don't worry).    P Note that it is much easier to add a VECTOR for a later version of the shareableP than to remove an unwanted VECTOR. If you have any doubts about the desirabilityG of letting a user call any particular routine himself, use IGNORE so he  can't.  O The procedure attempts to take care of another hassle. The DEC FORTRAN compiler J generates COMMON program sections (psects) with the attributes GBL and SHRJ (global and shareable), and of course WRT (writeable). Other languages mayK take similar action with global writeable data objects. Unfortunately, when E such a section is linked into a shareable image, the SHR attribute is H interpreted to mean that the common block is shared between all users onK the system - a far cry from sharing between subroutines in the same program H which is normally what is wanted! Furthermore, a global shared writeable1 section requires privileged actions to create it.   N The cure is to tell the linker that the common block is NOT shareable, despiteN information to the contrary. BLDSHR identifies  allpsects with the SHR and WRTN attribues, and at the end of the UPD file you will find statements of the form   	PSECT	<blockname>  L where <blockname> is the name of a FORTRAN common block used in the library.J This statement will later be used by BLDSHR to redeclare the common block,E or psect (in linker jargon)  as NOSHR, which is normally the correct  D action. Unless you KNOW what you are doing, leave these lines alone.  F Having edited MYLIB.UPD to hide internal routines from your users, you3 proceed to stage two, not surprisingly invoked with    	$ BLDSHR MYLIB 2   G which will create the shareable image for you. Resulting files will be:    	SHAREABLE_MYLIB.EXE
 	MYLIB.OPT
 	MYLIB.VEC 	SHAREABLE_MYLIB.MAP  L The first is the shareable image itself. The second is a linker options fileD that you use to link programs with the shareable image itself, as in   	$ LINK	TESTPROG, MYLIB/OPT   I The third is an essential file to keep around for when you want to create K an update version of the shareable image, with bugfixes, new routines, etc. N DO NOT DELETE MYLIB.VEC!! The last is a linker map, worth keeping until things are known to be working.  G Finally, the procedure will define a logical name SHAREABLE_MYLIB equal L to the full file specification of disc:[directory]SHAREABLE_MYLIB.EXE, which will help with testing.   L Obviously, this name definition only lasts until you log out. If you do not N finish testing in one session, you will have to redefine it as you next login.I Once your shareable image is in production, steps should be taken to make J sure that SHAREABLE_name: is permanently defined: as a system logical nameG set up at system boot, via the system-wide login file or via the user's L LOGIN.COM as appropriate. Note also that if you move the shareable image to K another directory, you must change both the logical name definition and thei contents of name.OPT to match.   5. Updating a shareable imager =============================s  L This procedure is similar to the above, but generally less work. BLDSHR will% require the following files as input:t  : 	MYLIB.VEC	from the last time you built the shareable, and. 	MYLIB.OLB	containing new code, bugfixes, etc.   	$BLDSHR MYLIB 1  K will check to make sure that MYLIB.VEC has not been tampered with, and willaF compare its contents with that of the (presumably update) library. TheH created file MYLIB.UPD will contain VECTOR and PSECT statements only forK routines and common blocks which are new since last time. You may edit thisnN as before. You may also add VECTOR statements for previously IGNOREd routines,@ or REMOVE statements and an .IDENT (see the next section). Then,   	$BLDSHR MYLIB 2  I will do all that is needed to create a new version (1.1) of the shareableiI image. As mentioned ablve, once this EXE file is placed in the productionlH directory, all programs using SHAREABLE_MYLIB will automatically get theF benefit of the new version. It is therefore clearly essential that theJ functionality of existing routines is not changed and that the new version# is upwards-compatible with the old..  L Subsequent BLDSHR operations work similarly, creating versions 1.2, 1.3, ... of the shareable image.h   6. Advanced UPDate options ==========================  L Sometimes, it is desired to remove a routine from a shareable image (becauseI it has become obsolete and unmaintainable). The preferred manner of doingtL this is to replace it by a 'stub' routine that either does nothing, or whichL outputs an error message and/or signals an error. If, however, it is desiredK to make it impossible to find that obsolete routine's name when next a user I program is linked, there is a problem: a transfer vector entry cannot be e removed.  O The next best thing is to replace the transfer code by code to crash a program. " This can be accomplished by adding   	REMOVE	<name>  M to an UPDate file. Thereafter, attempts to relink a call to <name> will fail.mL Any existing program that isn't relinked will CRASH with 'opcode reserved toL digital' if they attempt to call the REMOVED routine. (NOTE: this message isG caused by executing a HALT instruction. Don't do this in Kernel mode!) eL Introducing a crash into a program which was working yesterday is in general9 undesirable: use REMOVE with extreme reluctance, if ever.d  O Should it become necessary to create a new version which is wholly incompatibleaO with previous ones, this is accomplished by creating a new MAJOR VERSION of thea= library (eg 2.0 following 1.n). To do this, one adds the linea   	.IDENT	/2 -0 /a  M to the UPD file. THe new ident MUST be bigger than the last one! Once versionhJ 2.0 is in production, any attempt to run a program that was linked againstG any version 1.n shareable will fail, with a message telling the user toi re-link his program.   7. Troubleshooting ==================  K BLDSHR can produce error and warning messages, if it spots something wrong.  The most serious is   / 	"VEC file has been tampered with"	(first pass)   L this means what it says. The implication is that the ordering of the entriesI in the transfer vector might be incompatible with the previous version: alI catastrophe. If at all possible, recover the old .VEC file from a backup. @ As a last resort, create a NEW MAJOR VERSION as if from scratch.   Other messages:   @ 	"Entrypoint xxx used in vector file but not defined in library"< 	"Common xxx used in vector file but not defined in library"  I changes to the library have caused a routine entrypoint or a common blockuH to disappear. In the first case, see REMOVE in section 6. In the second,1 it is safe to press on if the change is intended.   + 	"Attempt to REMOVE an IGNOREd name: xxxxx"r* 	"Attempt to REMOVE an unused name: xxxxx"  J What it says. You can only remove a VECTOR'ed name. The REMOVE is ignored.  % 	"Unrecognised statement in UPD file"   ? followed by the offending line. Probably a typo, edit it right.a   	"xxxxx: table overflow"  H The BLDSHR program has run out of space for storing names. The amount ofJ space available is declared in the first few lines of BLDSHR: suggest EDIT and recompile the utility.  , 	"SPSC record in object library?? giving up"  = DEC have done something horrid and BLDSHR needs fixing. Also,    	"BUG - xxxxx xxxx xxx"- 	"xxxxx: table array too small"=  H Internal errors. Contact a guru, or the author (who doesn't guarantee to+ do anything about it, but it's worth a try)   E The BLDSHR diver command procedure also uses LINK and a few other DCL F utilities, which can of course go wrong. Most of these errors (such asE file access privilege or disk quota problems) are easy to understand.   G As well as any errors that may be produced by any normal LINK, such as 2K unresolved references, there are a few possible problems which give rise to  non-obvious errors.|  P The most likely one is the message "incompatible attributes specified for psect M ..." when you attempt to link to the shareable image. This is caused by your SJ program using a common block of the same name as one within the shareable I image. If this is deliberate rather than a latent bug, it is necessary to I include PSECT statements to once again override the blocks SHR attribute.-M These have the form PSECT=psect-name,NOSHR (one per line), and are fed in via M an options file. You can see examples in the SHAREABLE_name.OPT file used to   create the shareable image.   I A related one is a self-explanitory message saying that your common psect-I is longer than the one in the shareable image. The only way to get around-L this is to re-build the shareable image and force something it it to declareO the whole of the common block. It seems more likely that the message reflects a- previously latent bug, though.  L A message saying that file SYS$SHARE:SHAREABLE_name cannot be found when youL try to run a program linked to a shareable image means that the logical nameG SHAREABLE_name: is not defined. If it refers to some other directory ord< filename, it means that the logical name is wrongly defined.  L A message "multiply defined transfer vector" means that you nave defined theJ same routine in more than one place in the transfer vector. This shouldn't be possible using BLDSHR  P Finally, the message "writeable shareable images must be INSTALLED" could appearM when you try to run the test program linked with the new shareable image. TheaP statement is true but misleading - do NOT immediately ask your system manager toK install it! The probable cause is a SHR,WRT psect that for some reason has sO escaped the attentions of BUILD_SHARE. Edit the .MAP file to find the offendingsP psect, and report the problem to the author or maintainer of BUILD_SHARE because' this indicates a bug in that procedure.o  N If your shareable image SHAREABLE_name.EXE is enormous, the probable cause is M the definition of a huge common block (or local array) by one or more of its UK routines. This used to happen only if the storage was DATA-initialized, butRL from VMS 4.5 seems to happen always. In any case, it is bad practice to holdN large arrays in common or local storage. Consider re-coding the subroutines soL that the storage is passed as an argument, live with it, or abandon the idea, of making this particular library shareable.   8. Advanced features ====================  O If a program will occasionally make use of a large shareable image, but usuallyeL won't, it is possible to link to the code in the shareable image dynamicallyL at run-time rather than linking to it with the linker. the key to this trickI are the RTL routines LIB$FIND_IMAGE_SYMBOL and (if you are using FORTRAN)m0 LIB$CALLG. (C programmers may find this easier!)  G Further information may be found in the DEC manuals "A guide to writingh? modular library procedures" and in the linker reference manual.r   9. Maintenance ==============  K Either fix it yourself, or contact the author, who does not guarantee to donF anything but who is definitely interested in any bugs and their fixes.  I BLDSHR was written in a hurry, and has not been tested on code written in I anythinh other than FORTRAN. It is quite likely that other languages will L have 'wrinkles' of theit own, which may require extension of the object-file# scanning abilities of this program.i   History:   	original version:	15-OCT-1987+ 				abandoned in shocking state due to timee 				pressure   	version 1.1		3-MAR-19920 				resurrected, fixed (?) and documented better0 				in response to MACRO32'ers asking me for it.    
 The author isf   	Nigel R. Arnot, 	dept. Physics,w 	Kings College London, 	Strand, 	London WC2R 2LS, UK.t   	e-mail: NRA@UK.AC.KCL.PH.IPGa6 		NRA%ipg.ph.kcl.ac.uk@nsfnet-relay.ac.uk   (internet)4 		NRA%uk.ac.kcl.ph.ipg@ukacrl.bitnet        (bitnet) 		etc...   	phone:  +44 71 873 2583   The legal bit (again):  ( C Copyright N. R. Arnot, 1987 and 1992.   L This code as supplied 'as is'. The Author takes no responsibility whatsoever* for whatever you may manage to make it do.  G This code may not be sold for profit, nor may any derivative thereof be-O sold for profit. (Should you wish to do so, please make an offer to the author,IE who might be persuaded to grant you a license to do so). 'Derivative' @ excludes files created as a direct result of running the programG in the usual way (in other words I'm not trying to claim rights to your= shareable images).  K The copyright notices contained in these files may not be altered, deleted,i or amended in any way. a  M With these two exceptions, you are free to use this code in any way you like.wJ The Author would like to hear of any changes or improvements that you find useful. 