Appendix A2. Unloading

KEY Unloading strategy takes advantage of the pseudo stack operation of the loader entry tables, gla and initialised stack and the ideas associated with the concept of loadlevel. It may be recalled that with each loadlevel there is an associated record in the record array LLINFO which contains three integers: the offset of the first entry in the loader's entry tables at this loadlevel, the address of the first byte of gla used at this loadlevel and the address of the first byte of initialised stack used at this loadlevel. These three integers are, in effect, static pointers into three stacks which were the current 'stack tops' when the loadlevel was initially defined. If we want to unload the loadlevel then the current, actual 'stack tops' must be returned to the values held in the LLINFO record for this loadlevel, discarding the information in between. The main complication to this simple scheme is to ensure that references remain consistent. To illustrate it is necessary to appreciate how linking between separate modules is achieved. An external reference in an object file has an associated location in the gla of that file, 8 bytes long. A reference in the code of the object file to the external reference is made in terms of a descriptor to the required entry point which has to be planted at that location by the loader. The descriptor supplied by the loader in turn points to a location in the gla of an object file which contains the desired reference as an entry point (This location itself contains a descriptor which points to the entry point in the code area of the target object file). The problem arises when a file at one loadlevel has an external reference satisfied by an entry point from a a file loaded at a higher loadlevel and the higher loadlevel is to be unloaded. After the gla of the object file containing the entry point is unloaded then the descriptor in the gla of the file which remains loaded will be pointing at a location whose meaning is no longer defined. Any attempt to call the reference would be catastrophic. The solution to this problem is first to identify such references at unload time then make them into dynamic references by overwriting the descriptor in the gla with an escape descriptor. In consequence, if a call is made to the external reference then the normal escape sequence will be triggered. If an unload of loadlevel LL is requested then the following sequence of events takes place:
1. Check whether anything has to be unloaded. There will be something to unload if a) the current top of the temporary entries table (TEMPOFFSET) > LLINFO(LL)_TAB or b) the unload is a consequence of a load which failed and the top of the permanent entries table (PERMOFFSET) > LLINFO(0)_TAB If unloading is required then: 2. Start to build a table of ranges of gla and initialised stack which have to be unloaded. This table is held in a record array, DUFFGLA. Each record consists of two integers, FROM and TO. Let us assume that we have to do the maximum amount of unloading i.e. a load has failed and some permanent and temporary loaded material has to be unloaded. We begin with the permanently loaded material. There will always be some basegla to unload, therefore DUFFGLA(0)_FROM=LLINFO(0)_GLA DUFFGLA(0)_TO=SSCURBGLA i.e. the current top of the basegla If some permanent initialised stack has to be unloaded then DUFFGLA(1)_FROM=LLINFO(0)_ISTK DUFFGLA(1)_TO=PERMISTK i.e. current top of the permanent initialised stack. 3. Find out which files have to be unloaded from the permanent entries table by chaining down listhead 251 of this table and inspecting filename records which have offsets >=LLINFO(0)_TAB. Reduce the use counts of these files by 1 (or if the filename record is a DATASPACE created record then by the USECOUNT field in the record). If any of the filenames are of the form T#GLAnn where nn is an integer then the file contains the gla of a bound file which is to be unloaded so that the GLAFROM and GLATO fields of the record should be added to the next free record in DUFFGLA. If any of the filenames are of the form T#CODEnn or T#GLAnn then destroy them if possible. Other files should be disconnected if possible. 4. For ALL listheads in the permanent entries table, i.e. 0 - 251, tidy the chains. Any chain which starts after LLINFO(0)_TAB can be wholly discarded and the listhead zeroed. Any chain which straddles LLINFO(0)_TAB must have a chain terminator placed in the LINK field of the last entry record on the chain before LLINFO(0)_TAB. 5. Fill the newly released area in the table with zeros. 6 - 9. We now go through a similar procedure for the temporary entries table, the only difference being that there will already be some members in DUFFGLA and there are no DATASPACE entries to worry about. E.g. the next DUFFGLA entry, the nth say would be DUFFGLA(n)_FROM=LLINFO(LL)_GLA DUFFGLA(n)_TO=SSCOMREG(44) i.e. the current top of the user gla 10.We have now built the final version of DUFFGLA and it is time to tidy the references table. To do this we must inspect every information record currently in the table. If the reference has a loadlevel >=LL then it should be discarded forthwith. For references with a loadlevel <LL then the following applies: If the reference location (the DR1 field) is in one of the DUFFGLA ranges then it should be discarded. If not and the reference is a satisfied reference i.e. the dynamic and unsatisfied bits in the basic record are NOT set, then the fixed up descriptor at the reference location should be checked to see whether it points into one of the DUFFGLA ranges. If it does then this reference has to be unfixed and made into a dynamic reference. This is done by picking up the address of the relevant dynamic escape table from the ADYNR field of the information record and overwriting the reference location with an escape descriptor which points to this escape table. 11.Any basic record which now has no information records should be discarded. 12.Tidy LLINFO