Loader Interface
KEY
Note 1. Loader search order.
When the loader is asked to find an entry point, the search is done
in the following order:
1. System entries i.e. subsystem and Director system call list
2. Privately loaded entries
3. Current active directory
4. Subsystem base directory
5. Privately nominated directories i.e. SEARCHDIR list
The subsystem base directory contains pointers to heavily used
software such as the standard compilers and mathematical libraries,
MAIL, VIEW, SETMODE etc. Object files found via the subsystem base
directory are always added to the 'permanently loaded' loader table and
remain loaded until the end of the current session or a call of
RESETLOADER.
Searching is always linear down the search list, never circular.
Note 2. Searching for entries at command level.
If the loader is asked to load a particular command and it could not
be found after a full search then the following action is taken.
The loader assumes that the command name is really a file name and
tries to connect it. If the connect fails or it succeeds but the file
is neither an object file nor a character file then the load has failed
and the message 'Load fails - ENTRY not found' is output. If the file
is an object file then it is examined for a main entry point. If found
then the object file is run otherwise the load fails.
If the file is a character file, then a call is made to OBEYJOB to
obey the contents of the file on the assumption that it contains a
series of commands.
Note that for an object file with a main entry then
Command: PROGY
Command: RUN(PROGY)
Command: EXECUTE(PROGY)
have identical effects at command level.
Note 3. Return code from non-trappable events in user programs.
Just before the loader passes control to a piece of user software,
it sets a trap to catch catastrophic failures in that software such as
'unassigned variable', 'address error', etc. If indeed some such
contingency does occur in the user program then control passes to the
trap. Almost the first thing the loader does is check the return code.
If this is still zero, i.e. 'success' - which is quite likely since the
failure was presumably unexpected - then the loader itself will set a
standard return code of 103050709 before calling the diagnostics package
and returning to whatever initiated the unsuccessful call.
In many cases the initiating software will be the subsystem itself
i.e. a user command typed at command level, but some other
routines/commands available in the subsystem and callable from within
user programs, themselves set up loader traps. Examples of these are
RUN, CALL, EXECUTE (all described below), EMASFC, FCALL and PCALL. If a
user program calls on one of these utilities then control will return to
the program even after a catastrophic failure. If the program always
checks the return code after calling one of these utilities then at
least it can detect that a non-trappable failure has occurred and take
appropriate action.
Note 4. Reserved filenames
The files T#CODE, T#GLA and T#LOAD are reserved for use by the
loader; their use for any other purpose is NOT recommended.
User Interface
KEY
This section contains details of the commands used to control and
interrogate the loader. It also contains details of the procedures CALL
and USEFOR, commonly used by user programs.
LOADPARM
This command allows loader run-time options to be set. It is the
loader equivalent of PARM (which sets compiler options).
The default is FULL, which requests full cascade loading. Failure
is reported if any unsatisfied references remain. LOADPARM(MIN)
suppresses cascade loading and the loader will only load the file which
contains the entry point being looked for. Any common areas required
are created and all unsatisfied references are made dynamic.
LOADPARM(LET) makes unsatisfied references 'unresolved' after a full
cascade load so that execution can begin.
IF LOADPARMs MIN and LET are both set, then unsatisfied references
will always be made dynamic. Although it might appear that under these
circumstances LET is ignored, it does affect the handling of mismatching
lengths for a data entry and its references (see the "Errors and
warnings associated with loading" section for further details).
LOADPARM(MIN) is set.
If LOADPARM(ZERO) is requested then any common areas created by the
loader will be zeroed otherwise they are filled with the unassigned
pattern.
Example: LOADPARM(LET,ZERO)
DATASPACE
This command allows the user to set up a data area in a file and use
it to satisfy data references which occur during loading. The file can
be a data file created by NEWSMFILE or a character file. DATASPACE
permits the caller to add data entries to the 'permanent entries' loader
table. Each entry is associated with a specific area within a file.
Two entries are not allowed to overlap and any entry must be wholly
contained within the file in which it occurs.
The command takes 5 parameters of which 2 are optional:
ENTRY - name of the new data entry
FILE - name of the file which contains the area of
store to be used by ENTRY.
LENGTH - length of data area in BYTES
OFFSET [optional] - offset of the start of ENTRY from the start of
the file in BYTES. This parameter defaults to 0
i.e. the first available byte in the file is the
first byte of the data area.
ACCESS [optional] - Type of access required to the data area. The
permitted values are:
R - Read and Read Shared
W - Unshared Write
WS - Write Shared
The default is W for a file, R for a pdfile
member. Indeed pdfile members can ONLY be used
in R access mode. This is to prevent problems
arising when object files and DATASPACE areas
are members of the same pd file. The loader
connects object files in R mode to load them so
if an object file which was a pd file member was
loaded then the whole pd file would be connected
in this mode regardless of any previous use of
the pd file or any of its members.
Whatever the access type requested, the
appropriate permission must have been given. W
and WS permissions are allowed on another user's
file. Write shared access can be tricky,
e.g. what if two of you are trying to write to
the same area at the same time, and should not
be used unless you are sure you know what you
are doing.
This command will be particularly useful to users of programming
languages other than IMP since it allows the powerful EMAS facility of
store mapping to be used from any language. The only requirement is
that the language implementation allows external data areas. IMP
defines %external variables which have this property, while in FORTRAN
the equivalent is the common area. Normally the loader will create
common areas at load time by assigning space from the user's gla file.
DATASPACE allows the user to set up the data area independently of the
loader in a location of his own choosing. When the loader encounters
the data reference it will find that there is a data entry of the
correct name and type already loaded and use it to satisfy the
reference. By using common areas for input and output all conventional
(and expensive) READ and WRITE operations can be avoided. There is the
further advantage that more of the user's gla file is available for
programs and the 'user gla full' error will occur less often.
Note. This is not a language provided facility but a system supplied one
and users should bear this in mind when making use of it.
DATASPACE definitions remain in force until the end of the current
session or an explicit call of RESETLOADER (q.v.).
WARNING
-------
IMP programmers should not use SMADDR on a file which has active
DATASPACE definitions. This is because SMADDR can change the access
mode to a file without the loader knowing about it. For example a file
with DATASPACE entries connected in READ access mode could have this
switched to WRITE mode by a call of SMADDR with consequences best left
to the imagination! If you must access a file currently in use by
DATASPACE then you should seek advice.
Example of the use of DATASPACE
KEY
Consider the following two programs:
%BEGIN COMMON /STAR/ISTAR(10)
%EXTRINSICINTEGERARRAY STAR(1:10) DO 100 I=1,10
%INTEGER I ISTAR(I)=ISTAR(I)+I
%FOR I=1,1,10 %CYCLE 100 CONTINUE
STAR(I)=STAR(I)+I WRITE(6,600)ISTAR
WRITE(STAR(I),6) 600 FORMAT(1H ,10I7)
%REPEAT STOP
%ENDOFPROGRAM END
Both refer to an external data area called STAR, 40 bytes long,
which is to be regarded as 10 integers. In the IMP program the extrinsic
array STAR generates the data reference whereas in the FORTRAN program,
the array ISTAR is contained in the common block STAR.
Both programs increment each array element by the array subscript
before outputting the value of each element.
Each program requires access in W mode to a data area 40 bytes long
and we can provide this using the command DATASPACE. First the file to
hold the area is created by, say,
NEWSMFILE(DAREA,80)
This command creates a zeroed file 80 bytes long called DAREA and we
assign the first 40 bytes of it to a data entry called STAR by the
command:
DATASPACE(STAR,DAREA,40)
If either program is run then when the loader tries to satisfy the data
reference to STAR then it will find an entry of the correct name, type
and length already loaded.
Running either program would give the result
1 2 3 4 5 6 7 8 9 10
STAR remains loaded after the run so a second run would give the result
2 4 6 8 10 12 14 16 18 20
and so on.
The final values are always preserved between calls and the
definition of STAR will remain in force until log off or a call of
RESETLOADER.
DAREA can support as many other DATASPACE definitions as we wish
provided that the areas defined are wholly within the file, no two areas
overlap and there is no conflict in access mode. For example if we have
STAR set up as above then the following attempts to set up another
DATASPACE area would fail:
DATASPACE(PLANET,DAREA,40,60) => Not wholly contained in DAREA
DATASPACE(ASTEROID,DAREA,40,20) => Overlaps STAR
DATASPACE(COMET,DAREA,40,40,R) => DAREA already connected in
W mode for STAR
whereas
DATASPACE(RIGEL,DAREA,20,40)
would set up a new data entry 20 bytes long from byte 41 to 60 in DAREA
while
DATASPACE(CASTOR,DAREA,10,60) and
DATASPACE(POLLUX,DAREA,10,70)
would assign the remaining 20 bytes in the file to data entries CASTOR
and POLLUX each 10 bytes long.
The important point to remember is that the DATASPACE area length is
always given in BYTES.
ALIASENTRY
This command allows a user to add an alias to a system or
permanently loaded entry point directly to the loader tables for the
duration of the session or the next call on RESETLOADER(q.v.). The
alias is added to the 'permanent entries' loader table with a copy of
the type and descriptor of the original name.
The command takes two parameters:
ENTRY - Name of a currently loaded entry point
ALIAS - Name to be added to the permanently loaded entry table
This method of aliasing differs in several ways from the command
ALIAS. ALIAS works by adding an entry of the form ALIAS=ENTRY to the
current active directory. For example ALIAS(ANALYSE,A) would enter
A=ANALYSE in the active directory. The alias is permanent and can only
be removed by another call on ALIAS. A call on A would cause the loader
to search the currently loaded material. An entry called A would not be
found so the loader would now search the active directory where it would
find A=ANALYSE. The loader would remember that it started off looking
for A in case this branch proves fruitless then start to look for
ANALYSE. ANALYSE would be found among the currently loaded entries and
the loader would return the descriptor to enter the command.
If the alias had been set up using ALIASENTRY then a call on A would
have found A among the currently loaded entries and returned the
descriptor immediately.
ALIASENTRY is more efficient than alias but ALIASENTRY definitions
only remain in force for the current session or the next call on
RESETLOADER.
Example: ALIAS(FILES,F)
RUN
This command is used for running a compiled program. The only
parameter is the name of the object file which contains the program.
Note that the first action is to increment the loadlevel before starting
any loading operations. After the RUN has terminated then everything
loaded at the new loadlevel is unloaded and the loadlevel decremented
before proceeding. By implication, anything loaded by a call on RUN
will be unloaded again after the RUN. A routine which calls RUN will
not have access to any temporarily loaded code or any temporary data
area created by the RUN.
If RUN is called from within a program and the file RUN fails
catastrophically then a standard return code of 103050709 will be set
unless the file itself had already set a non-zero return code.
At command level RUN and EXECUTE have identical effects.
Example: RUN(PROGY)
EXECUTE
This command operates in the same way as RUN (q.v.) except that the
loadlevel is unaltered. Any code loaded or data area created by the
call of EXECUTE can be used by the routine or program calling EXECUTE.
Unlike RUN, EXECUTE does not unload.
If EXECUTE is called from within a program and the file EXECUTEd
fails catastrophically then a standard return code of 103050709 will be
set unless the file itself had already set a non-zero return code.
At command level EXECUTE and RUN have identical effects.
Example: EXECUTE(PROGY)
CALL
%externalroutinespec call(%string(31) command, %string(255) param)
This routine is as described in the EMAS 2900 User's Guide with the
difference that if the load fails then CALL will set a return code and
return to the routine which called it, rather than returning directly to
command level.
Note that the remarks pertaining to loadlevel and loading/unloading
made in the description of RUN also apply to CALL (and its FORTRAN
user's equivalents EMASFC and FCALL).
If the code CALLed fails catastrophically then a standard return
code of 103050709 will be set by the loader unless a non zero return
code has already been set.
USEFOR
%systemintegerfunctionspec usefor(%routinename myname,
%string(31) externalname)
This function can be used to call any external routine or function
from within a program where the routine or function need not be
specified until run time. The nearest equivalent is CALL, but USEFOR is
a much more powerful tool than CALL since it is not restricted to
commands with a single %STRING(255) parameter.
Code loaded via the USEFOR mechanism is not unloaded after it has
been run, unlike the CALL mechanism. This is particularly useful in
situations where constant loading and unloading could cause inefficiency
e.g. CALL inside a loop.
To use USEFOR you must first declare a dummy dynamic routine or
function which has the same specification as the target routine(s) or
function(s). A call to USEFOR at run time will then make a call to the
dummy routine or function equivalent to a call on the desired code.
USEFOR takes two parameters:
MYNAME - the name of the dummy dynamic routine or function, and
EXTERNALNAME - the name of the external routine or function which you
actually want to call at run-time,
and will return a result of zero if successful.
The one restriction on USEFOR is that it can only be used with one
dummy routine or function per program.
Technically, what USEFOR does is to work its way back from its own
stack to the location in the gla which contains the escape descriptor
corresponding to the dummy routine. An attempt is then made to load
EXTERNALNAME and if this is successful the escape descriptor in the gla
is overwritten by the descriptor to EXTERNALNAME. A call on the dummy
routine in the user program is then equivalent to a call on
EXTERNALNAME. If we want to call EXTERNALNAME many times then we only
have to load it once. If desired then we can give the program different
EXTERNALNAMEs in the same run.
Example of the use of USEFOR
KEY
Here is an extract from a program showing how USEFOR could be used
in place of CALL:
%BEGIN
%DYNAMICROUTINESPEC ANYTHING(%STRING(255) S)
%SYSTEMINTEGERFNSPEC USEFOR(%ROUTINENAME DUM(%STRING(255) S),
%STRING(31) NEX)
%ROUTINESPEC QUERY(%STRING(31) PROMPT,%STRINGNAME ANSWER)
.
.
.
%CYCLE
! Get next command
QUERY("Next command: ",NCOM)
%EXIT IF NCOM=".END"
FLAG=USEFOR(ANYTHING,NCOM); !Make call on ANYTHING into call
!on NCOM %RETURN
%IF FLAG#0; ! USEFOR failed for some reason.
! What params do we want to give NCOM?
QUERY("Param? ", PARM)
! Now call NCOM by calling ANYTHING
ANYTHING(PARM)
! Check return code
%IF RETURN CODE#0 %THEN %START
.
.
%FINISH
.
.
.
%REPEAT
.
.
%ENDOFPROGRAM
By contrast, here is another program fragment which shows USEFOR
being used to allow different integer functions to be selected:
%BEGIN
%DYNAMICINTEGERFNSPEC ANYTHING(%INTEGERNAME I,J,K)
%SYSTEMINTEGERFNSPEC USEFOR(%INTEGERFNNAME DUM(%INTEGERNAME I,J,K),
%STRING(31) EXTERNALNAME)
%ROUTINESPEC QUERY(%STRING(31) PROMPT,%STRINGNAME ANSWER)
.
.
.
.
Solve loop
%CYCLE
! Get name of next solve function
QUERY("Solve function? ", NEXTFN)
%RETURN %IF NEXTFN=".END"
FLAG=USEFOR(ANYTHING,NEXTFN); ! Make call on ANYTHING into call on NEXTFN
%RETURN %IF FLAG#0; ! Abandon if error
TESTFLAG=0
I=NEXTPRIME
J=I*2
%WHILE TESTFLAG=0 %CYCLE
TESTFLAG=ANYTHING(I,J,K)
%EXIT %IF K<0
I=K//2
J=K*2
%REPEAT
%IF TESTFLAG#0 %THEN PRINTSTRING(NEXTFN." is diverging")
PRINTSTRING("Final values are: ")
WRITE(I,8)
WRITE(J,8)
WRITE(K,8)
NEWLINE
%REPEAT
.
.
.
%ENDOFPROGRAM
USEFOR will fail if
a) MYNAME is not declared as dynamic
b) MYNAME had been satisfied before USEFOR was first called e.g.
%DYNAMICROUTINESPEC FILES(%STRING(255) S)
would be satisfied by the subsystem command FILES at load time.
c) the load of EXTERNALNAME failed.
Note that in the spec of USEFOR given above, which is how it appears
in the code of the loader, the %ROUTINENAME MYNAME parameter is simply a
pointer to a code item external to the loader. The loader knows nothing
about the spec of the external object. It could be a routine, a
function, have many or few parameters; it doesn't matter because USEFOR
does not call it.
In the program or routine which calls USEFOR, however, the MYNAME
spec must be identical to the spec of the dummy routine or function as
the above examples illustrate. Once this has been done then any routine
or function with the same spec as the dummy can be called.
Important note
KEY
Care must be taken when using USEFOR over the problem of serial
re-entrancy. This is discussed at greater length in the 'PRELOADing
object files' subsection of the 'Efficient loading' section but in
essence the problem is that global variables and common areas are only
initialised by the loader when a file is loaded. USEFOR can call a
routine or function many times but it is only loaded once. The nth call
of the routine has as its starting values for global variables the n-1th
final values.
Not all routines have global variables or common blocks and in these
there is no ambiguity but even in files which are not serially
re-entrant the fact that global variables and common block values are
preserved between runs can be turned to advantage but initially it is
vital to be aware of the potential problems.
PRELOAD
This command causes object file FILE to be 'permanently loaded'
i.e. until the end of the current session or an explicit call on
RESETLOADER (q.v.). Any references which remain unsatisfied after the
file is loaded are made dynamic. Note that this includes ALL data
references except common areas. Common areas are set up by claiming
space from the base gla. Preloading is generally used to 'permanently
load' files which are going to be frequently used during a session.
Loading overheads are only incurred once.
Important note
KEY
PRELOAD should not be used until the 'PRELOADing object files'
subsection of 'Efficient loading' has been read. In particular the
implications of loading an object file once but running it several times
must be understood if the command is to be used safely.
RESETLOADER
This command will unload any user files which are currently loaded.
Any DATASPACE or ALIASENTRY definitions will also be lost.
This command can ONLY be issued at command level; attempts to call
it from a program will fail.
Current load status - LOADEDENTRIES, LOADEDFILES, CURRENTREFS
KEY LOADEDENTRIES,LOADEDFILES,CURRENTREFS
LOADEDENTRIES prints a list of entries which have been loaded by the
caller i.e. no subsystem or system call table entries.
LOADEDFILES prints a list of currently loaded files.
CURRENTREFS prints out a list of currently active references. An
active reference is one which will trigger off a loader search if
encountered during a load (unsatisfied reference) or program execution
(dynamic reference).
System Interface
KEY
This description of the system interface is accurate at the time of
writing, however, the ERCC reserves the right to alter this interface as
necessary.
Intending users of any of the routines below do so at their own risk
and should ensure that the specifications given here are still extant.
Note 1. Loader Constants.
The following constants are used in the description of the loader
interface to categorise the various types of entry understood by the
loader:
FNAMETYPE(filename type) 0
DATA 1
CODE 2
MACRO 4
Note 2. Supplying loadlevel values to system routines.
Many of the routines described in the system interface request a
'local loadlevel', (usually LOCLL). The loader is the only software
which is allowed to alter the overall value of the loadlevel of the
process, so the programmer should not attempt it. What the programmer
can do is to decide whether a file is to be permanently or temporarily
loaded. If the former is required then the caller should supply a LOCLL
of 0. This causes a temporary, localised switch in loadlevel for the
duration of the load of that file. The global value of loadlevel is
unaltered. If, however, the file is only to be temporarily loaded then
the current value of the global loadlevel should be supplied. This can
be obtained by calling the integer function CURRENTLL (q.v.). If a
value of LOCLL is supplied such that 0#LOCLL#global loadlevel, then the
result is undefined but assuredly catastrophic.
Searching
LOOKLOADED
%systemlongintegerfunctionspec lookloaded(%string(31) entry,
%integername type)
This function looks for the occurrence of ENTRY in the caller's
currently loaded material (i.e. subsystem entries and caller's privately
loaded entries) TYPE can be FNAMETYPE or any combination of CODE,DATA or
MACRO (e.g. CODE!MACRO). If TYPE is a multiple then if the search is
successful the value of TYPE returned will be the type actually found.
The function always returns a result of 0 if the search
fails. Successful searches give the following longinteger results:
Returned TYPE Result
======== ==== ======
FNAMETYPE 1 i.e. the file is already loaded
DATA A pseudo descriptor with the first word giving
the length of the data entry in bytes and the
second its address, but with no 'descriptor type'
information.
CODE A descriptor to ENTRY
MACRO Not yet implemented
SEARCH
%systemintegerfunctionspec search(%string(31) entry,
%longintegername desc,%stringname file,actualepname,
%integername type,locll)
This is the loader's main searching routine
for the current EMAS subsystem. Searching is
done in the order:
1. Subsystem entries
2. Privately loaded entries
3. Active directory
4. Subsystem base directory
5. Privately nominated directories
Input required
ENTRY Entry name to be searched for
TYPE Any combination of CODE,DATA or MACRO
LOCLL Supply value of global loadlevel (i.e. from CURRENTLL).
Possible results
%RESULT < 0
-----------
This means that ENTRY was found and is already loaded.
Output given
------------
DESC Descriptor to CODE or DATA or MACRO item found
ACTUALEPNAME If ENTRY was an alias or the leader of a chain of
aliases then ACTUALEPNAME is the name of the entry
point at the end of the alias chain, otherwise
ACTUALEPNAME=ENTRY.
TYPE Type of entry point found
%RESULT = 0
-----------
This means that ENTRY was found but is not currently loaded.
Output given
------------
FILE The name of the file which contains ACTUALEPNAME.
ACTUALEPNAME ENTRY, or if ENTRY was an alias then the entry point
name eventually found.
TYPE Type of entry point found.
LOCLL Loadlevel value input or, or if the file was found in
the subsystem base directory then 0 (so that FILE will
be 'permanently' loaded).
%RESULT > 0
-----------
ENTRY was not found after a complete search(%RESULT=289) or an
error condition was encountered.
Loading and searching
LOADEP
%systemlongintegerfunctionspec loadep(%string(31) entry,
%integername type,flag, %integer locll)
This longinteger function is used to effect a complete load based on
a starting search for ENTRY.
TYPE can be any combination of CODE, DATA or MACRO although in most
cases CODE or CODE!MACRO would be the likely choices. If the load
succeeds then the actual type found is returned through TYPE.
FLAG indicates the success or failure of the load - a zero flag
means successful.
LOCLL is the value of the loadlevel supplied to the function in
accordance with Note 2 above. It is therefore either the current
loadlevel (from CURRENTLL) or 0 if all the loading is to be 'permanent'.
If the call is successful then the result of the function is a
descriptor to ENTRY otherwise the result is 0. Note that only in the
case of ENTRY being of type CODE is a true 2900 descriptor returned.
The function first looks for ENTRY. If ENTRY is already loaded then
the result is returned immediately. If not then routine SEARCH is
called. If a suitable file to load is found then this is loaded by a
call on LOADFILE2. If unsatisfied references remain then the load
continues by calling CASCADELOAD (q.v.) by default, or MINLOAD (q.v.) if
LOADPARM MIN is set. Should the load fail at some point, then everything
that has been loaded by the call on LOADEP will be unloaded (by a call
on UNLOAD2 (q.v.)).
LOADENTITY
%systemlongintegerfunctionspec loadentity(%string(31) entry,
%integername type,flag,%integer locll)
This function takes the same parameters as LOADEP and behaves
exactly the same as LOADEP except where the initial call on SEARCH to
find ENTRY returns a 'not found' condition. In these circumstances
LOADENTITY will try to connect ENTRY on the assumption that it is a
file. If the connect fails, or if it succeeds but the file is neither an
object file nor a character file, then the function terminates.
If ENTRY is an object file then it is inspected for a main entry and
if one is found then the file is loaded as in LOADEP with the entry
descriptor returned as the result, otherwise the function terminates.
If ENTRY is a character file then the result -1 is returned. In the
standard subsystem this is taken as an indication to attempt an OBEYJOB
on the file.
CASCADELOAD
%systemroutinespec cascadeload(%integername flag,%integer locll)
Used in conjunction with LOADFILE2 (q.v.) to effect a complete load
(see LOADEP and LOADENTITY).
While there are unsatisfied references (COMREG(7)>0), the routine
attempts to satisfy them by searching for, and loading, files which
contain any of the outstanding reference names as entry points. Common
areas are created where appropriate. The routine terminates on
encountering the first failure of any kind and will return a non zero
flag. The routine requires the value of the local loadlevel as
input. (LOCLL). If everything is to be 'permanently loaded' then LOCLL
should be 0 otherwise the overall load level (from CURRENTLL (q.v.))
should be supplied (See Note 2 above).
Important note
KEY
UNLOAD2 (q.v.) should be used to tidy up after any failure of
CASCADELOAD.
MINLOAD
%systemroutinespec minload(%integer locll,makedynamic,
%integername flag)
Used in conjunction with LOADFILE2 (q.v.) to allow a single file to
begin executing by fixing up unsatisfied references to be dynamic or
unresolved as specified (See also LOADEP and LOADENTITY).
The routine goes through the list of unsatisfied references and
changes their type to dynamic if MAKEDYNAMIC=1 or unresolved if
MAKEDYNAMIC=0. No further loading occurs although any outstanding common
areas will be created. Note that in some circumstances calling MINLOAD
may result in the creation of dynamic data references (q.v.).
The routine returns a flag and requires the local loadlevel as input
exactly as described in CASCADELOAD.
Important note
KEY
UNLOAD2 (q.v.) should be used to tidy up after any failure.
Loading - LOADFILE2
KEY LOADFILE2
%systemroutinespec loadfile2(%string(31) file,%integername flag,
%integer locll)
This routine causes file FILE to be loaded at loadlevel LOCLL with
the result returned via FLAG. A flag of 0 indicates success.
LOADFILE2 copes with standard and bound object files. If the CODE
area crosses a segment boundary or is marked as unshareable then the
CODE and SST areas are copied into a file called T#CODEnn where nn is a
unique suffix chosen by the system.
In addition to performing basic loading operations, LOADFILE2
carries out any linking operations which are possible with already
loaded material and will satisfy any outstanding references to entry
points contained in FILE.
Unloading - UNLOAD2
KEY UNLOAD2
%systemroutinespec unload2(%integer locll,fail)
This routine causes everything loaded with a loadlevel>=LOCLL to be
unloaded. When the unload occurs at the end of normal processing then
FAIL should be set to 0. However when the call to UNLOAD2 occurs as the
result of a failed load then FAIL should be set to 1. This will ensure
that any item 'permanently' loaded during the failed load will be
unloaded. Note that if there are any references at loadlevels<LOCLL
which have been satisfied by entries which are about to be unloaded then
these references will be unfixed and made dynamic. A warning will be
given when this is done.
Entering code - ENTER
KEY ENTER
%systemroutinespec enter(%integer mode,dr0,dr1,%string(255) param)
This routine is used to enter the code pointed at by the descriptor
held in DR0 and DR1. This code may have either no parameters or a single
%STRING(255) parameter contained in PARAM. MODE is a bit significant
quantity:
2**0 - If set then request an explicit stack switch (i.e. from base
stack to user stack).
2**1 - If set then parameter supplied.
Note that the rules for executing a stack switch are as follows:
Switch stacks if a) you are presently on the base stack
and b) you are not privileged
and c) you are calling something outside the basefile
or
c') you explicitly request a stack switch
Rebuilding loader search list - BDIRLIST
KEY BDIRLIST
%systemroutinespec bdirlist
Instructs the loader to rebuild its list of directories which must
be searched when looking for entries. This routine must be called by
software which changes the information on directories in the options
file to ensure that the loader updates its own table.
General information routines
CURRENTLL
%systemintegerfunctionspec currentll
Returns the current global value of loadlevel for the process.
CURSTACK
%systemintegerfunctionspec curstack
Returns 0 if running on the base stack, otherwise 1.
Utility routine - FILLPATTN
KEY FILLPATTN
%systemroutinespec fillpattn(%integer ncopies,n,from,to)
Moves NCOPIES of N bytes from address FROM to address TO.
Dumping routine - LOADDUMP
KEY LOADDUMP
%externalroutinespec loaddump(%string(255) s)
This routine takes a single parameter to control which particular
part of the loader tables are to be dumped. Valid parameters are:
0 - T#LOAD file header
1 - References table
2 - Permanent entries table
3 - Temporary entries table
A null parameter or any other than those specified above will dump
the whole T#LOAD file. Additional information on the current state of
the SSLOADTAB, LLINFO and DUFFGLA record arrays is always printed.